Skip to content

Instantly share code, notes, and snippets.

@gabrielhamel
Last active September 22, 2021 13:10
Show Gist options
  • Save gabrielhamel/b992ea8f470d5980545a7934dcb3988a to your computer and use it in GitHub Desktop.
Save gabrielhamel/b992ea8f470d5980545a7934dcb3988a to your computer and use it in GitHub Desktop.
Observable template C++
#ifndef CPP_OBSERVABLE_H
#define CPP_OBSERVABLE_H
#include <unordered_map>
#include <functional>
namespace Design {
typedef unsigned long long Subscriber;
template<typename T>
class Observable {
public:
virtual Subscriber subscribe(std::function<void(const T &)> &&next, std::function<void()> &&end = [] {}) = 0;
virtual void unsubscribe(Subscriber subscriber) = 0;
virtual ~Observable() {};
};
template<typename T>
class BehaviorSubject : public Observable<T> {
private:
std::unordered_map<Subscriber, std::function<void(const T &)>> m_next_subscribers;
std::unordered_map<Subscriber, std::function<void()>> m_end_subscribers;
private:
Subscriber generateSubscriber() const;
public:
BehaviorSubject();
Subscriber subscribe(std::function<void(const T &)> &&next, std::function<void()> &&end = [] {});
void unsubscribe(Subscriber subscriber);
void next(const T &value);
void end();
};
template<typename T>
BehaviorSubject<T>::BehaviorSubject() {
}
template<typename T>
Subscriber BehaviorSubject<T>::generateSubscriber() const
{
static Subscriber counter = 0;
return counter++;
}
template<typename T>
Subscriber BehaviorSubject<T>::subscribe(std::function<void(const T &)> &&next, std::function<void()> &&end) {
Subscriber sub = this->generateSubscriber();
this->m_next_subscribers.emplace(sub, next);
this->m_end_subscribers.emplace(sub, end);
return sub;
}
template<typename T>
void BehaviorSubject<T>::unsubscribe(Subscriber subscriber) {
this->m_next_subscribers.erase(subscriber);
this->m_end_subscribers.erase(subscriber);
}
template<typename T>
void BehaviorSubject<T>::next(const T &value) {
std::for_each(this->m_next_subscribers.begin(), this->m_next_subscribers.end(), [value](auto &subscriber) {
subscriber.second(value);
});
}
template<typename T>
void BehaviorSubject<T>::end() {
std::for_each(this->m_end_subscribers.begin(), this->m_end_subscribers.end(), [](auto &subscriber) {
subscriber.second();
});
}
} // namespace Design
#endif // CPP_OBSERVABLE_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment