私のイベントマネージャー
イベント マネージャーの場合、イベントがトリガーされたときに関数を呼び出すために、関数への多くのポインターをベクターに格納する必要があります。(この質問の最後に、EventFunction ヘルパー クラスのソース コードを提供します。)
// an event is defined by a string name and a number
typedef pair<string, int> EventKey;
// EventFunction holds a pointer to a listener function with or without data parameter
typedef unordered_map<EventKey, vector<EventFunction>> ListEvent;
// stores all events and their listeners
ListEvent List;
リスナーの登録は、追加データを受信するかどうかに応じて、最初または 2 番目の関数を呼び出すことで実行できます。(このコードは、私のイベント マネージャー クラスからのものです。)
public:
typedef void (*EventFunctionPointer)();
typedef void (*EventFunctionPointerData)(void* Data);
// let components register for events by functions with or without data parameter,
// internally simple create a EventFunction object and call the private function
void ManagerEvent::Listen(EventFunctionPointer Function, string Name, int State);
void ManagerEvent::Listen(EventFunctionPointerData Function, string Name, int State);
private:
void ManagerEvent::Listen(EventFunction Function, string Name, int State)
{
EventKey Key(Name, State);
List[Key].push_back(Function);
}
メンバー関数ポインター
リストに関数ポインターは格納しますが、メンバー関数ポインターは格納しないため、そのコードは機能しません。これらのポインターはすべてメンバー関数ポインターである必要があります。これは、イベントがトリガーされた場合に適切なサウンドを再生するために、そのメンバー関数のいずれかを使用してコンポーネントComponentSound
がイベントをリッスンするためです。"PlayerLevelup"
ComponentSound::PlayerLevelup
C++ のメンバ関数ポインタは次のようになります。
// ReturnType (Class::*MemberFunction)(Parameters);
void (ComponentSound::*PlayerLevelup)();
問題は、任意のコンポーネント クラスがイベントをリッスンできる必要があることですが、メンバー関数ポインターをイベント マネージャーに格納するには、リッスン クラスを指定する必要があります。例でわかるように、指定する必要がありますComponentSound
が、イベント マネージャーは単に任意のクラスへのメンバー関数ポインターのベクトルを持つ必要があります。
質問
これらの質問のいずれかへの回答は、私を大いに助けてくれます。
- イベント マネージャーのベクター内の任意のメンバー関数への関数ポインターを格納するにはどうすればよいですか? (おそらく、すべてのリッスン機能が 1 つの抽象クラスから継承されていることが役立つでしょう
Component
。) - 目的の機能を実現するために、別の方法でイベント マネージャーを設計するにはどうすればよいですか? (メッセージに string および int キーを使用したい。)
質問を一般的なものにしようとしましたが、さらに情報やコードが必要な場合はコメントしてください。
課題
メンバー関数ポインターのベクトルでは、ポインターだけでなく EventFunction を使用して、2 つのメッセージ型を提供します。1 つはデータ パラメーターを使用し、もう 1 つはデータ パラメーターを使用しません。
class EventFunction
{
private: EventFunctionPointer Pointer; EventFunctionPointerData PointerData; bool Data;
public:
EventFunction(EventFunctionPointer Pointer) : Pointer(Pointer), PointerData(NULL), Data(false) { }
EventFunction(EventFunctionPointerData PointerData) : PointerData(PointerData), Pointer(NULL), Data(true) { }
EventFunctionPointer GetFunction() { return Pointer; }
EventFunctionPointerData GetFunctionData() { return PointerData; } bool IsData() { return Data; }
void Call(void* Data = NULL){ if(this->Data) PointerData(Data); else Pointer(); }
};