I have an event driven application. I want the event handler (a EventHandlerclass capable of many / all events) to be a common implementation, allowing to change EventSource(in particular - at compile time).
To link EventHandlerto EventSource, I will need to save the handler instance in EventSource. I tried to store handlers of various forms:
- pointer to an interface
EventHandler(which has open handler methods defined in a particularEventHandler - instance
std::function- this provided maximum flexibility.
However, in both cases, the latency when calling the target method / lambda was quite high (about 250 ns on my test setup) - and, even worse, it was inconsistent. Maybe due to a virtual table and / or heap allocation and / or type erasure ???
To reduce this delay, I want to use patterns.
The best I could come up with was:
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;
EventHandler handler;
EventSourceTraits<EventSource1>::AssignHandler (source, &handler);
}
This method restricts all my EventSourceclasses to be template classes.
Question : Is this the best way to achieve consistent and low latency for callback? Is it possible to improve this code to avoid the event source classes being completely independent of the type of event handler objects?
source
share