Last active
December 26, 2024 14:35
-
-
Save mmj-the-fighter/52b1b3ca0a15aee1bf96bcebd37184e3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <map> | |
#include <functional> | |
#include <vector> | |
#include <iostream> | |
#include <set> | |
#include <algorithm> | |
using Message = std::string; | |
using Topic = std::string; | |
using Client = std::string; | |
using Callback = std::function<void(Message&)>; | |
using ClientCallbackSetMap = std::map<Client, std::vector<Callback>>; | |
using TopicSubscriberInfoMap = std::map<Topic, ClientCallbackSetMap>; | |
class MessageDispatcher | |
{ | |
TopicSubscriberInfoMap topicSubscriberInfoMap; | |
public: | |
void Subscribe(Topic topic, Client client, Callback callback) { | |
topicSubscriberInfoMap[topic][client].push_back(callback); | |
} | |
void Unsubscribe(const Topic& topic, const Client& client, const Callback& callback) { | |
if (topicSubscriberInfoMap.count(topic) && topicSubscriberInfoMap[topic].count(client)) { | |
auto& clientCallbacks = topicSubscriberInfoMap[topic][client]; | |
auto it = std::find_if(clientCallbacks.begin(), clientCallbacks.end(), | |
[&callback](const Callback& cb) { | |
return cb.target<void(Message&)>() == callback.target<void(Message&)>(); | |
} | |
); | |
if (it != clientCallbacks.end()) { | |
clientCallbacks.erase(it); | |
} | |
if (topicSubscriberInfoMap[topic][client].empty()) { | |
topicSubscriberInfoMap[topic].erase(client); | |
if (topicSubscriberInfoMap[topic].empty()) { | |
topicSubscriberInfoMap.erase(topic); | |
} | |
} | |
} | |
} | |
void BroadCast(const Topic& topic, const Message& message) { | |
auto it = topicSubscriberInfoMap.find(topic); | |
if (it != topicSubscriberInfoMap.end()) { | |
const auto& callbackMap = it->second; | |
for (const auto& clientCallbackSetPair : callbackMap) { | |
for (const auto& callback : clientCallbackSetPair.second) { | |
Message mutableMessage = message; | |
callback(mutableMessage); | |
} | |
} | |
} | |
} | |
void MultiCast(const Topic& topic, const Message& message, const std::set<Client> targetClients) { | |
auto it = topicSubscriberInfoMap.find(topic); | |
if (it != topicSubscriberInfoMap.end()) { | |
const auto& callbackMap = it->second; | |
for (const auto& clientCallbackSetPair : callbackMap) { | |
Client client = clientCallbackSetPair.first; | |
if (targetClients.find(client) == targetClients.end()) { | |
continue; | |
} | |
for (const auto& callback : clientCallbackSetPair.second) { | |
Message mutableMessage = message; | |
callback(mutableMessage); | |
} | |
} | |
} | |
} | |
void Send(const Topic& topic, const Message& message, const Client& client) { | |
auto it = topicSubscriberInfoMap.find(topic); | |
if (it != topicSubscriberInfoMap.end()) { | |
const auto& callbackMap = it->second; | |
auto it2 = callbackMap.find(client); | |
if (it2 != callbackMap.end()) { | |
for (const auto& callback : it2->second) { | |
Message mutableMessage = message; | |
callback(mutableMessage); | |
} | |
} | |
} | |
} | |
}; | |
void client1_on_greetings(Message& message) { | |
std::cout << "@Client1 received:" << message << "\n"; | |
} | |
void client2_on_greetings(Message& message) { | |
std::cout << "@Client2 received:" << message << "\n"; | |
} | |
void client3_on_greetings(Message& message) { | |
std::cout << "@Client3 received:" << message << "\n"; | |
} | |
void client4_on_greetings(Message& message) { | |
std::cout << "@Client4 received:" << message << "\n"; | |
} | |
void client5_on_greetings(Message& message) { | |
std::cout << "@Client5 received:" << message << "\n"; | |
} | |
int main(int argc, char* argv[]) { | |
MessageDispatcher pmd; | |
//register as event subscriber | |
pmd.Subscribe("/greetings", "Client1", client1_on_greetings); | |
pmd.Subscribe("/greetings", "Client2", client2_on_greetings); | |
pmd.Subscribe("/greetings", "Client3", client3_on_greetings); | |
pmd.Subscribe("/greetings", "Client4", client4_on_greetings); | |
pmd.Subscribe("/greetings", "Client5", client5_on_greetings); | |
//unregister an event | |
pmd.Unsubscribe("/greetings", "Client2", client2_on_greetings); | |
//fire an event | |
std::cout << "Event Brodcasting" << "\n"; | |
pmd.BroadCast("/greetings", "hi"); | |
std::cout << "\n"; | |
std::cout <<"Sending Event to a particular subscriber" << "\n"; | |
pmd.Send("/greetings", "hola", "Client1"); | |
std::cout << "\n"; | |
std::cout << "Sending Event to a subset of subscribers" << "\n"; | |
pmd.MultiCast("/greetings", "namaste", { "Client3", "Client5"}); | |
std::cout << "\n"; | |
} | |
/* output: | |
Event Brodcasting | |
@Client1 received:hi | |
@Client3 received:hi | |
@Client4 received:hi | |
@Client5 received:hi | |
Sending Event to a particular subscriber | |
@Client1 received:hola | |
Sending Event to a subset of subscribers | |
@Client3 received:namaste | |
@Client5 received:namaste | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment