Skip to content

Instantly share code, notes, and snippets.

@JSH32
Last active June 30, 2022 04:27
Show Gist options
  • Save JSH32/de6ac7d3ede18f499ba1587af43b7c2e to your computer and use it in GitHub Desktop.
Save JSH32/de6ac7d3ede18f499ba1587af43b7c2e to your computer and use it in GitHub Desktop.
Reactive State
#pragma once
template <class Container, class F>
auto erase_where(Container& c, F&& f) {
return c.erase(std::remove_if(c.begin(), c.end(), std::forward<F>(f)),
c.end());
}
/**
* @brief Reactive state. Listeners will be registered as callbacks to state
* changes on T
*
* @tparam T state type (inherit on T, crtp pattern)
*/
template <class T>
class State {
public:
/**
* @brief Listen to state changes triggered by State<T>
*
* @tparam T state type
*/
class Listener {
T* state;
public:
Listener(T* state) : state(state) {
state->listeners.push_back(this);
}
virtual ~Listener() {
erase_where(state->listeners,
[this](auto* instance) { return this == instance; });
}
T* getState() { return state; }
virtual void onStateUpdate(T* state) = 0;
};
protected:
void dispatchUpdate() {
for (auto* listener : this->listeners)
listener->onStateUpdate(static_cast<T*>(this));
}
private:
std::vector<Listener*> listeners;
friend Listener;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment