feat: Added Interfaces to make some generic usages easier

feat: Added alternative event handlers, that allow to handle generic events
This commit is contained in:
Oliver Biwer 2024-07-17 23:35:36 +02:00
parent 2e11570e74
commit 02bd90f5ac
2 changed files with 56 additions and 2 deletions

View File

@ -5,15 +5,28 @@ using System.Collections.Generic;
using UnityEditor; using UnityEditor;
#endif #endif
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
namespace UnityAtoms namespace UnityAtoms
{ {
public interface IAtomEventHandler
{
public void Handle<T>(T t);
}
public interface IAtomEvent
{
public void Register(IAtomEventHandler handler);
public void Unregister(IAtomEventHandler handler);
}
/// <summary> /// <summary>
/// Generic base class for Events. Inherits from `AtomEventBase`. /// Generic base class for Events. Inherits from `AtomEventBase`.
/// </summary> /// </summary>
/// <typeparam name="T">The type for this Event.</typeparam> /// <typeparam name="T">The type for this Event.</typeparam>
[EditorIcon("atom-icon-cherry")] [EditorIcon("atom-icon-cherry")]
public class AtomEvent<T> : AtomEventBase public class AtomEvent<T> : AtomEventBase, IAtomEvent
{ {
public T InspectorRaiseValue { get => _inspectorRaiseValue; } public T InspectorRaiseValue { get => _inspectorRaiseValue; }
@ -28,6 +41,8 @@ namespace UnityAtoms
[SerializeField] [SerializeField]
protected event Action<T> _onEvent; protected event Action<T> _onEvent;
[SerializeField] protected List<IAtomEventHandler> _handlers = new();
/// <summary> /// <summary>
/// The event replays the specified number of old values to new subscribers. Works like a ReplaySubject in Rx. /// The event replays the specified number of old values to new subscribers. Works like a ReplaySubject in Rx.
/// </summary> /// </summary>
@ -105,6 +120,7 @@ namespace UnityAtoms
#endif #endif
base.Raise(); base.Raise();
_onEvent?.Invoke(item); _onEvent?.Invoke(item);
foreach (var handler in _handlers) handler.Handle(item);
AddToReplayBuffer(item); AddToReplayBuffer(item);
} }
@ -124,6 +140,8 @@ namespace UnityAtoms
ReplayBufferToSubscriber(action); ReplayBufferToSubscriber(action);
} }
public void Register(IAtomEventHandler handler) => _handlers.Add(handler);
/// <summary> /// <summary>
/// Unregister handler that was registered using the `Register` method. /// Unregister handler that was registered using the `Register` method.
/// </summary> /// </summary>
@ -132,6 +150,8 @@ namespace UnityAtoms
{ {
_onEvent -= action; _onEvent -= action;
} }
public void Unregister(IAtomEventHandler handler) => _handlers.Remove(handler);
/// <summary> /// <summary>
/// Unregister all handlers that were registered using the `Register` method. /// Unregister all handlers that were registered using the `Register` method.
@ -140,6 +160,7 @@ namespace UnityAtoms
{ {
base.UnregisterAll(); base.UnregisterAll();
_onEvent = null; _onEvent = null;
_handlers.Clear();
} }
/// <summary> /// <summary>
@ -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();
}
}
}
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
#if UNITY_EDITOR #if UNITY_EDITOR
@ -8,6 +9,17 @@ using UnityEditor;
namespace UnityAtoms namespace UnityAtoms
{ {
public interface IAtomVariable
{
public IAtomEvent GetChangedEvent();
}
public interface IAtomVariable<T> : IAtomVariable
{
public T Value { get; set; }
}
/// <summary> /// <summary>
/// Generic base class for Variables. Inherits from `AtomBaseVariable&lt;T&gt;`. /// Generic base class for Variables. Inherits from `AtomBaseVariable&lt;T&gt;`.
/// </summary> /// </summary>
@ -17,7 +29,7 @@ namespace UnityAtoms
/// <typeparam name="E2">Event of type `AtomEvent&lt;T, T&gt;`.</typeparam> /// <typeparam name="E2">Event of type `AtomEvent&lt;T, T&gt;`.</typeparam>
/// <typeparam name="F">Function of type `FunctionEvent&lt;T, T&gt;`.</typeparam> /// <typeparam name="F">Function of type `FunctionEvent&lt;T, T&gt;`.</typeparam>
[EditorIcon("atom-icon-lush")] [EditorIcon("atom-icon-lush")]
public abstract class AtomVariable<T, P, E1, E2, F> : AtomBaseVariable<T>, IGetEvent, ISetEvent, IGetOrCreateEvent public abstract class AtomVariable<T, P, E1, E2, F> : AtomBaseVariable<T>, IAtomVariable<T>, IGetEvent, ISetEvent, IGetOrCreateEvent
where P : struct, IPair<T> where P : struct, IPair<T>
where E1 : AtomEvent<T> where E1 : AtomEvent<T>
where E2 : AtomEvent<P> where E2 : AtomEvent<P>
@ -60,6 +72,8 @@ namespace UnityAtoms
} }
} }
public IAtomEvent GetChangedEvent() => Changed;
/// <summary> /// <summary>
/// Changed with history Event triggered when the Variable value gets changed. /// Changed with history Event triggered when the Variable value gets changed.
/// </summary> /// </summary>