Browse Source

Refactor set variable system, add setting of GameObjects

The intent of this refactor is to reduce boilerplate code in the SetVariable.cs and
SetVariableEditor.cs files. Additionaly, the intent is to move variable specific
information from the SetVariable.cs file into the Variable.cs and the respecting
variable type files.
master
Jorge Ramirez 7 years ago
parent
commit
673b3166a3
  1. 120
      Assets/Fungus/Scripts/Commands/SetVariable.cs
  2. 23
      Assets/Fungus/Scripts/Components/Variable.cs
  3. 163
      Assets/Fungus/Scripts/Editor/SetVariableEditor.cs
  4. 2
      Assets/Fungus/Scripts/Editor/VariableEditor.cs
  5. 15
      Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs
  6. 25
      Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs
  7. 15
      Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs
  8. 25
      Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs
  9. 13
      Assets/Fungus/Scripts/VariableTypes/StringVariable.cs

120
Assets/Fungus/Scripts/Commands/SetVariable.cs

@ -2,28 +2,10 @@
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) // It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine; using UnityEngine;
using System.Collections.Generic;
namespace Fungus namespace Fungus
{ {
/// <summary>
/// Mathematical operations that can be performed on variables.
/// </summary>
public enum SetOperator
{
/// <summary> = operator. </summary>
Assign,
/// <summary> =! operator. </summary>
Negate,
/// <summary> += operator. </summary>
Add,
/// <summary> -= operator. </summary>
Subtract,
/// <summary> *= operator. </summary>
Multiply,
/// <summary> /= operator. </summary>
Divide
}
/// <summary> /// <summary>
/// Sets a Boolean, Integer, Float or String variable to a new value using a simple arithmetic operation. The value can be a constant or reference another variable of the same type. /// Sets a Boolean, Integer, Float or String variable to a new value using a simple arithmetic operation. The value can be a constant or reference another variable of the same type.
/// </summary> /// </summary>
@ -37,7 +19,8 @@ namespace Fungus
[VariableProperty(typeof(BooleanVariable), [VariableProperty(typeof(BooleanVariable),
typeof(IntegerVariable), typeof(IntegerVariable),
typeof(FloatVariable), typeof(FloatVariable),
typeof(StringVariable))] typeof(StringVariable),
typeof(GameObjectVariable))]
[SerializeField] protected Variable variable; [SerializeField] protected Variable variable;
[Tooltip("The type of math operation to be performed")] [Tooltip("The type of math operation to be performed")]
@ -55,6 +38,9 @@ namespace Fungus
[Tooltip("String value to set with")] [Tooltip("String value to set with")]
[SerializeField] protected StringDataMulti stringData; [SerializeField] protected StringDataMulti stringData;
[Tooltip("GameObject value to set with")]
[SerializeField] protected GameObjectData gameObjectData;
protected virtual void DoSetOperation() protected virtual void DoSetOperation()
{ {
if (variable == null) if (variable == null)
@ -64,90 +50,42 @@ namespace Fungus
if (variable.GetType() == typeof(BooleanVariable)) if (variable.GetType() == typeof(BooleanVariable))
{ {
BooleanVariable lhs = (variable as BooleanVariable); BooleanVariable booleanVariable = (variable as BooleanVariable);
bool rhs = booleanData.Value; booleanVariable.Apply(setOperator, booleanData.Value);
switch (setOperator)
{
default:
case SetOperator.Assign:
lhs.Value = rhs;
break;
case SetOperator.Negate:
lhs.Value = !rhs;
break;
}
} }
else if (variable.GetType() == typeof(IntegerVariable)) else if (variable.GetType() == typeof(IntegerVariable))
{ {
IntegerVariable lhs = (variable as IntegerVariable); IntegerVariable integerVariable = (variable as IntegerVariable);
int rhs = integerData.Value; integerVariable.Apply(setOperator, integerData.Value);
switch (setOperator)
{
default:
case SetOperator.Assign:
lhs.Value = rhs;
break;
case SetOperator.Add:
lhs.Value += rhs;
break;
case SetOperator.Subtract:
lhs.Value -= rhs;
break;
case SetOperator.Multiply:
lhs.Value *= rhs;
break;
case SetOperator.Divide:
lhs.Value /= rhs;
break;
}
} }
else if (variable.GetType() == typeof(FloatVariable)) else if (variable.GetType() == typeof(FloatVariable))
{ {
FloatVariable lhs = (variable as FloatVariable); FloatVariable floatVariable = (variable as FloatVariable);
float rhs = floatData.Value; floatVariable.Apply(setOperator, floatData.Value);
switch (setOperator)
{
default:
case SetOperator.Assign:
lhs.Value = rhs;
break;
case SetOperator.Add:
lhs.Value += rhs;
break;
case SetOperator.Subtract:
lhs.Value -= rhs;
break;
case SetOperator.Multiply:
lhs.Value *= rhs;
break;
case SetOperator.Divide:
lhs.Value /= rhs;
break;
}
} }
else if (variable.GetType() == typeof(StringVariable)) else if (variable.GetType() == typeof(StringVariable))
{ {
StringVariable lhs = (variable as StringVariable); StringVariable stringVariable = (variable as StringVariable);
string rhs = stringData.Value;
var flowchart = GetFlowchart(); var flowchart = GetFlowchart();
rhs = flowchart.SubstituteVariables(rhs); stringVariable.Apply(setOperator, flowchart.SubstituteVariables(stringData.Value));
}
switch (setOperator) else if (variable.GetType() == typeof(GameObjectVariable))
{ {
default: GameObjectVariable gameObjectVariable = (variable as GameObjectVariable);
case SetOperator.Assign: gameObjectVariable.Apply(setOperator, gameObjectData.Value);
lhs.Value = rhs;
break;
}
} }
} }
#region Public members #region Public members
public static readonly Dictionary<System.Type, SetOperator[]> operatorsByVariableType = new Dictionary<System.Type, SetOperator[]>() {
{ typeof(BooleanVariable), BooleanVariable.operators },
{ typeof(IntegerVariable), IntegerVariable.operators },
{ typeof(FloatVariable), FloatVariable.operators },
{ typeof(StringVariable), StringVariable.operators },
{ typeof(GameObjectVariable), GameObjectVariable.operators }
};
/// <summary> /// <summary>
/// The type of math operation to be performed. /// The type of math operation to be performed.
/// </summary> /// </summary>
@ -208,6 +146,10 @@ namespace Fungus
{ {
description += stringData.GetDescription(); description += stringData.GetDescription();
} }
else if (variable.GetType() == typeof(GameObjectVariable))
{
description += gameObjectData.GetDescription();
}
return description; return description;
} }

