Started upgrading things to new state
This commit is contained in:
@ -4,8 +4,3 @@
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
StateOwner.cpp
|
||||
StateProperty.cpp
|
||||
)
|
@ -4,7 +4,53 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StateEvent.hpp"
|
||||
#include "StateOwner.hpp"
|
||||
#include "StateProperty.hpp"
|
||||
#include "StateProperty.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class StateOwner {
|
||||
private:
|
||||
std::vector<IStateEvent*> eventsSubscribed;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Listen for changees to a state property and involke 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.
|
||||
*/
|
||||
template<class V>
|
||||
void useEffect(
|
||||
StateProperty<V> &property,
|
||||
const std::function<void()> &fn
|
||||
) {
|
||||
property._effectListners.push_back(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* way.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
template<typename F, typename... A>
|
||||
void useEvent(StateEvent<A...> &event, F fn) {
|
||||
event._eventListeners[this].push_back(fn);
|
||||
this->eventsSubscribed.push_back(&event);
|
||||
}
|
||||
|
||||
~StateOwner() {
|
||||
auto it = this->eventsSubscribed.begin();
|
||||
while(it != this->eventsSubscribed.end()) {
|
||||
(*it)->_stateOwnerDestroyed(this);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -9,25 +9,38 @@
|
||||
namespace Dawn {
|
||||
class StateOwner;
|
||||
|
||||
class IStateEvent {
|
||||
protected:
|
||||
virtual void _stateOwnerDestroyed(StateOwner *owner) = 0;
|
||||
|
||||
friend class StateOwner;
|
||||
};
|
||||
|
||||
template<typename...A>
|
||||
class StateEvent {
|
||||
private:
|
||||
std::vector<std::function<void(A...)>> listeners;
|
||||
class StateEvent : public IStateEvent {
|
||||
protected:
|
||||
void _stateOwnerDestroyed(StateOwner *owner) override {
|
||||
this->_eventListeners.erase(owner);
|
||||
}
|
||||
|
||||
public:
|
||||
std::map<StateOwner*, std::vector<std::function<void(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 itListeners = this->listeners.begin();
|
||||
while(itListeners != this->listeners.end()) {
|
||||
(*itListeners)(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;
|
||||
}
|
||||
}
|
||||
|
||||
friend class StateOwner;
|
||||
};
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "State.hpp"
|
||||
|
||||
using namespace Dawn;
|
@ -1,114 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "StateEvent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<class V>
|
||||
class StateProperty;
|
||||
|
||||
class StateOwner {
|
||||
private:
|
||||
std::map<void*, std::vector<std::function<void()>>> effectListeners;
|
||||
std::vector<std::function<void()>> stateUpdateListeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new state property and listens for its change.
|
||||
*
|
||||
* @tparam V The type of the state that is held.
|
||||
* @param initial The initial value of this state.
|
||||
* @return The state that can then be listened for.
|
||||
*/
|
||||
template<class V>
|
||||
StateProperty<V> useState(V initial) {
|
||||
auto property = StateProperty<V>();
|
||||
property.value = initial;
|
||||
property.owner = this;
|
||||
return property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for changees to a state property and involke 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.
|
||||
*/
|
||||
template<class V>
|
||||
void useEffect(StateProperty<V> &property, const std::function<void()> &fn) {
|
||||
assertFalse(property.owner == this);
|
||||
this->effectListeners[(void*)&property].push_back(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for changes to any single state property managed by this state
|
||||
* owner.
|
||||
*
|
||||
* @param fn Function to be invoked when any state property is updated.
|
||||
*/
|
||||
void useStateUpdated(const std::function<void()> &fn) {
|
||||
this->stateUpdateListeners.push_back(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* way.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
template<typename...A>
|
||||
void useEvent(StateEvent<A...> &event, const std::function<void(A...)> &fn) {
|
||||
event.listeners.push_back(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method (that has to be exposed) to listen for changes for when
|
||||
* a state property that belongs to this state owner is updated.
|
||||
*
|
||||
* @tparam V The value type of the state property.
|
||||
* @param prop The property that has its value changed in question.
|
||||
* @param n The new, current value of the property.
|
||||
* @param o The old, previous value of the property.
|
||||
*/
|
||||
template<class V>
|
||||
void _statePropertyUpdated(StateProperty<V> *prop, V n, V o) {
|
||||
auto eff = &this->effectListeners[prop];
|
||||
|
||||
auto itEff = eff->begin();
|
||||
while(itEff != eff->end()) {
|
||||
(*itEff)();
|
||||
++itEff;
|
||||
}
|
||||
|
||||
auto itUpdate = this->stateUpdateListeners.begin();
|
||||
while(itUpdate != this->stateUpdateListeners.end()) {
|
||||
(*itUpdate)();
|
||||
++itUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to listen for when a state property is disposed or
|
||||
* destroyed so that it can be completely removed from this state owner.
|
||||
*
|
||||
* @tparam V Value type.
|
||||
* @param prop Property that was destroyed.
|
||||
*/
|
||||
template<class V>
|
||||
void _statePropertyDestroyed(StateProperty<V> *prop) {
|
||||
this->effectListeners.erase((void*)prop);
|
||||
}
|
||||
|
||||
virtual ~StateOwner() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "State.hpp"
|
||||
|
||||
using namespace Dawn;
|
@ -7,14 +7,9 @@
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class StateOwner;
|
||||
|
||||
template<class V>
|
||||
class StateProperty {
|
||||
private:
|
||||
StateOwner *owner;
|
||||
V value;
|
||||
|
||||
/**
|
||||
* Method that is invoked every time that the value of this state property
|
||||
* is updated.
|
||||
@ -22,25 +17,45 @@ namespace Dawn {
|
||||
* @param val Value that is to be used for this property.
|
||||
*/
|
||||
void setInternal(V val) {
|
||||
if(val == this->value) return;// TODO: can I omit this? kinda bad tbh.
|
||||
assertNotNull(this->owner);
|
||||
auto old = this->value;
|
||||
this->value = val;
|
||||
this->owner->_statePropertyUpdated(this, val, old);
|
||||
if(val == this->_realValue) return;// TODO: can I omit this? kinda bad tbh.
|
||||
this->previous = this->_realValue;
|
||||
this->_realValue = val;
|
||||
|
||||
// Notify the effect listeners
|
||||
auto itEffect = this->_effectListners.begin();
|
||||
while(itEffect != this->_effectListners.end()) {
|
||||
(*itEffect)();
|
||||
++itEffect;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
V _realValue;
|
||||
std::vector<std::function<void()>> _effectListners;
|
||||
V previous;
|
||||
|
||||
/**
|
||||
* Creates a new state property and listens for its change.
|
||||
*/
|
||||
StateProperty() {}
|
||||
|
||||
/**
|
||||
* Creates a new state property and listens for its change.
|
||||
* @param initial The initial value of this state.
|
||||
*/
|
||||
StateProperty(V initial) : _realValue(initial) {}
|
||||
|
||||
const StateProperty& operator += (const V &value) {
|
||||
this->setInternal(this->value + value);
|
||||
this->setInternal(this->_realValue + value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const bool_t operator != (const V &value) {
|
||||
return value != this->value;
|
||||
return value != this->_realValue;
|
||||
}
|
||||
|
||||
const bool_t operator == (const V &value) {
|
||||
return value == this->value;
|
||||
return value == this->_realValue;
|
||||
}
|
||||
|
||||
const StateProperty& operator = (const V &val) {
|
||||
@ -49,15 +64,13 @@ namespace Dawn {
|
||||
}
|
||||
|
||||
operator V() const {
|
||||
return this->value;
|
||||
return this->_realValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for StateProperty.
|
||||
*/
|
||||
~StateProperty() {
|
||||
this->owner->_statePropertyDestroyed(this);
|
||||
}
|
||||
~StateProperty() {}
|
||||
|
||||
friend class StateOwner;
|
||||
};
|
||||
|
Reference in New Issue
Block a user