using System;
using UnityEngine;
namespace UnityAtoms
{
///
/// An Event Reference lets you define an event in your script where you then from the inspector can choose if it's going to use the Event from an Event, Event Instancer, Variable or a Variable Instancer.
///
/// The type of the event.
/// Variable of type `T`.
/// Event of type `T`.
/// Variable Instancer of type `T`.
/// Event Instancer of type `T`.
public abstract class AtomEventReference : AtomEventReferenceBase, IGetEvent, ISetEvent
where V : IGetEvent, ISetEvent
where E : AtomEvent
where VI : IGetEvent, ISetEvent
where EI : AtomEventInstancer
{
///
/// Get the event for the Event Reference.
///
/// The event of type `E`.
public E Event
{
get
{
switch (_usage)
{
case (AtomEventReferenceBase.Usage.Variable): return _variable.GetEvent();
case (AtomEventReferenceBase.Usage.VariableInstancer): return _variableInstancer.GetEvent();
case (AtomEventReferenceBase.Usage.EventInstancer): return _eventInstancer.Event;
case (AtomEventReferenceBase.Usage.Event):
default:
return _event;
}
}
set
{
switch (_usage)
{
case (AtomEventReferenceBase.Usage.Variable):
{
_variable.SetEvent(value);
break;
}
case (AtomEventReferenceBase.Usage.VariableInstancer):
{
_variableInstancer.SetEvent(value);
break;
}
case (AtomEventReferenceBase.Usage.Event):
{
_event = value;
break;
}
default:
throw new NotSupportedException($"Event not reassignable for usage {_usage}.");
}
}
}
///
/// Event used if `Usage` is set to `Event`.
///
[SerializeField]
private E _event;
///
/// EventInstancer used if `Usage` is set to `EventInstancer`.
///
[SerializeField]
private EI _eventInstancer;
///
/// Variable used if `Usage` is set to `Variable`.
///
[SerializeField]
private V _variable;
///
/// Variable Instancer used if `Usage` is set to `VariableInstancer`.
///
[SerializeField]
private VI _variableInstancer;
protected AtomEventReference()
{
_usage = AtomEventReferenceBase.Usage.Event;
}
public static implicit operator E(AtomEventReference reference)
{
return reference.Event;
}
///
/// Get event by type. Don't use directly! Used only so that we don't need two implementations of Event Instancer and Listeners (one for `T` and one for `IPair<T>`)
///
///
/// The event.
public EO GetEvent() where EO : AtomEventBase
{
if (typeof(EO) == typeof(E))
return (Event as EO);
throw new Exception($"Event type {typeof(EO)} not supported! Use {typeof(E)}.");
}
///
/// Set event by type. Don't use directly! Used only so that we don't need two implementations of Event Instancer and Listeners (one for `T` and one for `IPair<T>`)
///
/// The new event value.
///
public void SetEvent(EO e) where EO : AtomEventBase
{
if (typeof(EO) == typeof(E))
{
Event = (e as E);
return;
}
throw new Exception($"Event type {typeof(EO)} not supported! Use {typeof(E)}.");
}
}
}