I am trying to create a templated dispatcher to handle the registering of consumers, and pushing of data from producers. The goals are:
- When a user calls push(myData) a static (singleton-ish) dispatcher is used.
- When a user registers a callback interested in data of type T, they register their callback to the dispatcher of type T.
- #1 or #2 can occur first, register before push, or push before register. This is why a static/singleton-ish dispatcher is used. Also want to make sure both producers and consumers are referring to the same dispatcher.
- I will have many different message/data types going through the system so wanted to create a generic producer/consumer/dispatch.
This is what I have so far. It compiles fine however the callback does not work or get triggered. Names are temporary while experimenting.
main.cpp
#include "t.h"
#include <string>
#include <iostream>
/* My concrete class/data that needs to be sent out */
class A {
public:
std::string name() const {return "A";}
};
/* Consumer callback */
void callback(const A& a);
int main() {
A a;
std::function<void(const A&)> f = callback;
/* Try and register for A objects */
reg<A>(f);
/* Push the A object, should in theory call callback() but it doesnt */
push(a);
}
void callback(const A& a) {
std::cout << "I got callbacked with " << a.name() << std::endl;
}
t.h So in this example I am hoping to create a dispatcher of A objects in reg(), and then on push() use the same dispatcher to notify observers. I have print statements on the type for my debugging of this problem.
// t.h
#include <iostream>
#include <functional>
#include <vector>
#include <typeinfo>
/* Generic dispatcher of type T objects */
template<typename T>
class Dispatcher {
public:
/* Users register a callback to get incoming T objects */
void Register(std::function<void(const T&)> f) {
observers_.push_back(f);
}
/* On push() notify all observers with the new data */
void Notify(const T& t) const {
for (auto o : observers_) {
o(t);
}
}
private:
std::vector<std::function<void(const T&)>> observers_;
};
/* For creating only 1 dispatcher of type T, so push() and reg() are referring to the same object */
template<typename T>
T& Get() {
static T t_;
std::cout << "Get " << typeid(T).name() << std::endl;
return t_;
}
/* Producers push new T objects */
template<typename T>
void push(const T& t) {
std::cout << "Push " << typeid(T).name() << std::endl;
auto d = Get<Dispatcher<T>>();
d.Notify(t);
}
/* Consumers register for new T objects */
template<typename T>
void reg(std::function<void(const T& t)> f) {
auto d = Get<Dispatcher<T>>();
std::cout << "reg " << typeid(T).name() << std::endl;
d.Register(f);
}
Aucun commentaire:
Enregistrer un commentaire