I am currently trying to implement a messenger system for my game engine. It uses function callbacks of the form:
typedef std::function<void(const Message &)> Callback;
It maintains a message list:
mutable std::vector<std::unique_ptr<Message>> messageList;
And a callback dictionary of signature:
mutable std::map<std::string, std::vector<Callback>> callbackDictionary;
which is used to call all the callbacks 'bound' to a specific message type. When the callback function is called, the respective message is passed. So far so good.
For better understanding, here is the subscribe method that lets the user add a function method that is called for every message of the subscribed to type.
void Messenger::Subscribe(Message::Type type, Callback callbackFunction)
const
{
callbackDictionary[type].push_back(callbackFunction);
}
And here an example of how it used (by the clickable component class)
messageBus.Subscribe("Message/Click", [this](const Message & message) {this->OnClick(static_cast<const ClickMessage &>(message)); });
Now my problem:
I want to implement an unsubscribe method that finds a function/method in the dictionary's vector and removes it. Note that the function could be subscribed to more than one message type. I was thinking of something like this:
void Messenger::UnSubscribe(Callback callbackFunction)
{
for (auto & pair : callbackDictionary)
{
auto & functionList = pair.second;
for (auto function : functionList)
{
if (function == callbackFunction)
functionList.erase(std::remove(functionList.begin(), functionList.end(), function), functionList.end());
// I am aware of issues that may appear from looping deleting while looping
}
}
}
However, the comparison operator (==) appears to be undefined for function objects. I couldn't come up with an easy way to get around this. So any ideas are much apprechiated. I am just trying to avoid some kind of id system cause from experience the can be a chore to manage. Especially when all kinds of functions and members can be added everywhere throughout the program.