Esempio n. 1
0
class Entity:
    # Keep track of the latest ID for entities to ensure they get unique IDs.
    _id_counter = 0
    
    def __init__(self, system_manager):
        # Fairly certain we don't need this to be a dict, as
        # we are unlikely to want to reference specific
        # systems by id.
        self._systems = []
        
        # A dict of all components inside this entity.
        # The keys are the IDs of the components.
        self._components = {}
        
        # The components this entity has.
        self._component_bitstring = BitString()
        
        # Keep track of the old bitstring so we can see
        # what has changed when we call refresh twice.
        self._old_component_bitstring = BitString()
        
        # Systems that this entity belongs to.
        self._systems_bitstring = BitString()
        
        # Ensure unique IDs.
        self.ID = Entity._id_counter
        Entity._id_counter = Entity._id_counter + 1
        
        # The system manager the entity belongs to.
        # Gives access to the existing systems.
        self.system_manager = system_manager
        
    # Remove an entity from all systems it is hooked into.
    def kill(self):
        for system in self._systems:
            system._remove_entity(self)
            
    # Allow all systems to hook into (or out of) the entity.
    def refresh(self):

        # If the entity is already hooked in remove them, so we don't add them twice.
        # This design can be optimized, but low priority since we likely only refresh
        # an entity once.
        if not self._old_component_bitstring.is_empty():
            self.kill()
                
        self._old_component_bitstring = self._component_bitstring    
        
        for system in self.system_manager._systems:
            
            # Add the entity if it maps correctly to the system.
            does_map = True
            for component_id in system._component_list:
                if not self._component_bitstring.contains(component_id):
                    does_map = False

            if does_map:
                system._add_entity(self)
                self._systems.append(system)

    # Return a component that the entity contains based on the class.
    def get_component(self, component_class):
        try:
            return self._components[component_class.ID]
        except:
            return None

    # Add a component to the entity. Be sure to refresh afterwards.
    def add_component(self, component):

        # Fairly certain we don't want two PositionComponents for example.
        if component.__class__.ID in self._components:
            raise Exception(component.__class__.__name__ + " already inside of entity!")
            
        self._components[component.__class__.ID] = component
        
        #self._components.append(component)
        self._component_bitstring.add_to_set(component.ID)