using System; using UnityEngine; namespace UnityAtoms { /// /// A Reference lets you define a variable in your script where you then from the inspector can choose if it's going to be taking the value from a Constant, Variable, Value or a Variable Instancer. /// /// The type of the variable. /// IPair of type `T`. /// Constant of type `T`. /// Variable of type `T`. /// Event of type `T`. /// Event of type `IPair<T>`. /// Function of type `T => T`. /// Variable Instancer of type `T`. public abstract class AtomReference : AtomBaseReference, IEquatable> where P : struct, IPair where C : AtomBaseVariable where V : AtomVariable where E1 : AtomEvent where E2 : AtomEvent

where F : AtomFunction where VI : AtomVariableInstancer { ///

/// Get or set the value for the Reference. /// /// The value of type `T`. public T Value { get { switch (_usage) { case (AtomReferenceUsage.CONSTANT): return _constant == null ? default(T) : _constant.Value; case (AtomReferenceUsage.VARIABLE): return _variable == null ? default(T) : _variable.Value; case (AtomReferenceUsage.VARIABLE_INSTANCER): return _variableInstancer == null ? default(T) : _variableInstancer.Value; case (AtomReferenceUsage.VALUE): default: return _value; } } set { switch (_usage) { case (AtomReferenceUsage.VARIABLE): { _variable.Value = value; break; } case (AtomReferenceUsage.VALUE): { _value = value; break; } case (AtomReferenceUsage.VARIABLE_INSTANCER): { _variableInstancer.Value = value; break; } case (AtomReferenceUsage.CONSTANT): default: throw new NotSupportedException("Can't reassign constant value"); } } } /// /// Value used if `Usage` is set to `Value`. /// [SerializeField] private T _value = default(T); /// /// Constant used if `Usage` is set to `Constant`. /// [SerializeField] private C _constant = default(C); /// /// Variable used if `Usage` is set to `Variable`. /// [SerializeField] private V _variable = default(V); /// /// Variable Instancer used if `Usage` is set to `VariableInstancer`. /// [SerializeField] private VI _variableInstancer = default(VI); protected AtomReference() { _usage = AtomReferenceUsage.VALUE; } protected AtomReference(T value) : this() { _usage = AtomReferenceUsage.VALUE; _value = value; } public static implicit operator T(AtomReference reference) { return reference.Value; } protected abstract bool ValueEquals(T other); public bool Equals(AtomReference other) { if (other == null) return false; return ValueEquals(other.Value); } public override int GetHashCode() { return Value == null ? 0 : Value.GetHashCode(); } } }