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;
#endif
using UnityEngine;
using UnityEngine.UIElements;
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>
/// Generic base class for Events. Inherits from `AtomEventBase`.
/// </summary>
/// <typeparam name="T">The type for this Event.</typeparam>
[EditorIcon("atom-icon-cherry")]
public class AtomEvent<T> : AtomEventBase
public class AtomEvent<T> : AtomEventBase, IAtomEvent
{
public T InspectorRaiseValue { get => _inspectorRaiseValue; }
@ -28,6 +41,8 @@ namespace UnityAtoms
[SerializeField]
protected event Action<T> _onEvent;
[SerializeField] protected List<IAtomEventHandler> _handlers = new();
/// <summary>
/// The event replays the specified number of old values to new subscribers. Works like a ReplaySubject in Rx.
/// </summary>
@ -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);
/// <summary>
/// Unregister handler that was registered using the `Register` method.
/// </summary>
@ -133,6 +151,8 @@ namespace UnityAtoms
_onEvent -= action;
}
public void Unregister(IAtomEventHandler handler) => _handlers.Remove(handler);
/// <summary>
/// Unregister all handlers that were registered using the `Register` method.
/// </summary>
@ -140,6 +160,7 @@ namespace UnityAtoms
{
base.UnregisterAll();
_onEvent = null;
_handlers.Clear();
}
/// <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.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<T> : IAtomVariable
{
public T Value { get; set; }
}
/// <summary>
/// Generic base class for Variables. Inherits from `AtomBaseVariable&lt;T&gt;`.
/// </summary>
@ -17,7 +29,7 @@ namespace UnityAtoms
/// <typeparam name="E2">Event of type `AtomEvent&lt;T, T&gt;`.</typeparam>
/// <typeparam name="F">Function of type `FunctionEvent&lt;T, T&gt;`.</typeparam>
[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 E1 : AtomEvent<T>
where E2 : AtomEvent<P>
@ -60,6 +72,8 @@ namespace UnityAtoms
}
}
public IAtomEvent GetChangedEvent() => Changed;
/// <summary>
/// Changed with history Event triggered when the Variable value gets changed.
/// </summary>