Entity System в C++

Я недавно обнаружил архитектуру EntitySystem, и у меня есть некоторые трудности, чтобы сделать это в C++ / понять реализацию.

Как я вижу Entity System:

Компоненты: класс с атрибутами, набором и получением.

  1. эльф
  2. Physicbody
  3. SpaceShip
  4. ...

Система: класс со списком компонентов.

  1. Элемент списка
  2. EntityManager
  3. Renderer
  4. вход
  5. камера
  6. ...

Entity: просто пустой класс со списком компонентов.

Что я сделал:

В настоящее время у меня есть программа, которая позволяет мне сделать это:

// Create a new entity/
Entity* entity = game.createEntity();

// Add some components.
entity->addComponent( new TransformableComponent() )
            ->setPosition( 15, 50 )
            ->setRotation( 90 )
        ->addComponent( new PhysicComponent() )
            ->setMass( 70 )
        ->addComponent( new SpriteComponent() )
            ->setTexture( "name.png" )
            ->addToSystem( new RendererSystem() );

Если я правильно понял EntitySystem, каждая система имеет свой собственный список компонентов, с которыми она работает. (Список компонентов или список сущностей, это вопрос)

class Component;

/////////////////////////////////////////////////
/// \brief  An abstract system. (Interface)
///
/////////////////////////////////////////////////
class System
{
public:

    /////////////////////////////////////////////////
    /// \brief Call when process is created.
    ///
    /////////////////////////////////////////////////
    virtual bool start() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is updated.
    ///
    /////////////////////////////////////////////////   
    virtual void update() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is removed.
    ///
    /////////////////////////////////////////////////
    virtual void end() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is removed.
    ///
    /////////////////////////////////////////////////
    virtual void addComponent( Component* component )
    {
        elements.push_back( component );
    }

protected:

    std::vector<Component*> elements;

};

(Я поместил код в.h просто для быстрой отладки ^^)

Эта проблема

Я хочу добавить компонент "T" в систему со списком компонентов X

Что я пробовал:

std::vector<Component*> elements;

Но я хочу что-то подобное:

std::vector<T*> elements;

Мой Системный класс абстрактный. У моего класса System детский класс должен иметь этот список с собственным типом.

Решение:

Я пытался поставить мой класс System имеет шаблонный класс, поэтому я просто должен сделать: class Renderer: System

Но мой SystemManager не нравится этот код: std::vector<System> systems,

Системный класс с типом T:

template<class T>
class System
{
public:

    /////////////////////////////////////////////////
    /// \brief Call when process is created.
    ///
    /////////////////////////////////////////////////
    virtual bool start() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is updated.
    ///
    /////////////////////////////////////////////////   
    virtual void update() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is removed.
    ///
    /////////////////////////////////////////////////
    virtual void end() = 0;

    /////////////////////////////////////////////////
    /// \brief Call when process is removed.
    ///
    /////////////////////////////////////////////////
    virtual void addComponent( T* component )
    {
        elements.push_back( component );
    }

protected:

    std::vector<T*> elements;

};

Код SystemManager:

class System;

class SystemManager
{
public:

    /////////////////////////////////////////////////
    /// \brief Default constructor.
    ///
    /////////////////////////////////////////////////
    SystemManager();

    /////////////////////////////////////////////////
    /// \brief Call when system is created.
    /// \param system A system to add.
    ///
    /////////////////////////////////////////////////
    bool addSystem( System* system);

    /////////////////////////////////////////////////
    /// \brief Call when system is updated.
    ///
    /////////////////////////////////////////////////
    void update();

    /////////////////////////////////////////////////
    /// \brief Call when system is removed.
    /// \param system A system to remove.
    ///
    /////////////////////////////////////////////////
    void removeSystem( System* system );

private:

    std::vector<System*> systemList;

};

При этом в SystemManager появилась ошибка:"Переопределение" System "как символа другого типа"(указание на строку "class System" в SystemManager).

У вас было решение этой проблемы? Мой Entity System подходит хорошо?

Спасибо!

1 ответ

Решение

В вашем коде System - это шаблон, позже в классе System manager вы пытаетесь использовать System, как если бы это был не шаблон. Это не будет работать. Вам нужно либо указать тип, сделать системный менеджер шаблоном и передать параметр типа в систему, либо система не будет шаблоном. Кроме того, объявление шаблонов, как не шаблонов, не сработает. Сделайте шаг назад и выясните, как работают шаблоны в C++.

Более того, на http://gamedev.stackexchange.com/ есть много вопросов и ответов о дизайне компонентов сущностей, которые могут оказаться полезными.

Другие вопросы по тегам