23
Assets/Fungus/Scripts/Components/Variable.cs

@ -25,6 +25,25 @@ namespace Fungus
GreaterThanOrEquals GreaterThanOrEquals
} }
/// <summary>
/// Mathematical operations that can be performed on variables.
/// </summary>
public enum SetOperator
{
/// <summary> = operator. </summary>
Assign,
/// <summary> =! operator. </summary>
Negate,
/// <summary> += operator. </summary>
Add,
/// <summary> -= operator. </summary>
Subtract,
/// <summary> *= operator. </summary>
Multiply,
/// <summary> /= operator. </summary>
Divide
}
/// <summary> /// <summary>
/// Scope types for Variables. /// Scope types for Variables.
/// </summary> /// </summary>
@ -176,5 +195,9 @@ namespace Fungus
// Remember the initial value so we can reset later on // Remember the initial value so we can reset later on
startValue = Value; startValue = Value;
} }
public virtual void Apply(SetOperator setOperator, T value) {
Debug.LogError("Variable doesn't have any operators.");
}
} }
} }

163
Assets/Fungus/Scripts/Editor/SetVariableEditor.cs

@ -11,12 +11,24 @@ namespace Fungus.EditorUtils
[CustomEditor (typeof(SetVariable))] [CustomEditor (typeof(SetVariable))]
public class SetVariableEditor : CommandEditor public class SetVariableEditor : CommandEditor
{ {
protected struct VariablePropertyInfo
{
public string name;
public SerializedProperty dataProp;
public VariablePropertyInfo(string name, SerializedProperty dataProp) {
this.name = name;
this.dataProp = dataProp;
}
}
protected SerializedProperty variableProp; protected SerializedProperty variableProp;
protected SerializedProperty setOperatorProp; protected SerializedProperty setOperatorProp;
protected SerializedProperty booleanDataProp;
protected SerializedProperty integerDataProp; // Variable data props
protected SerializedProperty floatDataProp; protected Dictionary<System.Type, VariablePropertyInfo> propertyInfoByVariableType;
protected SerializedProperty stringDataProp;
protected List<SerializedProperty> variableDataProps;
protected virtual void OnEnable() protected virtual void OnEnable()
{ {
@ -25,10 +37,15 @@ namespace Fungus.EditorUtils
variableProp = serializedObject.FindProperty("variable"); variableProp = serializedObject.FindProperty("variable");
setOperatorProp = serializedObject.FindProperty("setOperator"); setOperatorProp = serializedObject.FindProperty("setOperator");
booleanDataProp = serializedObject.FindProperty("booleanData");
integerDataProp = serializedObject.FindProperty("integerData"); // Get variable data props by name
floatDataProp = serializedObject.FindProperty("floatData"); propertyInfoByVariableType = new Dictionary<System.Type, VariablePropertyInfo>() {
stringDataProp = serializedObject.FindProperty("stringData"); { typeof(BooleanVariable), new VariablePropertyInfo("Boolean", serializedObject.FindProperty("booleanData")) },
{ typeof(IntegerVariable), new VariablePropertyInfo("Integer", serializedObject.FindProperty("integerData")) },
{ typeof(FloatVariable), new VariablePropertyInfo("Float", serializedObject.FindProperty("floatData")) },
{ typeof(StringVariable), new VariablePropertyInfo("String", serializedObject.FindProperty("stringData")) },
{ typeof(GameObjectVariable), new VariablePropertyInfo("GameObject", serializedObject.FindProperty("gameObjectData")) }
};
} }
public override void DrawCommandGUI() public override void DrawCommandGUI()
@ -43,6 +60,7 @@ namespace Fungus.EditorUtils
return; return;
} }
// Select Variable
EditorGUILayout.PropertyField(variableProp); EditorGUILayout.PropertyField(variableProp);
if (variableProp.objectReferenceValue == null) if (variableProp.objectReferenceValue == null)
@ -51,107 +69,62 @@ namespace Fungus.EditorUtils
return; return;
} }
// Get selected variable
Variable selectedVariable = variableProp.objectReferenceValue as Variable; Variable selectedVariable = variableProp.objectReferenceValue as Variable;
System.Type variableType = selectedVariable.GetType(); System.Type variableType = selectedVariable.GetType();
// Get operators for the variable
SetOperator[] setOperators = SetVariable.operatorsByVariableType[variableType];
// Create operator list
List<GUIContent> operatorsList = new List<GUIContent>(); List<GUIContent> operatorsList = new List<GUIContent>();
operatorsList.Add(new GUIContent("=")); foreach (var setOperator in setOperators)
if (variableType == typeof(BooleanVariable))
{
operatorsList.Add(new GUIContent("=!"));
}
else if (variableType == typeof(IntegerVariable) ||
variableType == typeof(FloatVariable))
{ {
operatorsList.Add(new GUIContent("+=")); switch (setOperator)
operatorsList.Add(new GUIContent("-=")); {
operatorsList.Add(new GUIContent("*=")); case SetOperator.Assign:
operatorsList.Add(new GUIContent("\\=")); operatorsList.Add(new GUIContent("="));
break;
case SetOperator.Negate:
operatorsList.Add(new GUIContent("=!"));
break;
case SetOperator.Add:
operatorsList.Add(new GUIContent("+="));
break;
case SetOperator.Subtract:
operatorsList.Add(new GUIContent("-="));
break;
case SetOperator.Multiply:
operatorsList.Add(new GUIContent("*="));
break;
case SetOperator.Divide:
operatorsList.Add(new GUIContent("\\="));
break;
default:
Debug.LogError("The " + setOperator.ToString() + " operator has no matching GUIContent.");
break;
}
} }
int selectedIndex = 0; // Get previously selected operator
switch (t._SetOperator) int selectedIndex = System.Array.IndexOf(setOperators, t._SetOperator);
if (selectedIndex < 0)
{ {
default: // Default to first index if the operator is not found in the available operators list
case SetOperator.Assign: // This can occur when changing between variable types
selectedIndex = 0; selectedIndex = 0;
break;
case SetOperator.Negate:
selectedIndex = 1;
break;
case SetOperator.Add:
selectedIndex = 1;
break;
case SetOperator.Subtract:
selectedIndex = 2;
break;
case SetOperator.Multiply:
selectedIndex = 3;
break;
case SetOperator.Divide:
selectedIndex = 4;
break;
} }
// Get next selected operator
selectedIndex = EditorGUILayout.Popup(new GUIContent("Operation", "Arithmetic operator to use"), selectedIndex, operatorsList.ToArray()); selectedIndex = EditorGUILayout.Popup(new GUIContent("Operation", "Arithmetic operator to use"), selectedIndex, operatorsList.ToArray());
SetOperator setOperator = SetOperator.Assign;
if (variableType == typeof(BooleanVariable) ||
variableType == typeof(StringVariable))
{
switch (selectedIndex)
{
default:
case 0:
setOperator = SetOperator.Assign;
break;
case 1:
setOperator = SetOperator.Negate;
break;
}
}
else if (variableType == typeof(IntegerVariable) ||
variableType == typeof(FloatVariable))
{
switch (selectedIndex)
{
default:
case 0:
setOperator = SetOperator.Assign;
break;
case 1:
setOperator = SetOperator.Add;
break;
case 2:
setOperator = SetOperator.Subtract;
break;
case 3:
setOperator = SetOperator.Multiply;
break;
case 4:
setOperator = SetOperator.Divide;
break;
}
}
setOperatorProp.enumValueIndex = (int)setOperator; setOperatorProp.enumValueIndex = (int)setOperators[selectedIndex];
VariablePropertyInfo propertyInfo = propertyInfoByVariableType[variableType];
EditorGUILayout.PropertyField(propertyInfo.dataProp, new GUIContent(propertyInfo.name));
if (variableType == typeof(BooleanVariable))
{
EditorGUILayout.PropertyField(booleanDataProp, new GUIContent("Boolean"));
}
else if (variableType == typeof(IntegerVariable))
{
EditorGUILayout.PropertyField(integerDataProp, new GUIContent("Integer"));
}
else if (variableType == typeof(FloatVariable))
{
EditorGUILayout.PropertyField(floatDataProp, new GUIContent("Float"));
}
else if (variableType == typeof(StringVariable))
{
EditorGUILayout.PropertyField(stringDataProp, new GUIContent("String"));
}
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }

