Added state event.

This commit is contained in:
2023-02-27 12:46:02 -08:00
parent e625078efe
commit fc34ae94ff
5 changed files with 88 additions and 18 deletions

View File

@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "assert/assert.hpp"
#include "StateEvent.hpp"
namespace Dawn {
template<class V>
@ -12,15 +12,10 @@ namespace Dawn {
class StateOwner {
private:
std::map<void*, std::vector<std::function<void()>>> effects;
std::map<void*, std::vector<std::function<void()>>> effectListeners;
std::vector<std::function<void()>> stateUpdateListeners;
public:
/**
* Invoked event listener for the subclass that listens for all changes
* to any part of this state updated.
*/
virtual void onStateUpdate() = 0;
/**
* Creates a new state property and listens for its change.
*
@ -46,7 +41,32 @@ namespace Dawn {
*/
template<class V>
void useEffect(StateProperty<V> &property, const std::function<void()> &fn) {
this->effects[(void*)&property].push_back(fn);
assertFalse(property.owner == this);
this->effectListeners[(void*)&property].push_back(fn);
}
/**
* Listen for changes to any single state property managed by this state
* owner.
*
* @param fn Function to be invoked when any state property is updated.
*/
void useStateUpdated(const std::function<void()> &fn) {
this->stateUpdateListeners.push_back(fn);
}
/**
* Listen for when an event is invoked by a state event. This is intended
* to allow for cross-state-owner communication in a simple and effective
* way.
*
* @tparam A The arguments from the state event that are calledback.
* @param event The event that is being subscribed to.
* @param fn The function to be inokved on event trigger.
*/
template<typename...A>
void useEvent(StateEvent<A...> &event, const std::function<void(A...)> &fn) {
event.listeners.push_back(fn);
}
/**
@ -60,14 +80,19 @@ namespace Dawn {
*/
template<class V>
void _statePropertyUpdated(StateProperty<V> *prop, V n, V o) {
this->onStateUpdate();
auto eff = &this->effects[prop];
auto eff = &this->effectListeners[prop];
auto itEff = eff->begin();
while(itEff != eff->end()) {
(*itEff)();
++itEff;
}
auto itUpdate = this->stateUpdateListeners.begin();
while(itUpdate != this->stateUpdateListeners.end()) {
(*itUpdate)();
++itUpdate;
}
}
/**
@ -79,7 +104,11 @@ namespace Dawn {
*/
template<class V>
void _statePropertyDestroyed(StateProperty<V> *prop) {
this->effects.erase((void*)prop);
this->effectListeners.erase((void*)prop);
}
virtual ~StateOwner() {
}
};
}