Added teardown styled use effect

This commit is contained in:
2023-03-01 06:41:14 -08:00
parent 008cf282dd
commit dfcc14f2a7
3 changed files with 51 additions and 3 deletions

View File

@ -36,12 +36,14 @@ namespace Dawn {
* *
* @param fn The callback to be invoked when the state value changes. * @param fn The callback to be invoked when the state value changes.
* @param property Property to listen for affect changees to. * @param property Property to listen for affect changees to.
* @return Returns callback that invokes the provided FN immediately.
*/ */
void useEffect( std::function<void()> useEffect(
const std::function<void()> &fn, const std::function<void()> &fn,
IStateProperty &property IStateProperty &property
) { ) {
property._effectListners.push_back(fn); property._effectListners.push_back(fn);
return fn;
} }
/** /**
@ -50,8 +52,9 @@ namespace Dawn {
* *
* @param fn The callback to be invoked when the state value changes. * @param fn The callback to be invoked when the state value changes.
* @param property Vector list of properties to listen for changes to. * @param property Vector list of properties to listen for changes to.
* @return Returns callback that invokes the provided FN immediately.
*/ */
void useEffect( std::function<void()> useEffect(
const std::function<void()> &fn, const std::function<void()> &fn,
std::vector<IStateProperty*> props std::vector<IStateProperty*> props
) { ) {
@ -60,6 +63,31 @@ namespace Dawn {
(*itProp)->_effectListners.push_back(fn); (*itProp)->_effectListners.push_back(fn);
++itProp; ++itProp;
} }
return fn;
}
/**
* Listen for changes to a state property and invoke the provided callback
* also, when state is changed this will run the returned teardown
* callback.
*
* @param fn The callback to be invoked when the state value changes.
* @param property Vector list of properties to listen for changes to.
* @return Returns callback that invokes the provided FN immediately.
*/
std::function<void()> useEffectWithTeardown(
const std::function<std::function<void()>()> &fn,
IStateProperty &property
) {
property._effectListnersWithTeardown.push_back(fn);
return std::bind([&](
std::function<std::function<void()>()> &callback,
IStateProperty *prop
) {
auto teardown = callback();
prop->_effectTeardowns.push_back(teardown);
}, fn, &property);
} }
/** /**
@ -74,7 +102,6 @@ namespace Dawn {
*/ */
template<typename F, typename... A> template<typename F, typename... A>
std::function<void()> useEvent(F fn, StateEvent<A...> &event) { std::function<void()> useEvent(F fn, StateEvent<A...> &event) {
// Create a listener structure // Create a listener structure
struct StateEventListener<A...> listener; struct StateEventListener<A...> listener;
listener.listener = fn; listener.listener = fn;
@ -99,6 +126,8 @@ namespace Dawn {
return listener.unsub; return listener.unsub;
} }
virtual ~StateOwner() { virtual ~StateOwner() {
auto it = this->eventsSubscribed.begin(); auto it = this->eventsSubscribed.begin();

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "assert/assert.hpp" #include "assert/assert.hpp"
#include "event/Event.hpp"
namespace Dawn { namespace Dawn {
/** Forwarders / Fake Virtuals for other methods. */ /** Forwarders / Fake Virtuals for other methods. */

View File

@ -10,6 +10,8 @@ namespace Dawn {
class IStateProperty { class IStateProperty {
public: public:
std::vector<std::function<void()>> _effectListners; 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>
@ -26,12 +28,28 @@ namespace Dawn {
this->previous = this->_realValue; this->previous = this->_realValue;
this->_realValue = val; this->_realValue = val;
// Run the teardowns
auto itTeardown = this->_effectTeardowns.begin();
while(itTeardown != this->_effectTeardowns.end()) {
(*itTeardown)();
++itTeardown;
}
this->_effectTeardowns.clear();
// Notify the effect listeners // Notify the effect listeners
auto itEffect = this->_effectListners.begin(); auto itEffect = this->_effectListners.begin();
while(itEffect != this->_effectListners.end()) { while(itEffect != this->_effectListners.end()) {
(*itEffect)(); (*itEffect)();
++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: public: