メンバー関数のコールバックを使用したいC++のイベントデーモンに取り組んでいます。基本的に、イベントキューは、デーモンが継続的に処理するイベントを収集します。IDを持つ基本クラスのEvent構造体があり、すべてのイベントはそれから派生します。各イベントに登録されているメソッドで、派生イベントタイプをシグネチャで使用するようにしたいと思います。
struct Event
{
unsigned int eventId;
};
struct EventA : public Event
{
unsigned int x;
unsigned int y;
};
// and struct EventB, EventC (use your imagination...)
const unsigned int EVENT_A = 1;
const unsigned int EVENT_B = 2;
const unsigned int EVENT_C = 3;
class Foo
{
public:
void handlerMethod_A(const EventA& e);
void handlerMethod_B(const EventB& e);
};
class Bar
{
public:
void handlerMethod_C(const EventC& e);
};
次に、デーモンは、これらのクラスが「this」ポインターを使用してメンバー関数をサブスクライブできるようにします。
class EventDaemon
{
public:
void serviceEvents();
template <class CallbackClass, class EventType>
void subscribe(
const unsigned int eventId,
CallbackClass* classInstancePtr,
void (CallbackClass::*funcPtr)(EventType));
private:
Queue<Event*> eventQueue_;
};
したがって、このクラスの外では、次のようなことができます。
EventDaemon* ed = new EventDaemon();
Foo* foo = new Foo();
Bar* bar = new Bar();
ed->subscribe(EVENT_A, foo, Foo::handlerMethod_A);
ed->subscribe(EVENT_B, foo, Foo::handlerMethod_B);
ed->subscribe(EVENT_C, bar, Bar::handlerMethod_C);
そして、EventDaemonループは
void EventDaemon::serviceEvents()
{
while (true)
{
if (eventQueue_.empty())
{
// yield to other threads
}
else
{
// pop an event out of the FIFO queue
Event e* = eventQueue_.pop();
// somehow look up the callback info and use it
classInstancePtr->*funcPtr(reinterpret_cast<?*>(e));
}
}
}
だから私の質問は、イベントIDによって'this'ポインタとメンバー関数ポインタをある種の配列に格納する方法です。そうすれば、再解釈キャストにe-> eventIdとイベントタイプを使用して、「classInstancePtr」と「funcPtr」を検索できます。