Sto cercando di implementare un sistema di entità basato su componenti ma sono un po 'confuso su come dovrei gestire la messaggistica. Ci sono due problemi che vorrei risolvere in modo da poter testare il sistema. Di seguito è riportato il codice che ho finora,
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_;
};
Le classi Componente di base e Messaggio:
class BaseComponent{
public:
virtual void handleMessage(BaseMessage &message){};
};
class BaseMessage{
public:
virtual int getType(void) = 0;
};
1. Gestione del tipo di messaggio
La mia prima domanda è come dovrei gestire i diversi tipi di messaggi (derivati da BaseMessage).
Ho pensato a due modi per gestire i tipi di messaggio dei tipi di messaggio derivati. Uno è generare un hash (cioè usando FNV) da una stringa che nomina il tipo di messaggio e usare quell'hash per determinare il tipo di messaggio. Quindi la handleMessage(BaseMessage &message)
funzione estrae prima questo hash dal messaggio e quindi esegue un static_cast nel tipo appropriato.
Il secondo metodo consiste nell'utilizzare un modello come segue (simile ai attachComponent
metodi della classe di entità),
template<class T>
handleMessage(T& message){};
e crea specializzazioni per ogni tipo di messaggio che il componente specifico sta per fare.
Ci sono degli svantaggi nel secondo metodo? Che dire delle prestazioni, perché non vedo questo tipo di utilizzo più spesso?
2. Gestione degli input
La mia seconda domanda è quale sarebbe il modo ottimale (in termini di latenza e facilità d'uso) di gestire l'input?
Il mio pensiero era quello di creare un InputHandlerComponent
registro con la classe di tastiera per ascoltare le pressioni di tasti specifiche definite possibilmente in alcuni file. Per esempio
keyboard.register( player.getComponent<InputHandler>() , 'W')
Vorrei che ci fosse una guida più concisa ai sistemi basati su componenti, ma credo che ci siano molti modi diversi di fare le stesse cose. Ho più domande ma penso che sarebbe più saggio provare prima a implementare ciò che posso.