Updated useEvent
This commit is contained in:
@ -11,24 +11,40 @@ namespace Dawn {
|
||||
class StateOwner {
|
||||
private:
|
||||
std::vector<IStateEvent*> eventsSubscribed;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* Listen for changees to a state property and involke the provided func
|
||||
* Listen for changes to a state property and invoke the provided func
|
||||
* when the value is changed.
|
||||
*
|
||||
* @tparam V The type of the state property.
|
||||
* @param property Property to listen for affect changees to.
|
||||
* @param fn The callback to be invoked when the state value changes.
|
||||
* @param property Property to listen for affect changees to.
|
||||
*/
|
||||
template<class V>
|
||||
void useEffect(
|
||||
StateProperty<V> &property,
|
||||
const std::function<void()> &fn
|
||||
const std::function<void()> &fn,
|
||||
IStateProperty &property
|
||||
) {
|
||||
property._effectListners.push_back(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for changes to a set of state properties and invoke the provided
|
||||
* func when any of their values are changed.
|
||||
*
|
||||
* @param fn The callback to be invoked when the state value changes.
|
||||
* @param property Vector list of properties to listen for changes to.
|
||||
*/
|
||||
void useEffect(
|
||||
const std::function<void()> &fn,
|
||||
std::vector<IStateProperty*> props
|
||||
) {
|
||||
auto itProp = props.begin();
|
||||
while(itProp != props.end()) {
|
||||
(*itProp)->_effectListners.push_back(fn);
|
||||
++itProp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -36,16 +52,38 @@ namespace Dawn {
|
||||
*
|
||||
* @tparam F The type of the callback function.
|
||||
* @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.
|
||||
* @param event The event that is being subscribed to.
|
||||
*/
|
||||
template<typename F, typename... A>
|
||||
void useEvent(StateEvent<A...> &event, F fn) {
|
||||
event._eventListeners[this].push_back(fn);
|
||||
this->eventsSubscribed.push_back(&event);
|
||||
std::function<void()> useEvent(F fn, StateEvent<A...> &event) {
|
||||
|
||||
// Create a listener structure
|
||||
struct StateEventListener<A...> listener;
|
||||
listener.listener = fn;
|
||||
listener.owner = this;
|
||||
listener.event = &event;
|
||||
listener.unsubWithParams = [&](struct StateEventListener<A...> listener) {
|
||||
auto itFound = listener.event->_eventListeners.begin();
|
||||
while(itFound != listener.event->_eventListeners.end()) {
|
||||
if(itFound->id == listener.id) {
|
||||
listener.event->_eventListeners.erase(itFound);
|
||||
break;
|
||||
}
|
||||
++itFound++;
|
||||
}
|
||||
};
|
||||
listener.id = event.stateEventId++;
|
||||
listener.unsub = std::bind(listener.unsubWithParams, listener);
|
||||
|
||||
// Put that listener structure on to the event stack
|
||||
event._eventListeners.push_back(listener);
|
||||
this->eventsSubscribed.push_back(&event);
|
||||
|
||||
return listener.unsub;
|
||||
}
|
||||
|
||||
~StateOwner() {
|
||||
virtual ~StateOwner() {
|
||||
auto it = this->eventsSubscribed.begin();
|
||||
while(it != this->eventsSubscribed.end()) {
|
||||
(*it)->_stateOwnerDestroyed(this);
|
||||
|
@ -9,8 +9,28 @@
|
||||
namespace Dawn {
|
||||
class StateOwner;
|
||||
|
||||
template<typename...A>
|
||||
class StateEvent;
|
||||
|
||||
template<typename...A>
|
||||
struct StateEventListener {
|
||||
uint32_t id;
|
||||
StateOwner *owner;
|
||||
std::function<void(A...)> listener;
|
||||
std::function<void(StateEventListener<A...>)> unsubWithParams;
|
||||
std::function<void()> unsub;
|
||||
StateEvent<A...> *event;
|
||||
};
|
||||
|
||||
class IStateEvent {
|
||||
protected:
|
||||
/**
|
||||
* Received notification from a state owner to let this state event know
|
||||
* that it wishes to unsubscribe all the event listeners that it may have
|
||||
* attached to this event.
|
||||
*
|
||||
* @param owner State owner that is being disposed.
|
||||
*/
|
||||
virtual void _stateOwnerDestroyed(StateOwner *owner) = 0;
|
||||
|
||||
friend class StateOwner;
|
||||
@ -19,12 +39,21 @@ namespace Dawn {
|
||||
template<typename...A>
|
||||
class StateEvent : public IStateEvent {
|
||||
protected:
|
||||
uint32_t stateEventId = 0;
|
||||
|
||||
void _stateOwnerDestroyed(StateOwner *owner) override {
|
||||
this->_eventListeners.erase(owner);
|
||||
auto it = this->_eventListeners.begin();
|
||||
while(it != this->_eventListeners.end()) {
|
||||
if(it->owner == owner) {
|
||||
it = this->_eventListeners.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::map<StateOwner*, std::vector<std::function<void(A...)>>> _eventListeners;
|
||||
std::vector<StateEventListener<A...>> _eventListeners;
|
||||
|
||||
/**
|
||||
* Invokes the event and emits to all of the listeners.
|
||||
@ -32,15 +61,22 @@ namespace Dawn {
|
||||
* @param args Arguments for this event to pass to the listeners.
|
||||
*/
|
||||
void invoke(A... args) {
|
||||
auto itListeners = this->_eventListeners.begin();
|
||||
while(itListeners != this->_eventListeners.end()) {
|
||||
auto itLists = itListeners->second.begin();
|
||||
while(itLists != itListeners->second.end()) {
|
||||
(*itLists)(args...);
|
||||
++itLists;
|
||||
}
|
||||
++itListeners;
|
||||
auto it = this->_eventListeners.begin();
|
||||
while(it != this->_eventListeners.end()) {
|
||||
it->listener(args...);
|
||||
++it;
|
||||
}
|
||||
// auto itListeners = this->_eventListeners.begin();
|
||||
// while(itListeners != this->_eventListeners.end()) {
|
||||
// auto itLists = itListeners->second.begin();
|
||||
// while(itLists != itListeners->second.end()) {
|
||||
// (*itLists)(args...);
|
||||
// ++itLists;
|
||||
// }
|
||||
// ++itListeners;
|
||||
// }
|
||||
}
|
||||
|
||||
friend class StateOwner;
|
||||
};
|
||||
}
|
@ -7,8 +7,13 @@
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class IStateProperty {
|
||||
public:
|
||||
std::vector<std::function<void()>> _effectListners;
|
||||
};
|
||||
|
||||
template<class V>
|
||||
class StateProperty {
|
||||
class StateProperty : public IStateProperty {
|
||||
private:
|
||||
/**
|
||||
* Method that is invoked every time that the value of this state property
|
||||
@ -31,7 +36,6 @@ namespace Dawn {
|
||||
|
||||
public:
|
||||
V _realValue;
|
||||
std::vector<std::function<void()>> _effectListners;
|
||||
V previous;
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user