Dawn/src/dawn/state/StateEvent.hpp
2023-02-28 22:18:26 -08:00

82 lines
2.2 KiB
C++

// 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;
};
}