From 02bd90f5acc9b5093bed030274817e5aa2686876 Mon Sep 17 00:00:00 2001 From: Oliver Biwer Date: Wed, 17 Jul 2024 23:35:36 +0200 Subject: [PATCH] feat: Added Interfaces to make some generic usages easier feat: Added alternative event handlers, that allow to handle generic events --- Packages/Core/Runtime/Events/AtomEvent.cs | 42 ++++++++++++++++++- .../Core/Runtime/Variables/AtomVariable.cs | 16 ++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Packages/Core/Runtime/Events/AtomEvent.cs b/Packages/Core/Runtime/Events/AtomEvent.cs index c0fd6947..e6535a24 100644 --- a/Packages/Core/Runtime/Events/AtomEvent.cs +++ b/Packages/Core/Runtime/Events/AtomEvent.cs @@ -5,15 +5,28 @@ using System.Collections.Generic; using UnityEditor; #endif using UnityEngine; +using UnityEngine.UIElements; namespace UnityAtoms { + + public interface IAtomEventHandler + { + public void Handle(T t); + } + + public interface IAtomEvent + { + public void Register(IAtomEventHandler handler); + public void Unregister(IAtomEventHandler handler); + } + /// /// Generic base class for Events. Inherits from `AtomEventBase`. /// /// The type for this Event. [EditorIcon("atom-icon-cherry")] - public class AtomEvent : AtomEventBase + public class AtomEvent : AtomEventBase, IAtomEvent { public T InspectorRaiseValue { get => _inspectorRaiseValue; } @@ -28,6 +41,8 @@ namespace UnityAtoms [SerializeField] protected event Action _onEvent; + [SerializeField] protected List _handlers = new(); + /// /// The event replays the specified number of old values to new subscribers. Works like a ReplaySubject in Rx. /// @@ -105,6 +120,7 @@ namespace UnityAtoms #endif base.Raise(); _onEvent?.Invoke(item); + foreach (var handler in _handlers) handler.Handle(item); AddToReplayBuffer(item); } @@ -124,6 +140,8 @@ namespace UnityAtoms ReplayBufferToSubscriber(action); } + public void Register(IAtomEventHandler handler) => _handlers.Add(handler); + /// /// Unregister handler that was registered using the `Register` method. /// @@ -132,6 +150,8 @@ namespace UnityAtoms { _onEvent -= action; } + + public void Unregister(IAtomEventHandler handler) => _handlers.Remove(handler); /// /// Unregister all handlers that were registered using the `Register` method. @@ -140,6 +160,7 @@ namespace UnityAtoms { base.UnregisterAll(); _onEvent = null; + _handlers.Clear(); } /// @@ -202,5 +223,24 @@ namespace UnityAtoms } } } + + private void ReplayBufferToSubscriber(IAtomEventHandler handler) + { + if (_replayBufferSize > 0 && _replayBuffer.Count > 0) + { + var enumerator = _replayBuffer.GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + handler.Handle(enumerator.Current); + } + } + finally + { + enumerator.Dispose(); + } + } + } } } diff --git a/Packages/Core/Runtime/Variables/AtomVariable.cs b/Packages/Core/Runtime/Variables/AtomVariable.cs index 20d593bc..d2199dae 100644 --- a/Packages/Core/Runtime/Variables/AtomVariable.cs +++ b/Packages/Core/Runtime/Variables/AtomVariable.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using UnityEngine; using UnityEngine.Serialization; #if UNITY_EDITOR @@ -8,6 +9,17 @@ using UnityEditor; namespace UnityAtoms { + + public interface IAtomVariable + { + public IAtomEvent GetChangedEvent(); + } + + public interface IAtomVariable : IAtomVariable + { + public T Value { get; set; } + } + /// /// Generic base class for Variables. Inherits from `AtomBaseVariable<T>`. /// @@ -17,7 +29,7 @@ namespace UnityAtoms /// Event of type `AtomEvent<T, T>`. /// Function of type `FunctionEvent<T, T>`. [EditorIcon("atom-icon-lush")] - public abstract class AtomVariable : AtomBaseVariable, IGetEvent, ISetEvent, IGetOrCreateEvent + public abstract class AtomVariable : AtomBaseVariable, IAtomVariable, IGetEvent, ISetEvent, IGetOrCreateEvent where P : struct, IPair where E1 : AtomEvent where E2 : AtomEvent

@@ -60,6 +72,8 @@ namespace UnityAtoms } } + public IAtomEvent GetChangedEvent() => Changed; + ///

/// Changed with history Event triggered when the Variable value gets changed. ///