コンポーネントベースのエンティティシステムを実装しようとしていますが、メッセージングの処理方法について少し混乱しています。システムをテストできるように、解決したい2つの問題があります。以下は私がこれまでに持っているコードです、
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から派生した)メッセージタイプをどのように処理するかです。
派生メッセージタイプのメッセージタイプを処理する2つの方法を考えました。1つは、メッセージタイプを指定する文字列からハッシュを生成(つまり、FNVを使用)し、そのハッシュを使用してメッセージタイプを決定することです。そのため、handleMessage(BaseMessage &message)
関数は最初にこのハッシュをメッセージから抽出し、次にstatic_castを適切なタイプに実行します。
2番目の方法は、次のようにテンプレートを使用することです(attachComponent
エンティティクラスのメソッドと同様)。
template<class T>
handleMessage(T& message){};
特定のコンポーネントが作成するメッセージタイプごとに特化します。
2番目の方法を使用する場合、欠点はありますか?パフォーマンスに関してはどうですか、なぜこの種の使用をもっと頻繁に見ないのですか?
2.入力処理
私の2番目の質問は、入力を処理するための(待ち時間と使いやすさの観点から)最適な方法は何ですか?
私の考えは、InputHandlerComponent
おそらくいくつかのファイルで定義された特定のキープレスをリッスンするためにキーボードクラスに登録するを作成することでした。例えば
keyboard.register( player.getComponent<InputHandler>() , 'W')
コンポーネントベースのシステムについてより簡潔なガイドがあったらいいのにと思いますが、同じことを行うには多くの異なる方法があると思います。他にも質問がありますが、最初にできることを実装してみるのが賢明だと思います。