// 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 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; } /** * Destructor for StateProperty. */ ~StateProperty() {} friend class StateOwner; }; }