Estoy tratando de implementar un sistema de entidad basado en componentes, pero estoy un poco confundido sobre cómo debo manejar los mensajes. Hay dos problemas que me gustaría resolver para poder probar el sistema. A continuación se muestra el código que tengo hasta ahora,
La clase de entidad:
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_;
};
El componente base y las clases de mensaje:
class BaseComponent{
public:
virtual void handleMessage(BaseMessage &message){};
};
class BaseMessage{
public:
virtual int getType(void) = 0;
};
1. Manejo de tipo de mensaje
Mi primera pregunta es cómo debo manejar los diferentes tipos de mensajes (derivados de BaseMessage).
He pensado en dos formas de manejar los tipos de mensajes de los tipos de mensajes derivados. Una es generar un hash (es decir, usar FNV) a partir de una cadena que nombra el tipo de mensaje y usar ese hash para determinar el tipo de mensaje. Entonces, la handleMessage(BaseMessage &message)
función, primero extraería este hash del mensaje y luego haría un static_cast al tipo apropiado.
El segundo método es usar una plantilla de la siguiente manera (similar a los attachComponent
métodos de la clase de entidad),
template<class T>
handleMessage(T& message){};
y hacer especializaciones para cada tipo de mensaje que hará el componente específico.
¿Hay algún inconveniente con el segundo método? ¿Qué pasa con el rendimiento, por qué no veo este tipo de uso con más frecuencia?
2. Manejo de entrada
Mi segunda pregunta es ¿cuál sería la forma óptima (en términos de latencia y facilidad de uso) para manejar la entrada?
Mi pensamiento era crear uno InputHandlerComponent
que se registre con la clase de teclado para escuchar pulsaciones de teclas específicas definidas posiblemente en algún archivo. Por ejemplo
keyboard.register( player.getComponent<InputHandler>() , 'W')
Desearía que hubiera una guía más concisa de los sistemas basados en componentes, pero creo que hay muchas maneras diferentes de hacer lo mismo. Tengo más preguntas, pero creo que sería más prudente intentar primero implementar lo que pueda.