using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MBT { // [RequireComponent(typeof(Blackboard))] public abstract class Variable : BlackboardVariable, Observable { // [HideInInspector] [SerializeField] protected T val = default(T); protected event ChangeListener listeners = delegate {}; // This is required to correctly compare Unity Objects as generic fields protected abstract bool ValueEquals(T val1, T val2); public void AddListener(ChangeListener listener) { listeners += listener; } public void RemoveListener(ChangeListener listener) { listeners -= listener; } public T Value { get { return val; } set { if (!ValueEquals(val, value)) { T oldValue = val; val = value; listeners.Invoke(oldValue, value); } } } protected virtual void OnValidate() { // Special case: Invoke listeners when there was change in inspector listeners.Invoke(val, val); } } public delegate void ChangeListener(T oldValue, T newValue); public interface Observable { void AddListener(ChangeListener listener); void RemoveListener(ChangeListener listener); } [System.Serializable] public class VariableReference : BaseVariableReference where T : BlackboardVariable { // Cache protected T value = null; [SerializeField] protected U constantValue = default(U); /// /// Returns observable Variable or null if it doesn't exists on blackboard. /// public T GetVariable() { if (value != null) { return value; } if (blackboard == null || string.IsNullOrEmpty(key)) { return null; } value = blackboard.GetVariable(key); #if UNITY_EDITOR if (value == null) { Debug.LogWarningFormat(blackboard, "Variable '{0}' does not exists on blackboard.", key); } #endif return value; } public U GetConstant() { return constantValue; } } public enum VarRefMode { EnableConstant, DisableConstant } [System.Serializable] public abstract class BaseVariableReference { [SerializeField] protected bool useConstant = false; // Additional editor feature to lock switch [SerializeField] protected VarRefMode mode = VarRefMode.EnableConstant; public Blackboard blackboard; public string key; public virtual bool isConstant { get { return useConstant; } } /// /// Returns true when constant value is valid /// /// protected virtual bool isConstantValid { get { return true; } } /// /// Returns true when variable setup is invalid /// public bool isInvalid { get { return (isConstant)? !isConstantValid : blackboard == null || string.IsNullOrEmpty(key); } } protected void SetMode(VarRefMode mode) { this.mode = mode; useConstant = (mode == VarRefMode.DisableConstant)? false : useConstant; } } }