Ich versuche, ein komponentenbasiertes Entitätssystem zu implementieren, bin aber etwas verwirrt darüber, wie ich mit dem Messaging umgehen soll. Es gibt zwei Probleme, die ich lösen möchte, damit ich das System testen kann. Unten ist der Code, den ich bisher habe,
Die Entitätsklasse:
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_;
};
Die Klassen Basiskomponente und Nachricht:
class BaseComponent{
public:
virtual void handleMessage(BaseMessage &message){};
};
class BaseMessage{
public:
virtual int getType(void) = 0;
};
1. Behandlung von Nachrichtentypen
Meine erste Frage ist, wie ich mit den verschiedenen (von BaseMessage abgeleiteten) Nachrichtentypen umgehen soll.
Ich habe mir zwei Möglichkeiten ausgedacht, um mit den Nachrichtentypen der abgeleiteten Nachrichtentypen umzugehen. Eine besteht darin, einen Hash (dh unter Verwendung von FNV) aus einer Zeichenfolge zu generieren, die den Nachrichtentyp benennt, und diesen Hash zu verwenden, um den Nachrichtentyp zu bestimmen. Die handleMessage(BaseMessage &message)
Funktion würde also zuerst diesen Hash aus der Nachricht extrahieren und dann einen static_cast für den entsprechenden Typ ausführen.
Die zweite Methode besteht darin, eine Vorlage wie folgt zu verwenden (ähnlich den attachComponent
Methoden der Entitätsklasse):
template<class T>
handleMessage(T& message){};
und Spezialisierungen für jeden Nachrichtentyp vornehmen, den die jeweilige Komponente vornehmen wird.
Gibt es irgendwelche Nachteile bei der zweiten Methode? Was ist mit der Leistung? Warum sehe ich diese Art der Verwendung nicht öfter?
2. Eingabehandhabung
Meine zweite Frage ist, wie (in Bezug auf Latenz und Benutzerfreundlichkeit) Eingaben optimal verarbeitet werden können.
Mein Gedanke war, eine zu erstellen, InputHandlerComponent
die sich bei der Tastaturklasse registriert, um bestimmte Tastendrücke zu hören, die möglicherweise in einer Datei definiert sind. Zum Beispiel
keyboard.register( player.getComponent<InputHandler>() , 'W')
Ich wünschte, es gäbe eine präzisere Anleitung für komponentenbasierte Systeme, aber ich denke, es gibt viele verschiedene Möglichkeiten, die gleichen Dinge zu tun. Ich habe weitere Fragen, aber ich denke, es wäre klüger, zuerst zu versuchen, das zu implementieren, was ich kann.