You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There should be support for callbacks on specific state changes such as a component being added or removed:
@attrs.define(frozen=True) # Class is frozen to ensure that a changed value is announcedclassPosition:
x: inty: int@tcod.ecs.register_on_component_changed(Position)defon_changed_position(entity: Entity, old_pos: Position|None, new_pos: Position|None) ->None:
"""Check for Position changes in all worlds."""ifold_posisnotNoneandnew_posisnotNone:
print(f"Changed from {old_pos} to {new_pos}")
elifold_posisNoneandnew_posisnotNone:
print(f"{new_pos} added")
else:
assertold_posisnotNoneandnew_posisNoneprint(f"{old_pos} removed")
This is global, there should also be a per-world variant.
These types of callbacks can also be used to manage compiled queries in #3
Would also need to add callbacks for tags and relations.
These should probably not be called during unpickling.
Note that tcod.ecs.callbacks.register_component_changed is implemented in the current releases. This can already be used for some tricks such as tracking the spatial position of entities dynamically, such as with the following example:
@attrs.define(frozen=True) # Class is frozen to ensure that a changed value is announcedclassPosition:
"""Tile position of an entity."""x: inty: int@attrs.define(frozen=True)classMapChunkPosition:
"""Map chunk index of an entity."""x: inty: intCHUNK_SIZE=32@tcod.ecs.callbacks.register_component_changed(component=Position)defon_position_changed(entity: Entity, old: Position|None, new: Position|None) ->None:
"""Track the Position component as a tag in entities. Update the map chunk position."""ifold==new:
return# Reduce cache invalidation by not adding and removing the same tagifoldisnotNone:
entity.tags.remove(old)
ifnewisnotNone:
entity.tags.add(new)
entity.components[MapChunkPosition] =MapChunkPosition(new.x//CHUNK_SIZE , new.y//CHUNK_SIZE)
else: # new is Nonedelentity.components[MapChunkPosition]
@tcod.ecs.callbacks.register_component_changed(component=MapChunkPosition)defon_chunk_position_changed(entity: Entity, old: MapChunkPosition|None, new: MapChunkPosition|None) ->None:
"""Track the MapChunkPosition component as a tag in entities."""ifold==new:
returnifoldisnotNone:
entity.tags.remove(old)
ifnewisnotNone:
entity.tags.add(new)
With this setup you can query entities by an exact or approximate position.
world.Q.all_of(tags=[Position(0, 0)]) # Query all entities at an exact position.world.Q.all_of(tags=[MapChunkPosition(0, 0)]) # Query all entities in a more general area.
Activity
Add callback for component changes
Add callback for component changes
Add callback for component changes
HexDecimal commentedon Oct 7, 2023
Note that tcod.ecs.callbacks.register_component_changed is implemented in the current releases. This can already be used for some tricks such as tracking the spatial position of entities dynamically, such as with the following example:
With this setup you can query entities by an exact or approximate position.