2
Assets/Fungus/Scripts/Editor/VariableEditor.cs

@ -229,7 +229,7 @@ namespace Fungus.EditorUtils
Rect valueRect = controlRect; Rect valueRect = controlRect;
valueRect.width = controlRect.width - popupWidth - 5; valueRect.width = controlRect.width - popupWidth - 5;
Rect popupRect = controlRect; Rect popupRect = controlRect;
if (referenceProp.objectReferenceValue == null) if (referenceProp.objectReferenceValue == null)
{ {
EditorGUI.PropertyField(valueRect, valueProp, new GUIContent("")); EditorGUI.PropertyField(valueRect, valueProp, new GUIContent(""));

15
Assets/Fungus/Scripts/VariableTypes/BooleanVariable.cs

@ -13,6 +13,8 @@ namespace Fungus
[System.Serializable] [System.Serializable]
public class BooleanVariable : VariableBase<bool> public class BooleanVariable : VariableBase<bool>
{ {
public static readonly SetOperator[] operators = { SetOperator.Assign, SetOperator.Negate };
public virtual bool Evaluate(CompareOperator compareOperator, bool booleanValue) public virtual bool Evaluate(CompareOperator compareOperator, bool booleanValue)
{ {
bool condition = false; bool condition = false;
@ -34,6 +36,19 @@ namespace Fungus
return condition; return condition;
} }
public override void Apply(SetOperator setOperator, bool value)
{
switch (setOperator)
{
default:
case SetOperator.Assign:
Value = value;
break;
case SetOperator.Negate:
Value = !value;
break;
}
}
} }
/// <summary> /// <summary>

25
Assets/Fungus/Scripts/VariableTypes/FloatVariable.cs

@ -13,6 +13,8 @@ namespace Fungus
[System.Serializable] [System.Serializable]
public class FloatVariable : VariableBase<float> public class FloatVariable : VariableBase<float>
{ {
public static readonly SetOperator[] operators = { SetOperator.Assign, SetOperator.Add, SetOperator.Subtract, SetOperator.Multiply, SetOperator.Divide };
public virtual bool Evaluate(CompareOperator compareOperator, float floatValue) public virtual bool Evaluate(CompareOperator compareOperator, float floatValue)
{ {
float lhs = Value; float lhs = Value;
@ -44,6 +46,29 @@ namespace Fungus
return condition; return condition;
} }
public override void Apply(SetOperator setOperator, float value)
{
switch (setOperator)
{
default:
case SetOperator.Assign:
Value = value;
break;
case SetOperator.Add:
Value += value;
break;
case SetOperator.Subtract:
Value -= value;
break;
case SetOperator.Multiply:
Value *= value;
break;
case SetOperator.Divide:
Value /= value;
break;
}
}
} }
/// <summary> /// <summary>

15
Assets/Fungus/Scripts/VariableTypes/GameObjectVariable.cs

@ -13,7 +13,20 @@ namespace Fungus
[AddComponentMenu("")] [AddComponentMenu("")]
[System.Serializable] [System.Serializable]
public class GameObjectVariable : VariableBase<GameObject> public class GameObjectVariable : VariableBase<GameObject>
{} {
public static readonly SetOperator[] operators = { SetOperator.Assign };
public override void Apply(SetOperator setOperator, GameObject value)
{
switch (setOperator)
{
default:
case SetOperator.Assign:
Value = value;
break;
}
}
}
/// <summary> /// <summary>
/// Container for a GameObject variable reference or constant value. /// Container for a GameObject variable reference or constant value.

25
Assets/Fungus/Scripts/VariableTypes/IntegerVariable.cs

@ -13,6 +13,8 @@ namespace Fungus
[System.Serializable] [System.Serializable]
public class IntegerVariable : VariableBase<int> public class IntegerVariable : VariableBase<int>
{ {
public static readonly SetOperator[] operators = { SetOperator.Assign, SetOperator.Add, SetOperator.Subtract, SetOperator.Multiply, SetOperator.Divide };
public virtual bool Evaluate(CompareOperator compareOperator, int integerValue) public virtual bool Evaluate(CompareOperator compareOperator, int integerValue)
{ {
int lhs = Value; int lhs = Value;
@ -44,6 +46,29 @@ namespace Fungus
return condition; return condition;
} }
public override void Apply(SetOperator setOperator, int value)
{
switch (setOperator)
{
default:
case SetOperator.Assign:
Value = value;
break;
case SetOperator.Add:
Value += value;
break;
case SetOperator.Subtract:
Value -= value;
break;
case SetOperator.Multiply:
Value *= value;
break;
case SetOperator.Divide:
Value /= value;
break;
}
}
} }
/// <summary> /// <summary>

13
Assets/Fungus/Scripts/VariableTypes/StringVariable.cs

@ -13,6 +13,8 @@ namespace Fungus
[System.Serializable] [System.Serializable]
public class StringVariable : VariableBase<string> public class StringVariable : VariableBase<string>
{ {
public static readonly SetOperator[] operators = { SetOperator.Assign };
public virtual bool Evaluate(CompareOperator compareOperator, string stringValue) public virtual bool Evaluate(CompareOperator compareOperator, string stringValue)
{ {
string lhs = Value; string lhs = Value;
@ -33,6 +35,17 @@ namespace Fungus
return condition; return condition;
} }
public override void Apply(SetOperator setOperator, string value)
{
switch (setOperator)
{
default:
case SetOperator.Assign:
Value = value;
break;
}
}
} }
/// <summary> /// <summary>

Loading…
Cancel
Save