From fbfd98ef7732531d52daa0194a7180b666de0909 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 1 Mar 2023 05:56:20 -0800 Subject: [PATCH] Improved proper handling of state events --- src/dawn/state/State.hpp | 19 ++++++++++++++++++- src/dawn/state/StateEvent.hpp | 35 +++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/dawn/state/State.hpp b/src/dawn/state/State.hpp index 9f9c39f4..adac24cd 100644 --- a/src/dawn/state/State.hpp +++ b/src/dawn/state/State.hpp @@ -8,9 +8,26 @@ #include "StateProperty.hpp" namespace Dawn { - class StateOwner { + class StateOwner : public IStateOwner { private: std::vector eventsSubscribed; + + /** + * Called by the state event when it is disposing (before the StateOwner + * itself is). + * + * @param evt Event that is being disposed. + */ + void _stateEventDisposed(IStateEvent *evt) override { + auto it = eventsSubscribed.begin(); + while(it != eventsSubscribed.end()) { + if(*it == evt) { + it = eventsSubscribed.erase(it); + } else { + ++it; + } + } + } public: /** diff --git a/src/dawn/state/StateEvent.hpp b/src/dawn/state/StateEvent.hpp index 2e048388..79b5318a 100644 --- a/src/dawn/state/StateEvent.hpp +++ b/src/dawn/state/StateEvent.hpp @@ -7,15 +7,19 @@ #include "assert/assert.hpp" namespace Dawn { - class StateOwner; - + /** Forwarders / Fake Virtuals for other methods. */ template class StateEvent; + class IStateEvent; + class IStateOwner { + public: + virtual void _stateEventDisposed(IStateEvent *evt) = 0; + }; template struct StateEventListener { uint32_t id; - StateOwner *owner; + IStateOwner *owner; std::function listener; std::function)> unsubWithParams; std::function unsub; @@ -31,7 +35,7 @@ namespace Dawn { * * @param owner State owner that is being disposed. */ - virtual void _stateOwnerDestroyed(StateOwner *owner) = 0; + virtual void _stateOwnerDestroyed(IStateOwner *owner) = 0; friend class StateOwner; }; @@ -41,7 +45,8 @@ namespace Dawn { protected: uint32_t stateEventId = 0; - void _stateOwnerDestroyed(StateOwner *owner) override { + /** Refer to IStateEvent::_stateOwnerDestroyed */ + void _stateOwnerDestroyed(IStateOwner *owner) override { auto it = this->_eventListeners.begin(); while(it != this->_eventListeners.end()) { if(it->owner == owner) { @@ -66,15 +71,17 @@ namespace Dawn { 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; - // } + } + + /** + * Disposal of a state event. + */ + ~StateEvent() { + auto it = this->_eventListeners.begin(); + while(it != this->_eventListeners.end()) { + it->owner->_stateEventDisposed(this); + ++it; + } } friend class StateOwner;