First Commit
This commit is contained in:
314
Assets/BaseVariableReference.cs
Normal file
314
Assets/BaseVariableReference.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace RogueUtils.Data
|
||||
{
|
||||
public abstract class BaseVariableReference<TVariable, TValue> : SubBaseVariableReference where TVariable : BaseVariable<TValue>
|
||||
{
|
||||
//
|
||||
[Multiline]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("description")]
|
||||
public string m_Description = "";
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected TVariable m_Variable;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//
|
||||
// This is what appear in the inspector as the variable.
|
||||
// It is separate so that Inspector changes can go through the this.Value = new variable instance
|
||||
// code path.
|
||||
//
|
||||
//[ShowInInspector]
|
||||
//[OnValueChanged("BaseHandleEditorVariableChange")]
|
||||
protected TVariable m_InspectorVariable;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The reason for the m_ZeroOnExitPlayMode is that it is an Unity Editor only feature and
|
||||
/// resets the Variable value so that Git does not see a bunch of changes to runtime
|
||||
/// ScriptableObject Variables
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
protected bool m_DefaultOnExitPlayMode = false;
|
||||
|
||||
|
||||
private event EventHandler InternalOnVariableChange;
|
||||
protected event EventHandler<BaseVariable<TValue>.OnChangeEventArgs> InternalOnReferencedValueChange;
|
||||
protected event EventHandler<BaseVariable<TValue>.OnChangeEventArgs> InternalOnValueChange;
|
||||
|
||||
public event EventHandler OnVariableChange
|
||||
{
|
||||
// Not thread safe.
|
||||
// Will add tracking of subscribers
|
||||
add
|
||||
{
|
||||
InternalOnVariableChange += value;
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
InternalOnVariableChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<BaseVariable<TValue>.OnChangeEventArgs> OnReferencedValueChange
|
||||
{
|
||||
// Not thread safe.
|
||||
// Will add tracking of subscribers
|
||||
add
|
||||
{
|
||||
InternalOnReferencedValueChange += value;
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
InternalOnReferencedValueChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<BaseVariable<TValue>.OnChangeEventArgs> OnValueChange
|
||||
{
|
||||
// Not thread safe.
|
||||
// Will add tracking of subscribers
|
||||
add
|
||||
{
|
||||
InternalOnValueChange += value;
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
InternalOnValueChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual TVariable DefaultVariable
|
||||
{
|
||||
get => default;
|
||||
}
|
||||
|
||||
public virtual TVariable Variable
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Variable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_Variable != null)
|
||||
{
|
||||
//
|
||||
// Remove the listeners from the old variable
|
||||
//
|
||||
m_Variable.OnChange -= HandleValueChange;
|
||||
}
|
||||
m_Variable = value;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
m_InspectorVariable = m_Variable;
|
||||
#endif
|
||||
|
||||
if (m_Variable != null)
|
||||
{
|
||||
m_Variable.OnChange += HandleValueChange;
|
||||
}
|
||||
|
||||
TriggerVariableListeners();
|
||||
|
||||
//
|
||||
// This is also a value change
|
||||
//
|
||||
if (m_Variable != null)
|
||||
{
|
||||
HandleValueChange(m_Variable, new BaseVariable<TValue>.OnChangeEventArgs(m_Variable.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleValueChange(m_Variable, new BaseVariable<TValue>.OnChangeEventArgs(default));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual TValue Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_Variable != null ? m_Variable.Value : default);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_Variable != null)
|
||||
{
|
||||
m_Variable.Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void HandleValueChange(object sender, BaseVariable<TValue>.OnChangeEventArgs onChangeEventArgs)
|
||||
{
|
||||
SubBaseTriggerValueListeners();
|
||||
if (m_Variable != null)
|
||||
{
|
||||
InternalOnValueChange?.Invoke(m_Variable, onChangeEventArgs);
|
||||
}
|
||||
InternalOnReferencedValueChange?.Invoke(this, onChangeEventArgs);
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.playModeStateChanged += HandlePlayModeStateChange;
|
||||
#endif
|
||||
//
|
||||
// Listen on the variable value changing.
|
||||
//
|
||||
if (m_Variable != null)
|
||||
{
|
||||
m_Variable.OnChange += HandleValueChange;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.playModeStateChanged -= HandlePlayModeStateChange;
|
||||
#endif
|
||||
//
|
||||
// Stop listening on the variable value changing.
|
||||
//
|
||||
if (m_Variable != null)
|
||||
{
|
||||
m_Variable.OnChange -= HandleValueChange;
|
||||
}
|
||||
|
||||
/*#if UNITY_EDITOR
|
||||
if (m_TestRuntimeVariable != null)
|
||||
{
|
||||
RogueUtils.Utils.NiceDestroy(m_TestRuntimeVariable);
|
||||
m_TestRuntimeVariable = null;
|
||||
}
|
||||
#endif*/
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void HandlePlayModeStateChange(PlayModeStateChange stateChange)
|
||||
{
|
||||
bool doDefaultVariable = false;
|
||||
switch (stateChange)
|
||||
{
|
||||
case PlayModeStateChange.EnteredEditMode:
|
||||
break;
|
||||
case PlayModeStateChange.ExitingEditMode:
|
||||
break;
|
||||
case PlayModeStateChange.EnteredPlayMode:
|
||||
break;
|
||||
case PlayModeStateChange.ExitingPlayMode:
|
||||
doDefaultVariable = m_DefaultOnExitPlayMode;
|
||||
break;
|
||||
}
|
||||
|
||||
if (doDefaultVariable)
|
||||
{
|
||||
var defaultVariable = DefaultVariable;
|
||||
//Undo.RecordObject(this, $"{name}: Clearing list");
|
||||
m_Variable = defaultVariable;
|
||||
//
|
||||
// Marking this dirty so Unity sees the value is its default value
|
||||
//
|
||||
EditorUtility.SetDirty(this);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public override SubBaseVariable GetVariableUntyped()
|
||||
{
|
||||
return Variable;
|
||||
}
|
||||
|
||||
public override void SetVariableUntyped(SubBaseVariable variable)
|
||||
{
|
||||
if (variable is TVariable theVariable)
|
||||
{
|
||||
Variable = theVariable;
|
||||
}
|
||||
}
|
||||
|
||||
public override T GetValue<T>()
|
||||
{
|
||||
var variable = Variable;
|
||||
if (variable != null)
|
||||
{
|
||||
var value = variable.Value;
|
||||
if (value is T theValue)
|
||||
{
|
||||
return theValue;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public override object GetValueUntyped()
|
||||
{
|
||||
var variable = Variable;
|
||||
if (variable != null)
|
||||
{
|
||||
return variable.Value;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public override void SetValueUntyped(object value)
|
||||
{
|
||||
var variable = Variable;
|
||||
if (variable != null)
|
||||
{
|
||||
if (value is TValue theValue)
|
||||
{
|
||||
variable.Value = theValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void TriggerVariableListeners()
|
||||
{
|
||||
InternalOnVariableChange?.Invoke(this, EventArgs.Empty);
|
||||
base.SubBaseTriggerVariableListeners();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Odin")]
|
||||
private void BaseHandleEditorVariableChange()
|
||||
{
|
||||
Variable = m_InspectorVariable;
|
||||
}
|
||||
|
||||
//[FoldoutGroup("Debug", Order = 200)]
|
||||
//[BoxGroup("Debug/Runtime")]
|
||||
//[ShowInInspector]
|
||||
//[ReadOnly]
|
||||
private TVariable m_TestRuntimeVariable;
|
||||
|
||||
//[BoxGroup("Debug/Runtime")]
|
||||
//[Button("Set to runtime variable instance")]
|
||||
//[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Odin")]
|
||||
private void SetToRuntimeInstance()
|
||||
{
|
||||
if (m_TestRuntimeVariable == null)
|
||||
{
|
||||
m_TestRuntimeVariable = ScriptableObject.CreateInstance<TVariable>();
|
||||
}
|
||||
|
||||
Variable = m_TestRuntimeVariable;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user