I have an event driven application. I want to keep the event handler (EventHandler
class capable of many/all events) a common implementation - while allowing the EventSource
be changeable (specifically - at compile time).
To couple the EventHandler
with the EventSource
, I will have to store an instance of handler within the EventSource
. I tried to store handlers of various forms:
- pointer to an interface of
EventHandler
(that has public handler methods defined in concreteEventHandler
's - instance of
std::function
- this provided greatest flexibility
However, in both cases, the latency in calling the target method/lambda was quite high (on my test setup about 250ns) - and to worse, was inconsistent. May be due to virtual table and/or heap allocation and/or type erasure ???
In order to reduce this latency, I want to make use of templates.
The best I could come up with is:
template <typename EventHandler>
class EventSource1
{
EventHandler* mHandler;
public:
typedef EventHandler EventHandlerType;
void AssignHandler (EventHandler* handler)
{
this->mHandler = handler;
}
void EventuallyDoCallback (int arbArg)
{
this->mHandler->CallbackFunction (arbArg);
}
};
template <EventSourceType>
class EventSourceTraits
{
typedef EventSourceType::EventHandlerType EventHandlerType;
static void AssignHandler (EventSourceType& source, EventHandlerType* handler)
{
source.AssignHandler(handler);
}
};
class EventHandler
{
public:
void CallbackFunction (int arg)
{
std::cout << "My callback called\n";
}
};
int main ()
{
EventSource1<EventHandler> source; /// as one can notice, EventSource's need not to know the event handler objects.
EventHandler handler;
EventSourceTraits<EventSource1>::AssignHandler (source, &handler);
}
This method impose a restriction that all my EventSource
's to be a template classes.
Question is: Is this best way to achieve consistent and low latency to callback? Can this code be improved to avoid the event source classes be completely independent of event handler objects' type ?