Dawn/src/dawn/state/StateProperty.hpp

140 lines
3.7 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "StateInterfaces.hpp"
namespace Dawn {
template<class V>
class StateProperty : public IStateProperty {
private:
/**
* Method that is invoked every time that the value of this state property
* is updated.
*
* @param val Value that is to be used for this property.
*/
void setInternal(V val) {
if(val == this->_realValue) return;// TODO: can I omit this? kinda bad tbh.
// Run the teardowns
auto itTeardown = this->_effectTeardowns.begin();
while(itTeardown != this->_effectTeardowns.end()) {
(*itTeardown)();
++itTeardown;
}
this->_effectTeardowns.clear();
// Update the values
this->previous = this->_realValue;
this->_realValue = val;
// Notify the effect listeners
auto itEffect = this->_effectListners.begin();
while(itEffect != this->_effectListners.end()) {
(*itEffect)();
++itEffect;
}
// Notify the teardown effect listeners
auto itWithTeardown = this->_effectListnersWithTeardown.begin();
while(itWithTeardown != this->_effectListnersWithTeardown.end()) {
auto teardown = (*itWithTeardown)();
this->_effectTeardowns.push_back(teardown);
++itWithTeardown;
}
}
public:
V _realValue;
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), previous(initial) {}
const StateProperty& operator += (const V &value) {
this->setInternal(this->_realValue + value);
return *this;
}
const bool_t operator != (const V &value) {
return value != this->_realValue;
}
const bool_t operator == (const V &value) {
return value == this->_realValue;
}
const StateProperty& operator = (const V &val) {
this->setInternal(val);
return *this;
}
StateProperty& operator++() {
this->setInternal(_realValue + 1);
return *this;
}
V operator++(int) {
V temp = _realValue;
this->setInternal(_realValue + 1);
return temp;
}
StateProperty& operator--() {
this->setInternal(_realValue - 1);
return *this;
}
V operator--(int) {
V temp = _realValue;
this->setInternal(_realValue - 1);
return temp;
}
const V operator->() const {
return this->_realValue;
}
operator V() const {
return this->_realValue;
}
/**
* Provides an alternate way to set the value, e.g. if using the equals
* operator is not possible.
*
* @param val Value to set on this property.
*/
void setValue(V val) {
this->setInternal(val);
}
/**
* Provides an alternate way to get the value, e.g. if using the equals
* operator is not possible.
*
* @return The value of this property.
*/
V getValue() {
return this->_realValue;
}
/**
* Destructor for StateProperty.
*/
~StateProperty() {}
friend class StateOwner;
};
}