Ejemplo n.º 1
0
 def __init__(self, **fields):
     self.fields = {}
     for fname, ftype in fields.items():
         assert ftype in field.types, fname + " has an illegal field type"
         self.fields[fname] = field.Field(self, fname, ftype)
     self.entities = ComponentEntitySet(self)
     self._added = []
     self._deleted = []
Ejemplo n.º 2
0
class Component(dict):
    """General component with a configurable schema

	The field schema is defined via keyword args where the 
	arg name is the field name and the value is the type object.

	The following types are supported for fields:

	- :class:`int`
	- :class:`float`
	- :class:`bool`
	- :class:`str`
	- :class:`object`
	- :class:`list`
	- :class:`dict`
	- |set|
	- |Vec2d|
	- |Vec2dArray|
	- |RGBA|
	- |Rect|
	"""

    deleted_entities = ()
    """List of entities deleted from the component since the last time step"""

    new_entities = ()
    """List of entities added to the component since the last time step"""

    def __init__(self, **fields):
        self.fields = {}
        for fname, ftype in fields.items():
            assert ftype in field.types, fname + " has an illegal field type"
            self.fields[fname] = field.Field(self, fname, ftype)
        self.entities = ComponentEntitySet(self)
        self._added = []
        self._deleted = []

    def set_world(self, world):
        self.world = world

    def step(self, dt):
        """Update the component for the next timestep"""
        delitem = super(Component, self).__delitem__
        for entity in self._deleted:
            delitem(entity)
        self.new_entities = self._added
        self.deleted_entities = self._deleted
        self._added = []
        self._deleted = []

    def set(self, entity, data=None, **data_kw):
        """Set the component data for an entity, adding it to the
		component if it is not already a member.

		If data is specified, its data for the new entity's fields are
		copied from its attributes, making it easy to copy another
		entity's data. Keyword arguments are also matched to fields.
		If both a data attribute and keyword argument are supplied for
		a single field, the keyword arg is used.
		"""
        if data is not None:
            for fname, field in self.fields.items():
                if fname not in data_kw and hasattr(data, fname):
                    data_kw[fname] = getattr(data, fname)
        data = self[entity] = Data(self.fields, entity, **data_kw)
        return data

    def __setitem__(self, entity, data):
        assert entity.world is self.world, "Entity not in component's world"
        if entity not in self.entities:
            self._added.append(entity)
            self.entities.add(entity)
        super(Component, self).__setitem__(entity, data)

    def remove(self, entity):
        if entity in self.entities:
            self._deleted.append(entity)
            self.entities.remove(entity)
            return True
        return False

    __delitem__ = remove

    def __repr__(self):
        return "<%s %x of %r>" % (self.__class__.__name__, id(self), getattr(self, "world", None))