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. /// Constant of type T. /// Variable of type T. /// Event of type T. /// Event x 2 of type T. /// Function of type T => T. /// Variable Instancer of type T. public abstract class AtomReference : AtomReferenceBase, IEquatable> 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 (AtomReferenceBase.Usage.Constant): return _constant == null ? default(T) : _constant.Value; case (AtomReferenceBase.Usage.Variable): return _variable == null ? default(T) : _variable.Value; case (AtomReferenceBase.Usage.VariableInstancer): return _variableInstancer == null ? default(T) : _variableInstancer.Value; case (AtomReferenceBase.Usage.Value): default: return _value; } } set { switch (_usage) { case (AtomReferenceBase.Usage.Variable): { _variable.Value = value; break; } case (AtomReferenceBase.Usage.Value): { _value = value; break; } case (AtomReferenceBase.Usage.VariableInstancer): { _variableInstancer.Value = value; break; } case (AtomReferenceBase.Usage.Constant): default: throw new NotSupportedException("Can't reassign constant value"); } } } /// /// Value used if `Usage` is set to `Value`. /// [SerializeField] private T _value; /// /// Constant used if `Usage` is set to `Constant`. /// [SerializeField] private C _constant; /// /// 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 AtomReference() { _usage = AtomReferenceBase.Usage.Value; } protected AtomReference(T value) : this() { _usage = AtomReferenceBase.Usage.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(); } } }