More work on State System
This commit is contained in:
@ -8,12 +8,12 @@
|
|||||||
#include "assert/assert.hpp"
|
#include "assert/assert.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
|
|
||||||
template<typename... A>
|
template<typename... A>
|
||||||
struct IEventListener {
|
struct IEventListener {
|
||||||
/**
|
/**
|
||||||
* Abstracted method for C++ template reasons. Invokes the listener.
|
* Abstracted method for C++ template reasons. Invokes the listener.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @param args Arguments to pass to the listener.
|
* @param args Arguments to pass to the listener.
|
||||||
*/
|
*/
|
||||||
virtual void invoke(A... args) = 0;
|
virtual void invoke(A... args) = 0;
|
||||||
@ -27,6 +27,7 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Construct a new event listener structure.
|
* Construct a new event listener structure.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @param instance Instance that the callback belongs to.
|
* @param instance Instance that the callback belongs to.
|
||||||
* @param callback Callback method that invokes back.
|
* @param callback Callback method that invokes back.
|
||||||
*/
|
*/
|
||||||
@ -42,6 +43,7 @@ namespace Dawn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
template<typename...A>
|
template<typename...A>
|
||||||
class Event {
|
class Event {
|
||||||
private:
|
private:
|
||||||
@ -51,6 +53,7 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Add a listener to this event.
|
* Add a listener to this event.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @tparam T The class that will receive the event.
|
* @tparam T The class that will receive the event.
|
||||||
* @param instance Instance of type T that will receive the callback.
|
* @param instance Instance of type T that will receive the callback.
|
||||||
* @param callback Callback method attached to T to receive the event.
|
* @param callback Callback method attached to T to receive the event.
|
||||||
@ -72,6 +75,7 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Removes an event listener from this event.
|
* Removes an event listener from this event.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @tparam T The class that was once receiving the event.
|
* @tparam T The class that was once receiving the event.
|
||||||
* @param instance Instance of type T that did receive the callback.
|
* @param instance Instance of type T that did receive the callback.
|
||||||
* @param callback Callback method attached to T for the event.
|
* @param callback Callback method attached to T for the event.
|
||||||
@ -99,6 +103,7 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Invokes the event and emits to all of the listeners.
|
* Invokes the event and emits to all of the listeners.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
* @param args Arguments for this event to pass to the listeners.
|
* @param args Arguments for this event to pass to the listeners.
|
||||||
*/
|
*/
|
||||||
void invoke(A... args) {
|
void invoke(A... args) {
|
||||||
|
@ -8,10 +8,44 @@
|
|||||||
#include "StateProperty.hpp"
|
#include "StateProperty.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
|
template<typename ...A>
|
||||||
|
class StateOwnerEventLegacy : public IStateOwnerEventLegacy {
|
||||||
|
public:
|
||||||
|
IStateOwner *owner;
|
||||||
|
Event<A...> *event;
|
||||||
|
std::function<void(A...)> fn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function used to simply remove the event listener from the legacy
|
||||||
|
* event, does not deal with the state owner.
|
||||||
|
*/
|
||||||
|
void removeListener() override {
|
||||||
|
event->removeListener(this, &StateOwnerEventLegacy::callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that can be used to tear down this legacy event.
|
||||||
|
*/
|
||||||
|
void teardown() override {
|
||||||
|
this->removeListener();
|
||||||
|
owner->_stateLegacyEventDisposed(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbaack method that is invoked by the legacy event.
|
||||||
|
* @param args Arguments received by legacy event.
|
||||||
|
*/
|
||||||
|
void callback(A... args) {
|
||||||
|
this->fn(args...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class StateOwner : public IStateOwner {
|
class StateOwner : public IStateOwner {
|
||||||
private:
|
private:
|
||||||
std::vector<IStateEvent*> eventsSubscribed;
|
std::vector<IStateEvent*> eventsSubscribed;
|
||||||
|
std::vector<IStateOwnerEventLegacy*> eventLegacyBridge;
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* Called by the state event when it is disposing (before the StateOwner
|
* Called by the state event when it is disposing (before the StateOwner
|
||||||
* itself is).
|
* itself is).
|
||||||
@ -28,8 +62,25 @@ namespace Dawn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
/**
|
||||||
|
* Called by legacy events when they are being disposed in a way that was
|
||||||
|
* not called by this state owner disposing.
|
||||||
|
*
|
||||||
|
* @param evt Event that is being disposed.
|
||||||
|
*/
|
||||||
|
void _stateLegacyEventDisposed(IStateOwnerEventLegacy *evt) override {
|
||||||
|
auto it = this->eventLegacyBridge.begin();
|
||||||
|
while(it != this->eventLegacyBridge.end()) {
|
||||||
|
if(*it == evt) {
|
||||||
|
this->eventLegacyBridge.erase(it);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen for changes to a state property and invoke the provided func
|
* Listen for changes to a state property and invoke the provided func
|
||||||
* when the value is changed.
|
* when the value is changed.
|
||||||
@ -126,15 +177,55 @@ namespace Dawn {
|
|||||||
|
|
||||||
return listener.unsub;
|
return listener.unsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for callback of a legacy styled event. This will be removed in
|
||||||
|
* the future in favour of everything using State Events. This uses a lot
|
||||||
|
* more memory than the new state event listener.
|
||||||
|
*
|
||||||
|
* @deprecated In favour of StateEvent<>
|
||||||
|
* @tparam F The type of the callback function.
|
||||||
|
* @tparam A Argument types for the event.
|
||||||
|
* @param fn Callback function to be invoked when the event is triggered.
|
||||||
|
* @param event Event that will be listened to.
|
||||||
|
*/
|
||||||
|
template<typename F, typename... A>
|
||||||
|
std::function<void()> useEventLegacy(
|
||||||
|
F fn,
|
||||||
|
Event<A...> &event
|
||||||
|
) {
|
||||||
|
// This is a legacy feature to make upgrading to the new useEffect a bit
|
||||||
|
// easier for me. For the time being I am just bodging this together to
|
||||||
|
// do what I need here.
|
||||||
|
auto bridge = new StateOwnerEventLegacy<A...>();
|
||||||
|
bridge->owner = this;
|
||||||
|
bridge->event = &event;
|
||||||
|
bridge->fn = fn;
|
||||||
|
event.addListener(bridge, &StateOwnerEventLegacy<A...>::callback);
|
||||||
|
eventLegacyBridge.push_back(bridge);
|
||||||
|
|
||||||
|
return std::bind([&](IStateOwnerEventLegacy *evt){
|
||||||
|
evt->teardown();
|
||||||
|
}, bridge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State Owner teardown function. Mostly just used to remove any lingering
|
||||||
|
* useEffects or useEvents.
|
||||||
|
*/
|
||||||
virtual ~StateOwner() {
|
virtual ~StateOwner() {
|
||||||
auto it = this->eventsSubscribed.begin();
|
auto it = this->eventsSubscribed.begin();
|
||||||
while(it != this->eventsSubscribed.end()) {
|
while(it != this->eventsSubscribed.end()) {
|
||||||
(*it)->_stateOwnerDestroyed(this);
|
(*it)->_stateOwnerDestroyed(this);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto itBridge = this->eventLegacyBridge.begin();
|
||||||
|
while(itBridge != this->eventLegacyBridge.end()) {
|
||||||
|
(*itBridge)->removeListener();
|
||||||
|
delete *itBridge;
|
||||||
|
++itBridge;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,31 +4,14 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "assert/assert.hpp"
|
#include "StateInterfaces.hpp"
|
||||||
#include "event/Event.hpp"
|
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
/** Forwarders / Fake Virtuals for other methods. */
|
|
||||||
template<typename...A>
|
template<typename...A>
|
||||||
class StateEvent;
|
class StateEvent : public IStateEvent {
|
||||||
class IStateEvent;
|
|
||||||
class IStateOwner {
|
|
||||||
public:
|
|
||||||
virtual void _stateEventDisposed(IStateEvent *evt) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename...A>
|
|
||||||
struct StateEventListener {
|
|
||||||
uint32_t id;
|
|
||||||
IStateOwner *owner;
|
|
||||||
std::function<void(A...)> listener;
|
|
||||||
std::function<void(StateEventListener<A...>)> unsubWithParams;
|
|
||||||
std::function<void()> unsub;
|
|
||||||
StateEvent<A...> *event;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IStateEvent {
|
|
||||||
protected:
|
protected:
|
||||||
|
uint32_t stateEventId = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Received notification from a state owner to let this state event know
|
* 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
|
* that it wishes to unsubscribe all the event listeners that it may have
|
||||||
@ -36,17 +19,6 @@ namespace Dawn {
|
|||||||
*
|
*
|
||||||
* @param owner State owner that is being disposed.
|
* @param owner State owner that is being disposed.
|
||||||
*/
|
*/
|
||||||
virtual void _stateOwnerDestroyed(IStateOwner *owner) = 0;
|
|
||||||
|
|
||||||
friend class StateOwner;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename...A>
|
|
||||||
class StateEvent : public IStateEvent {
|
|
||||||
protected:
|
|
||||||
uint32_t stateEventId = 0;
|
|
||||||
|
|
||||||
/** Refer to IStateEvent::_stateOwnerDestroyed */
|
|
||||||
void _stateOwnerDestroyed(IStateOwner *owner) override {
|
void _stateOwnerDestroyed(IStateOwner *owner) override {
|
||||||
auto it = this->_eventListeners.begin();
|
auto it = this->_eventListeners.begin();
|
||||||
while(it != this->_eventListeners.end()) {
|
while(it != this->_eventListeners.end()) {
|
||||||
|
53
src/dawn/state/StateInterfaces.hpp
Normal file
53
src/dawn/state/StateInterfaces.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (c) 2023 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "assert/assert.hpp"
|
||||||
|
#include "event/Event.hpp"
|
||||||
|
|
||||||
|
namespace Dawn {
|
||||||
|
class IStateEvent;
|
||||||
|
|
||||||
|
template<typename...A>
|
||||||
|
class StateEvent;
|
||||||
|
|
||||||
|
template<typename ...A>
|
||||||
|
class StateOwnerEventLegacy;
|
||||||
|
|
||||||
|
class IStateOwnerEventLegacy {
|
||||||
|
public:
|
||||||
|
virtual void removeListener() = 0;
|
||||||
|
virtual void teardown() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IStateOwner {
|
||||||
|
public:
|
||||||
|
virtual void _stateEventDisposed(IStateEvent *evt) = 0;
|
||||||
|
virtual void _stateLegacyEventDisposed(IStateOwnerEventLegacy *evt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename...A>
|
||||||
|
struct StateEventListener {
|
||||||
|
uint32_t id;
|
||||||
|
IStateOwner *owner;
|
||||||
|
std::function<void(A...)> listener;
|
||||||
|
std::function<void(StateEventListener<A...>)> unsubWithParams;
|
||||||
|
std::function<void()> unsub;
|
||||||
|
StateEvent<A...> *event;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IStateProperty {
|
||||||
|
public:
|
||||||
|
std::vector<std::function<void()>> _effectListners;
|
||||||
|
std::vector<std::function<std::function<void()>()>> _effectListnersWithTeardown;
|
||||||
|
std::vector<std::function<void()>> _effectTeardowns;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IStateEvent {
|
||||||
|
protected:
|
||||||
|
virtual void _stateOwnerDestroyed(IStateOwner *owner) = 0;
|
||||||
|
friend class StateOwner;
|
||||||
|
};
|
||||||
|
}
|
@ -4,16 +4,9 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "assert/assert.hpp"
|
#include "StateInterfaces.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class IStateProperty {
|
|
||||||
public:
|
|
||||||
std::vector<std::function<void()>> _effectListners;
|
|
||||||
std::vector<std::function<std::function<void()>()>> _effectListnersWithTeardown;
|
|
||||||
std::vector<std::function<void()>> _effectTeardowns;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
class StateProperty : public IStateProperty {
|
class StateProperty : public IStateProperty {
|
||||||
private:
|
private:
|
||||||
|
@ -17,8 +17,8 @@ namespace Dawn {
|
|||||||
class TicTacToeScene : public Scene {
|
class TicTacToeScene : public Scene {
|
||||||
protected:
|
protected:
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
StateProperty<int32_t> age;
|
int32_t age = 0;
|
||||||
StateEvent<int32_t> ageEvent;
|
std::function<void()> evtUnsub;
|
||||||
|
|
||||||
void stage() override {
|
void stage() override {
|
||||||
camera = Camera::create(this);
|
camera = Camera::create(this);
|
||||||
@ -43,6 +43,11 @@ namespace Dawn {
|
|||||||
tile->ticTacToe->tile = i++;
|
tile->ticTacToe->tile = i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evtUnsub = useEventLegacy([&]{
|
||||||
|
std::cout << "Legacy Event Invoked " << age << std::endl;
|
||||||
|
evtUnsub();
|
||||||
|
}, this->eventSceneUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Asset*> getRequiredAssets() override {
|
std::vector<Asset*> getRequiredAssets() override {
|
||||||
|
Reference in New Issue
Block a user