2024-06-23 19:12:22 +01:00

139 lines
3.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MBT
{
// [RequireComponent(typeof(Blackboard))]
public abstract class Variable<T> : BlackboardVariable, Observable<T>
{
// [HideInInspector]
[SerializeField]
protected T val = default(T);
protected event ChangeListener<T> 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<T> listener)
{
listeners += listener;
}
public void RemoveListener(ChangeListener<T> 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>(T oldValue, T newValue);
public interface Observable<T>
{
void AddListener(ChangeListener<T> listener);
void RemoveListener(ChangeListener<T> listener);
}
[System.Serializable]
public class VariableReference<T, U> : BaseVariableReference where T : BlackboardVariable
{
// Cache
protected T value = null;
[SerializeField]
protected U constantValue = default(U);
/// <summary>
/// Returns observable Variable or null if it doesn't exists on blackboard.
/// </summary>
public T GetVariable()
{
if (value != null) {
return value;
}
if (blackboard == null || string.IsNullOrEmpty(key)) {
return null;
}
value = blackboard.GetVariable<T>(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; }
}
/// <summary>
/// Returns true when constant value is valid
/// </summary>
/// <value></value>
protected virtual bool isConstantValid
{
get
{
return true;
}
}
/// <summary>
/// Returns true when variable setup is invalid
/// </summary>
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;
}
}
}