J'essaie d'implémenter un système d'entités basé sur des composants mais je suis un peu confus sur la façon dont je dois gérer la messagerie. Il y a deux problèmes que je voudrais résoudre pour pouvoir tester le système. Voici le code que j'ai jusqu'à présent,
La classe 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_;
};
Les classes Composant de base et Message:
class BaseComponent{
public:
virtual void handleMessage(BaseMessage &message){};
};
class BaseMessage{
public:
virtual int getType(void) = 0;
};
1. Gestion du type de message
Ma première question est de savoir comment gérer les différents types de messages (dérivés de BaseMessage).
J'ai pensé à deux façons de gérer les types de messages des types de messages dérivés. L'une consiste à générer un hachage (c'est-à-dire en utilisant FNV) à partir d'une chaîne qui nomme le type de message et à utiliser ce hachage pour déterminer le type de message. Ainsi, la handleMessage(BaseMessage &message)
fonction extraira d'abord ce hachage du message, puis effectuera un static_cast vers le type approprié.
La deuxième méthode consiste à utiliser un modèle comme suit (similaire aux attachComponent
méthodes de la classe d'entité),
template<class T>
handleMessage(T& message){};
et faites des spécialisations pour chaque type de message que le composant spécifique va faire.
Y a-t-il des inconvénients à utiliser la deuxième méthode? Qu'en est-il des performances, pourquoi ne vois-je pas ce type d'utilisation plus souvent?
2. Gestion des entrées
Ma deuxième question est quelle serait la manière optimale (en termes de latence et de facilité d'utilisation) de gérer les entrées?
Ma pensée était de créer un InputHandlerComponent
qui s'inscrit avec la classe de clavier pour écouter des pressions de touches spécifiques définies éventuellement dans un fichier. Par exemple
keyboard.register( player.getComponent<InputHandler>() , 'W')
J'aimerais qu'il y ait un guide plus concis des systèmes basés sur les composants, mais je suppose qu'il existe de nombreuses façons différentes de faire les mêmes choses. J'ai d'autres questions, mais je pense qu'il serait plus sage d'essayer d'abord de mettre en œuvre ce que je peux.