Added an explicit GetOrCreateEvent method

This commit is contained in:
Adam Ramberg 2020-12-25 23:50:22 +01:00
parent 9c5c1821c3
commit f975859a54
6 changed files with 88 additions and 54 deletions

View File

@ -30,7 +30,6 @@ namespace UnityAtoms.Editor
public override void OnInspectorGUI()
{
Rect buttonRect = new Rect();
var rect = GUILayoutUtility.GetRect(new GUIContent("Show"), EditorStyles.toolbarButton);

View File

@ -12,9 +12,9 @@ namespace UnityAtoms
/// <typeparam name="VI">Variable Instancer of type `T`.</typeparam>
/// <typeparam name="EI">Event Instancer of type `T`.</typeparam>
public abstract class AtomEventReference<T, V, E, VI, EI> : AtomBaseEventReference<T, E, EI>, IGetEvent, ISetEvent
where V : IGetEvent, ISetEvent
where V : IGetOrCreateEvent, ISetEvent
where E : AtomEvent<T>
where VI : IGetEvent, ISetEvent
where VI : IGetOrCreateEvent, ISetEvent
where EI : AtomEventInstancer<T, E>
{
/// <summary>
@ -27,8 +27,8 @@ namespace UnityAtoms
{
switch (_usage)
{
case (AtomEventReferenceUsage.VARIABLE): return _variable.GetEvent<E>();
case (AtomEventReferenceUsage.VARIABLE_INSTANCER): return _variableInstancer.GetEvent<E>();
case (AtomEventReferenceUsage.VARIABLE): return _variable.GetOrCreateEvent<E>();
case (AtomEventReferenceUsage.VARIABLE_INSTANCER): return _variableInstancer.GetOrCreateEvent<E>();
case (AtomEventReferenceUsage.EVENT_INSTANCER): return _eventInstancer.Event;
case (AtomEventReferenceUsage.EVENT):
default:

View File

@ -0,0 +1,10 @@
namespace UnityAtoms
{
/// <summary>
/// Interface for getting or creating an event.
/// </summary>
public interface IGetOrCreateEvent
{
E GetOrCreateEvent<E>() where E : AtomEventBase;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad6eca56e172547c688d3a2d11dc23b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -17,7 +17,7 @@ namespace UnityAtoms
/// <typeparam name="F">Function of type T => T</typeparam>
[EditorIcon("atom-icon-hotpink")]
[DefaultExecutionOrder(Runtime.ExecutionOrder.VARIABLE_INSTANCER)]
public abstract class AtomVariableInstancer<V, P, T, E1, E2, F> : AtomBaseVariableInstancer<T, V>, IGetEvent, ISetEvent
public abstract class AtomVariableInstancer<V, P, T, E1, E2, F> : AtomBaseVariableInstancer<T, V>, IGetEvent, ISetEvent, IGetOrCreateEvent
where V : AtomVariable<T, P, E1, E2, F>
where P : struct, IPair<T>
where E1 : AtomEvent<T>
@ -29,12 +29,12 @@ namespace UnityAtoms
/// </summary>
protected override void ImplSpecificSetup()
{
if (Base.HasChangedEvent)
if (Base.Changed != null)
{
_inMemoryCopy.Changed = Instantiate(Base.Changed);
}
if (Base.HasChangedWithHistoryEvent)
if (Base.ChangedWithHistory != null)
{
_inMemoryCopy.ChangedWithHistory = Instantiate(Base.ChangedWithHistory);
}
@ -51,10 +51,7 @@ namespace UnityAtoms
/// <returns>The event.</returns>
public E GetEvent<E>() where E : AtomEventBase
{
if (typeof(E) == typeof(E1) || typeof(E) == typeof(E2))
return _inMemoryCopy.GetEvent<E>();
throw new Exception($"Event type {typeof(E)} not supported! Use {typeof(E1)} or {typeof(E2)}.");
return _inMemoryCopy.GetEvent<E>();
}
/// <summary>
@ -64,18 +61,17 @@ namespace UnityAtoms
/// <typeparam name="E"></typeparam>
public void SetEvent<E>(E e) where E : AtomEventBase
{
if (typeof(E) == typeof(E1))
{
_inMemoryCopy.Changed = (e as E1);
return;
}
if (typeof(E) == typeof(E2))
{
_inMemoryCopy.ChangedWithHistory = (e as E2);
return;
}
_inMemoryCopy.SetEvent<E>(e);
}
throw new Exception($"Event type {typeof(E)} not supported! Use {typeof(E1)} or {typeof(E2)}.");
/// <summary>
/// Get event by type. Creates it if it doesn't exist.
/// </summary>
/// <typeparam name="E"></typeparam>
/// <returns>The event.</returns>
public E GetOrCreateEvent<E>() where E : AtomEventBase
{
return _inMemoryCopy.GetOrCreateEvent<E>();
}
}
}

View File

@ -17,7 +17,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
public abstract class AtomVariable<T, P, E1, E2, F> : AtomBaseVariable<T>, IGetEvent, ISetEvent, IGetOrCreateEvent
where P : struct, IPair<T>
where E1 : AtomEvent<T>
where E2 : AtomEvent<P>
@ -52,12 +52,6 @@ namespace UnityAtoms
{
get
{
if (_changed == null)
{
_changed = ScriptableObject.CreateInstance<E1>();
_changed.name = $"{(String.IsNullOrWhiteSpace(name) ? "" : $"{name}_")}ChangedEvent_Runtime_{typeof(E1)}";
_changedInstantiatedAtRuntime = true;
}
return _changed;
}
set
@ -66,11 +60,6 @@ namespace UnityAtoms
}
}
/// <summary>
/// True if Variable has a Changed Event
/// </summary>
public bool HasChangedEvent { get => _changed != null; }
/// <summary>
/// Changed with history Event triggered when the Variable value gets changed.
/// </summary>
@ -82,12 +71,6 @@ namespace UnityAtoms
{
get
{
if (_changedWithHistory == null)
{
_changedWithHistory = ScriptableObject.CreateInstance<E2>();
_changedWithHistory.name = $"{(String.IsNullOrWhiteSpace(name) ? "" : $"{name}_")}_ChangedWithHistoryEvent_Runtime_{typeof(E2)}";
_changedWithHistoryInstantiatedAtRuntime = true;
}
return _changedWithHistory;
}
set
@ -96,11 +79,6 @@ namespace UnityAtoms
}
}
/// <summary>
/// True if Variable has a Changed with history Event
/// </summary>
public bool HasChangedWithHistoryEvent { get => _changedWithHistory != null; }
/// <summary>
/// Whether Changed Event should be triggered on OnEnable or not
/// </summary>
@ -199,11 +177,11 @@ namespace UnityAtoms
/// </summary>
public void TriggerInitialEvents()
{
if (HasChangedEvent && _triggerChangedOnOnEnable)
if (Changed != null && _triggerChangedOnOnEnable)
{
Changed.Raise(Value);
}
if (HasChangedWithHistoryEvent != null && _triggerChangedWithHistoryOnOnEnable)
if (ChangedWithHistory != null && _triggerChangedWithHistoryOnOnEnable)
{
var pair = default(P);
pair.Item1 = _value;
@ -269,8 +247,8 @@ namespace UnityAtoms
if (triggerEvents)
{
if (HasChangedEvent) { Changed.Raise(_value); }
if (HasChangedWithHistoryEvent)
if (Changed != null) { Changed.Raise(_value); }
if (ChangedWithHistory != null)
{
// NOTE: Doing new P() here, even though it is cleaner, generates garbage.
var pair = default(P);
@ -355,10 +333,14 @@ namespace UnityAtoms
/// </returns>
public E GetEvent<E>() where E : AtomEventBase
{
if (_changed is E evt1)
return evt1;
if (_changedWithHistory is E evt2)
return evt2;
if (typeof(E) == typeof(E1))
{
return Changed as E;
}
if (typeof(E) == typeof(E2))
{
return ChangedWithHistory as E;
}
throw new NotSupportedException($"Event type {typeof(E)} not supported! Use {typeof(E1)} or {typeof(E2)}.");
}
@ -383,5 +365,41 @@ namespace UnityAtoms
throw new Exception($"Event type {typeof(E)} not supported! Use {typeof(E1)} or {typeof(E2)}.");
}
/// <summary>
/// Get event by type (allowing inheritance). Creates an event if the type is supported for this Variable, but the Event itself is `null`.
/// </summary>
/// <typeparam name="E"></typeparam>
/// <returns>Changed - If Changed (or ChangedWithHistory) are of type E
/// ChangedWithHistory - If not Changed but ChangedWithHistory is of type E
/// <exception cref="NotSupportedException">if none of the events are of type E</exception>
/// </returns>
public E GetOrCreateEvent<E>() where E : AtomEventBase
{
if (typeof(E) == typeof(E1))
{
if (Changed == null)
{
Changed = ScriptableObject.CreateInstance<E1>();
Changed.name = $"{(String.IsNullOrWhiteSpace(name) ? "" : $"{name}_")}ChangedEvent_Runtime_{typeof(E1)}";
_changedInstantiatedAtRuntime = true;
}
return Changed as E;
}
if (typeof(E) == typeof(E2))
{
if (ChangedWithHistory == null)
{
ChangedWithHistory = ScriptableObject.CreateInstance<E2>();
ChangedWithHistory.name = $"{(String.IsNullOrWhiteSpace(name) ? "" : $"{name}_")}_ChangedWithHistoryEvent_Runtime_{typeof(E2)}";
_changedWithHistoryInstantiatedAtRuntime = true;
}
return ChangedWithHistory as E;
}
throw new NotSupportedException($"Event type {typeof(E)} not supported! Use {typeof(E1)} or {typeof(E2)}.");
}
}
}