Как сериализовать мою систему Entity / Component (без бесконечной рекурсии), используя python shelve - PullRequest
0 голосов
/ 17 ноября 2018

Я разрабатываю игру в стиле roguelike на Python и использую урезанную модель Entity / Component - без всех Систем.Компоненты просто упрощают добавление и удаление атрибутов игровых объектов.У меня есть метод getattr в Entity, чтобы сделать его действительно удобным для доступа к значениям компонентов напрямую из Entity, но я думаю, что это создает проблемы, поскольку он достигает максимальной глубины рекурсии при попытке перезагрузить сохраненную полку.

Как сохранить удобство, не мешая процессу сохранения?

Класс Component действительно прост:

class Component(object):                                                                                       
    def __init__(self, entity=None):                                                                           
    self.entity = entity

А вот мой класс Entity:

import uuid
class Entity(object):
    # A generic game object: player, monster, item, stairs, etc.

    def __init__(self, *components):
        # Set a unique uuid
        self._uuid = uuid.uuid4()

        # Add the supplied components.
        self.components = {}
        if components:  # refactor this to *components when all the attributes are components
            for component in components:
                self.set(component)

    @property
    def uuid(self):
        """Property to access the Entity's uuid, exists to prevent uuid modification."""
        return self._uuid

    def find_component(self, name):
        # Searches through the Entity's components to match the given value. If
        # found, it returns the Component that manages that value, otherwise returns None.
        for comp in self.components.values():
            if hasattr(comp, name):
                return comp
        return None

    def __getattr__(self, name):
        comp = self.find_component(name)
        if comp:
            return getattr(comp, name)
        raise AttributeError("Entity has no component with attribute {}".format(name))

    def set(self, component):
        """Sets a new Component."""
        key = type(component)
        self.components[key] = component

    def get(self, component):
        """ Returns the specified Component, if it exists, otherwise returns None."""
        return self.components.get(component, None)

    def has(self, component):
        """ Returns True if this Entity contains the specified Component, otherwise returns False."""
        return self.get(component) is not None

    def rm(self, component):
        """ Removes a Component."""
        return self.components.pop(component, None)
...