using UnityEngine; using UnityEngine.Events; namespace ScriptableObjectArchitecture { public abstract class BaseVariable : GameEventBase { public abstract bool IsClamped { get; } public abstract bool Clampable { get; } public abstract bool ReadOnly { get; } public abstract System.Type Type { get; } public abstract object BaseValue { get; set; } } public abstract class BaseVariable : BaseVariable { public virtual T Value { get { return _value; } set { _value = SetValue(value); Raise(); } } public virtual T MinClampValue { get { if(Clampable) { return _minClampedValue; } else { return default(T); } } } public virtual T MaxClampValue { get { if(Clampable) { return _maxClampedValue; } else { return default(T); } } } public override bool Clampable { get { return false; } } public override bool ReadOnly { get { return _readOnly; } } public override bool IsClamped { get { return _isClamped; } } public override System.Type Type { get { return typeof(T); } } public override object BaseValue { get { return _value; } set { _value = SetValue((T)value); Raise(); } } [SerializeField] protected T _value = default(T); [SerializeField] private bool _readOnly = false; [SerializeField] private bool _raiseWarning = true; [SerializeField] protected bool _isClamped = false; [SerializeField] protected T _minClampedValue = default(T); [SerializeField] protected T _maxClampedValue = default(T); public virtual T SetValue(BaseVariable value) { return SetValue(value.Value); } public virtual T SetValue(T value) { if (_readOnly) { RaiseReadonlyWarning(); return _value; } else if(Clampable && IsClamped) { return ClampValue(value); } return value; } protected virtual T ClampValue(T value) { return value; } private void RaiseReadonlyWarning() { if (!_readOnly || !_raiseWarning) return; Debug.LogWarning("Tried to set value on " + name + ", but value is readonly!", this); } public override string ToString() { return _value == null ? "null" : _value.ToString(); } public static implicit operator T(BaseVariable variable) { return variable.Value; } } public abstract class BaseVariable : BaseVariable where TEvent : UnityEvent { [SerializeField] private TEvent _event = default; public override T SetValue(T value) { T oldValue = _value; T newValue = base.SetValue(value); if (!newValue.Equals(oldValue)) _event.Invoke(newValue); return newValue; } public void AddListener(UnityAction callback) { _event.AddListener(callback); } public void RemoveListener(UnityAction callback) { _event.RemoveListener(callback); } public override void RemoveAll() { base.RemoveAll(); _event.RemoveAllListeners(); } } }