More work on State System
This commit is contained in:
		@@ -8,10 +8,44 @@
 | 
			
		||||
#include "StateProperty.hpp"
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
    private:
 | 
			
		||||
      std::vector<IStateEvent*> eventsSubscribed;
 | 
			
		||||
 | 
			
		||||
      std::vector<IStateOwnerEventLegacy*> eventLegacyBridge;
 | 
			
		||||
  
 | 
			
		||||
    public:
 | 
			
		||||
      /**
 | 
			
		||||
       * Called by the state event when it is disposing (before the StateOwner
 | 
			
		||||
       * 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
 | 
			
		||||
       * when the value is changed.
 | 
			
		||||
@@ -126,15 +177,55 @@ namespace Dawn {
 | 
			
		||||
 | 
			
		||||
        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() {
 | 
			
		||||
        auto it = this->eventsSubscribed.begin();
 | 
			
		||||
        while(it != this->eventsSubscribed.end()) {
 | 
			
		||||
          (*it)->_stateOwnerDestroyed(this);
 | 
			
		||||
          ++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
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "assert/assert.hpp"
 | 
			
		||||
#include "event/Event.hpp"
 | 
			
		||||
#include "StateInterfaces.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  /** Forwarders / Fake Virtuals for other methods. */
 | 
			
		||||
  template<typename...A>
 | 
			
		||||
  class StateEvent;
 | 
			
		||||
  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 {
 | 
			
		||||
  class StateEvent : public IStateEvent {
 | 
			
		||||
    protected:
 | 
			
		||||
      uint32_t stateEventId = 0;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 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
 | 
			
		||||
@@ -36,17 +19,6 @@ namespace Dawn {
 | 
			
		||||
       * 
 | 
			
		||||
       * @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 {
 | 
			
		||||
        auto it = this->_eventListeners.begin();
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "assert/assert.hpp"
 | 
			
		||||
#include "StateInterfaces.hpp"
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
  class StateProperty : public IStateProperty {
 | 
			
		||||
    private:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user