Skip to content

Instantly share code, notes, and snippets.

@RazorNd
Created August 8, 2017 19:05
Show Gist options
  • Save RazorNd/a1088376e3dcd17326872615c8987d52 to your computer and use it in GitHub Desktop.
Save RazorNd/a1088376e3dcd17326872615c8987d52 to your computer and use it in GitHub Desktop.
Message bus
#include <iostream>
#include <unordered_map>
#include <typeindex>
#include <functional>
#include <algorithm>
#include <type_traits>
class Message {};
class MessageBus
{
template<typename MessageType>
using Callback = std::function<void(const MessageType&)>;
template<typename MessageType>
struct CallbackWrapper
{
CallbackWrapper(Callback<MessageType> callback) :
callback(callback) {}
void operator () (const Message & message) {
callback(static_cast<const MessageType &>(message));
}
Callback<MessageType> callback;
};
typedef std::unordered_multimap<std::type_index, Callback<Message>> CallbackMultimap;
public:
template<typename MessageType>
void subscribe(Callback<MessageType> callback) {
callbacks.insert({typeid(MessageType), CallbackWrapper<MessageType>(callback)});
}
template<typename MessageType>
void emit(const MessageType &message) {
auto range = callbacks.equal_range(typeid(MessageType));
std::for_each(range.first, range.second, [&message] (CallbackMultimap::value_type &callback) {
callback.second(message);
});
}
private:
CallbackMultimap callbacks;
};
class Test1Message : public Message {
public:
int a = 14;
};
class Test2Message : public Message {
public:
int b = 42;
};
class Test3Message : public Message {
public:
int с = 13;
};
void test1MessageHandler(const Test1Message &message) {
std::cout << "Test1 " << message.a << std::endl;
}
void test2MessageHandler(const Test2Message &message) {
std::cout << "Test2 " << message.b << std::endl;
}
void test2MessageHandler2(const Test2Message &message) {
std::cout << "Another Test2 " << message.b << std::endl;
}
void test3MessageHandler(const Test3Message &message) {
std::cout << "Test3 " << message.с << std::endl;
}
int main()
{
MessageBus bus;
std::function<void (const Test1Message &)> c1 = test1MessageHandler;
std::function<void (const Test2Message &)> c2 = test2MessageHandler;
std::function<void (const Test2Message &)> c22 = test2MessageHandler2;
bus.subscribe(c1);
bus.subscribe(c2);
bus.subscribe(c22);
bus.emit(Test1Message());
bus.emit(Test1Message());
bus.emit(Test1Message());
bus.emit(Test2Message());
bus.emit(Test3Message());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment