I would like to create a function which will register an event handler. EventHandler is registered to listen for a particular eventType. Method will have a Type and a variable number of parameters required for concrete EventHandler construction. Each concrete event handler will be derived from the abstract class EventHandler.
/* E.g this is an abstract eventHandler */
class EventHandler
{
public:
virtual ~EventHandler() {};
virtual void OnMessage(const Message *msg) = 0;
};
/* this is an example of derived event handler */
class ServerEventHandler : public EventHandler
{
int someVar1;
int someVar2;
public:
ServerEventHandler(int var1, var2): someVar1(var1), someVar2(var2) {}
void OnMessage(const Message* msg)
{
std::cout << "ServerEventHandler"
}
};
I would like to store event handlers in a vector sorted by their type. I know that the best data structure for this application would be std::multimap, however due to the nature of this problem I am only allowed to use a vector.
I can only think of wrapping eventHandler in another class Listener to be able to do it. Currently I am using a templated function registerHandler for that.
My gut feeling tells me that this is not an elegant way to do it. For example to be able to find a proper position where the new handler will be placed I will need to create a temporary listener which doesnt sound right to me. I am using templated function because I would like to do in place construction.
struct Listener
{
int32_t eventType;
std::unique_ptr<EventHandler> handle;
};
std::vector<Listener> listeners;
template<typename HandlerType, typename ...HandlerParametersType>
int registerHandler(int type, HandlerParametersType&&... handlerParams)
{
Listener m_searchValue;
m_searchValue.m_type = type;
/* Listeners are sorted in the vector by their type */
auto pos = std::lower_bound(m_listeners.begin(), m_listeners.end(), m_searchValue, [](const Listener& theirs, const Listener& my)
{
if (theirs.m_type < my.m_type)
return true;
else
return false;
}
);
pos = listeners.emplace(pos, type, std::move(std::make_unique<HandlerType>(std::forward<HandlerParametersType>(handlerParams)...)));
}
This is how I will call it
registerHandler<ServerEventHandler>(MESSAGE_TYPE_3, 4, 5);
Aucun commentaire:
Enregistrer un commentaire