// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "assert/assert.hpp" 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; }; template<typename...A> class StateEvent : public IStateEvent { protected: uint32_t stateEventId = 0; void _stateOwnerDestroyed(StateOwner *owner) override { auto it = this->_eventListeners.begin(); while(it != this->_eventListeners.end()) { if(it->owner == owner) { it = this->_eventListeners.erase(it); } else { ++it; } } } public: std::vector<StateEventListener<A...>> _eventListeners; /** * Invokes the event and emits to all of the listeners. * * @param args Arguments for this event to pass to the listeners. */ void invoke(A... args) { 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; }; }