Я пытаюсь реализовать систему сущностей на основе компонентов, но я немного запутался в том, как мне следует обращаться с сообщениями. Я хотел бы решить две проблемы, чтобы проверить систему. Ниже приведен код, который у меня есть,
Класс Entity:
class Entity{
public:
Entity(unsigned int id):
id_(id)
{};
void handleMessage(BaseMessage &message){
for(auto element: components_){
element.second->handleMessage(message);
}
}
template<class T>
void attachComponent(T *component){
//Consider making safer in case someone tries to attach same component type twice
components_[typeid(T).hash_code()] = component;
}
template<class T>
void detachComponent(void){
components_.erase(typeid(T).hash_code());
}
template<class T>
T* getComponent(void)const{
return *components_.find(typeid(T).hash_code());
}
unsigned int getInstanceID(void)const{
return id_;
}
private:
unsigned int id_;
std::map<size_t, BaseComponent*> components_;
};
Классы базового компонента и сообщения:
class BaseComponent{
public:
virtual void handleMessage(BaseMessage &message){};
};
class BaseMessage{
public:
virtual int getType(void) = 0;
};
1. Обработка типа сообщения
Мой первый вопрос заключается в том, как я должен обрабатывать различные (полученные из BaseMessage) типы сообщений.
Я подумал о двух способах обработки типов сообщений из производных типов сообщений. Один из них состоит в том, чтобы сгенерировать хеш (то есть, используя FNV) из строки, в которой указан тип сообщения, и использовать этот хеш для определения типа сообщения. Таким образом, handleMessage(BaseMessage &message)
функция сначала извлечет этот хеш из сообщения, а затем сделает static_cast для соответствующего типа.
Второй метод заключается в использовании шаблона следующим образом (аналогично attachComponent
методам класса сущности),
template<class T>
handleMessage(T& message){};
и сделайте специализации для каждого типа сообщения, который собирается сделать определенный компонент.
Есть ли недостатки при использовании второго метода? Что касается производительности, почему я не вижу такого рода использование чаще?
2. Обработка ввода
Мой второй вопрос: каков оптимальный (с точки зрения времени ожидания и простоты использования) способ обработки ввода?
Я хотел создать InputHandlerComponent
регистр с классом клавиатуры для прослушивания определенных нажатий клавиш, определенных, возможно, в каком-то файле. Например
keyboard.register( player.getComponent<InputHandler>() , 'W')
Хотелось бы, чтобы было более краткое руководство по компонентным системам, но я думаю, что есть много разных способов сделать то же самое. У меня есть еще вопросы, но я думаю, что было бы разумнее сначала попытаться реализовать то, что я могу.