Browse Source

merged InvokeMethod.cs

master
Timothy Ng 9 years ago
parent
commit
a2d4ae5b25
  1. 832
      Assets/Fungus/Flowchart/Editor/InvokeMethodEditor.cs
  2. 41
      Assets/Fungus/Flowchart/Scripts/Block.cs
  3. 4
      Assets/Fungus/Flowchart/Scripts/Commands/Call.cs
  4. 248
      Assets/Fungus/Flowchart/Scripts/Commands/InvokeMethod.cs
  5. 131
      Assets/Fungus/Flowchart/Scripts/Flowchart.cs
  6. 2
      Assets/Fungus/Narrative/Scripts/Commands/Say.cs
  7. 10
      Assets/Fungus/Narrative/Scripts/MenuDialog.cs
  8. 10
      Assets/Fungus/Narrative/Scripts/SayDialog.cs
  9. 414
      Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs
  10. 6
      Assets/Fungus/UI/Scripts/Commands/Write.cs
  11. 8
      Assets/Fungus/UI/Scripts/Writer.cs
  12. 72
      Assets/Tests/Scripting/Scripting.unity

832
Assets/Fungus/Flowchart/Editor/InvokeMethodEditor.cs

@ -13,430 +13,430 @@ namespace Fungus
[CustomEditor(typeof(InvokeMethod))]
public class InvokeMethodEditor : CommandEditor
{
InvokeMethod targetMethod;
public override void DrawCommandGUI()
{
base.DrawCommandGUI();
targetMethod = target as InvokeMethod;
if (targetMethod == null || targetMethod.targetObject == null)
return;
SerializedObject objSerializedTarget = new SerializedObject(targetMethod);
string component = ShowComponents(objSerializedTarget, targetMethod.targetObject);
// show component methods if selected
if (!string.IsNullOrEmpty(component))
{
var method = ShowMethods(objSerializedTarget, targetMethod.targetObject, component);
// show method parameters if selected
if (method != null)
{
objSerializedTarget.ApplyModifiedProperties();
ShowParameters(objSerializedTarget, targetMethod.targetObject, method);
ShowReturnValue(objSerializedTarget, method);
}
}
}
private string ShowComponents(SerializedObject objTarget, GameObject gameObject)
{
var targetComponentAssemblyName = objTarget.FindProperty("targetComponentAssemblyName");
var targetComponentFullname = objTarget.FindProperty("targetComponentFullname");
var targetComponentText = objTarget.FindProperty("targetComponentText");
var objComponents = gameObject.GetComponents<Component>();
var objTypesAssemblynames = (from objComp in objComponents select objComp.GetType().AssemblyQualifiedName).ToList();
var objTypesName = (from objComp in objComponents select objComp.GetType().Name).ToList();
int index = objTypesAssemblynames.IndexOf(targetComponentAssemblyName.stringValue);
index = EditorGUILayout.Popup("Target Component", index, objTypesName.ToArray());
if (index != -1)
{
targetComponentAssemblyName.stringValue = objTypesAssemblynames[index];
targetComponentFullname.stringValue = objComponents.GetType().FullName;
targetComponentText.stringValue = objTypesName[index];
}
else
{
targetComponentAssemblyName.stringValue = null;
}
objTarget.ApplyModifiedProperties();
return targetComponentAssemblyName.stringValue;
}
private MethodInfo ShowMethods(SerializedObject objTarget, GameObject gameObject, string component)
{
MethodInfo result = null;
var targetMethodProp = objTarget.FindProperty("targetMethod");
var targetMethodTextProp = objTarget.FindProperty("targetMethodText");
var methodParametersProp = objTarget.FindProperty("methodParameters");
InvokeMethod targetMethod;
public override void DrawCommandGUI()
{
base.DrawCommandGUI();
targetMethod = target as InvokeMethod;
if (targetMethod == null || targetMethod.targetObject == null)
return;
SerializedObject objSerializedTarget = new SerializedObject(targetMethod);
string component = ShowComponents(objSerializedTarget, targetMethod.targetObject);
// show component methods if selected
if (!string.IsNullOrEmpty(component))
{
var method = ShowMethods(objSerializedTarget, targetMethod.targetObject, component);
// show method parameters if selected
if (method != null)
{
objSerializedTarget.ApplyModifiedProperties();
ShowParameters(objSerializedTarget, targetMethod.targetObject, method);
ShowReturnValue(objSerializedTarget, method);
}
}
}
private string ShowComponents(SerializedObject objTarget, GameObject gameObject)
{
var targetComponentAssemblyName = objTarget.FindProperty("targetComponentAssemblyName");
var targetComponentFullname = objTarget.FindProperty("targetComponentFullname");
var targetComponentText = objTarget.FindProperty("targetComponentText");
var objComponents = gameObject.GetComponents<Component>();
var objTypesAssemblynames = (from objComp in objComponents select objComp.GetType().AssemblyQualifiedName).ToList();
var objTypesName = (from objComp in objComponents select objComp.GetType().Name).ToList();
int index = objTypesAssemblynames.IndexOf(targetComponentAssemblyName.stringValue);
index = EditorGUILayout.Popup("Target Component", index, objTypesName.ToArray());
if (index != -1)
{
targetComponentAssemblyName.stringValue = objTypesAssemblynames[index];
targetComponentFullname.stringValue = objComponents.GetType().FullName;
targetComponentText.stringValue = objTypesName[index];
}
else
{
targetComponentAssemblyName.stringValue = null;
}
objTarget.ApplyModifiedProperties();
return targetComponentAssemblyName.stringValue;
}
private MethodInfo ShowMethods(SerializedObject objTarget, GameObject gameObject, string component)
{
MethodInfo result = null;
var targetMethodProp = objTarget.FindProperty("targetMethod");
var targetMethodTextProp = objTarget.FindProperty("targetMethodText");
var methodParametersProp = objTarget.FindProperty("methodParameters");
var showInheritedProp = objTarget.FindProperty("showInherited");
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue");
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey");
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue");
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey");
var objComponent = gameObject.GetComponent(ReflectionHelper.GetType(component));
var bindingFlags = BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance;
var objComponent = gameObject.GetComponent(ReflectionHelper.GetType(component));
var bindingFlags = BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance;
if (!showInheritedProp.boolValue)
{
bindingFlags |= BindingFlags.DeclaredOnly;
}
if (!showInheritedProp.boolValue)
{
bindingFlags |= BindingFlags.DeclaredOnly;
}
if (objComponent != null)
{
var objMethods = objComponent.GetType().GetMethods(bindingFlags);
var methods = (from objMethod in objMethods where !objMethod.IsSpecialName select objMethod).ToList(); // filter out the getter/setter methods
var methodText = (from objMethod in methods select objMethod.Name + FormatParameters(objMethod.GetParameters()) + ": " + objMethod.ReturnType.Name).ToList();
int index = methodText.IndexOf(targetMethodTextProp.stringValue);
if (objComponent != null)
{
var objMethods = objComponent.GetType().GetMethods(bindingFlags);
var methods = (from objMethod in objMethods where !objMethod.IsSpecialName select objMethod).ToList(); // filter out the getter/setter methods
var methodText = (from objMethod in methods select objMethod.Name + FormatParameters(objMethod.GetParameters()) + ": " + objMethod.ReturnType.Name).ToList();
int index = methodText.IndexOf(targetMethodTextProp.stringValue);
index = EditorGUILayout.Popup("Target Method", index, methodText.ToArray());
index = EditorGUILayout.Popup("Target Method", index, methodText.ToArray());
EditorGUILayout.PropertyField(showInheritedProp);
if (index != -1)
{
if (targetMethodTextProp.stringValue != methodText[index])
{
// reset
methodParametersProp.ClearArray();
methodParametersProp.arraySize = methods[index].GetParameters().Length;
saveReturnValueProp.boolValue = false;
returnValueKeyProp.stringValue = null;
}
targetMethodTextProp.stringValue = methodText[index];
targetMethodProp.stringValue = methods[index].Name;
result = methods[index];
}
else
{
targetMethodTextProp.stringValue = null;
targetMethodProp.stringValue = null;
}
objTarget.ApplyModifiedProperties();
}
return result;
}
private void ShowParameters(SerializedObject objTarget, GameObject gameObject, MethodInfo method)
{
var methodParametersProp = objTarget.FindProperty("methodParameters");
var objParams = method.GetParameters();
if (objParams.Length > 0)
{
GUILayout.Space(20);
EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
for (int i = 0; i < objParams.Length; i++)
{
var objParam = objParams[i];
GUILayout.BeginHorizontal();
string labelFormat = string.Format("{0}: {1}", objParam.ParameterType.Name, objParam.Name);
var objItemProp = methodParametersProp.GetArrayElementAtIndex(i);
var serObjValueProp = objItemProp.FindPropertyRelative("objValue");
var serVariableKeyProp = objItemProp.FindPropertyRelative("variableKey");
var serValueTypeAssemblynameProp = serObjValueProp.FindPropertyRelative("typeAssemblyname");
var serValueTypeFullnameProp = serObjValueProp.FindPropertyRelative("typeFullname");
serValueTypeAssemblynameProp.stringValue = objParam.ParameterType.AssemblyQualifiedName;
serValueTypeFullnameProp.stringValue = objParam.ParameterType.FullName;
bool isDrawn = true;
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue))
{
isDrawn = DrawTypedPropertyInput(labelFormat, serObjValueProp, objParam.ParameterType);
}
if (isDrawn)
{
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().variables, objParam.ParameterType);
var values = new string[] { "<Value>" };
var displayValue = values.Concat(vars).ToList();
int index = displayValue.IndexOf(serVariableKeyProp.stringValue);
if (index == -1)
{
index = 0;
}
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue))
{
index = EditorGUILayout.Popup(index, displayValue.ToArray(), GUILayout.MaxWidth(80));
}
else
{
index = EditorGUILayout.Popup(labelFormat, index, displayValue.ToArray());
}
if (index > 0)
{
serVariableKeyProp.stringValue = displayValue[index];
}
else
{
serVariableKeyProp.stringValue = null;
}
}
else
{
var style = EditorStyles.label;
var prevColor = style.normal.textColor;
style.normal.textColor = Color.red;
EditorGUILayout.LabelField(new GUIContent(objParam.ParameterType.Name + " cannot be drawn, don´t use this method in the flowchart."), style);
style.normal.textColor = prevColor;
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
objTarget.ApplyModifiedProperties();
}
}
private void ShowReturnValue(SerializedObject objTarget, MethodInfo method)
{
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue");
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey");
var returnValueTypeProp = objTarget.FindProperty("returnValueType");
var callModeProp = objTarget.FindProperty("callMode");
returnValueTypeProp.stringValue = method.ReturnType.FullName;
if (method.ReturnType == typeof(IEnumerator))
{
GUILayout.Space(20);
EditorGUILayout.PropertyField(callModeProp);
}
else if (method.ReturnType != typeof(void))
{
GUILayout.Space(20);
EditorGUILayout.LabelField("Return Value", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
saveReturnValueProp.boolValue = EditorGUILayout.Toggle("Save return value", saveReturnValueProp.boolValue);
if (saveReturnValueProp.boolValue)
{
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().variables, method.ReturnType).ToList();
int index = vars.IndexOf(returnValueKeyProp.stringValue);
index = EditorGUILayout.Popup(method.ReturnType.Name, index, vars.ToArray());
if (index != -1)
{
returnValueKeyProp.stringValue = vars[index];
}
}
EditorGUILayout.EndVertical();
}
else
{
saveReturnValueProp.boolValue = false;
}
objTarget.ApplyModifiedProperties();
}
private bool DrawTypedPropertyInput(string label, SerializedProperty objProperty, Type type)
{
SerializedProperty objectValue = null;
if (type == typeof(int))
{
objectValue = objProperty.FindPropertyRelative("intValue");
objectValue.intValue = EditorGUILayout.IntField(new GUIContent(label), objectValue.intValue);
return true;
}
else if (type == typeof(bool))
{
objectValue = objProperty.FindPropertyRelative("boolValue");
objectValue.boolValue = EditorGUILayout.Toggle(new GUIContent(label), objectValue.boolValue);
return true;
}
else if (type == typeof(float))
{
objectValue = objProperty.FindPropertyRelative("floatValue");
objectValue.floatValue = EditorGUILayout.FloatField(new GUIContent(label), objectValue.floatValue);
return true;
}
else if (type == typeof(string))
{
objectValue = objProperty.FindPropertyRelative("stringValue");
objectValue.stringValue = EditorGUILayout.TextField(new GUIContent(label), objectValue.stringValue);
return true;
}
else if (type == typeof(Color))
{
objectValue = objProperty.FindPropertyRelative("colorValue");
objectValue.colorValue = EditorGUILayout.ColorField(new GUIContent(label), objectValue.colorValue);
return true;
}
else if (type == typeof(UnityEngine.GameObject))
{
objectValue = objProperty.FindPropertyRelative("gameObjectValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.GameObject), true);
return true;
}
else if (type == typeof(UnityEngine.Material))
{
objectValue = objProperty.FindPropertyRelative("materialValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Material), true);
return true;
}
else if (type == typeof(UnityEngine.Sprite))
{
objectValue = objProperty.FindPropertyRelative("spriteValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Sprite), true);
return true;
}
else if (type == typeof(UnityEngine.Texture))
{
objectValue = objProperty.FindPropertyRelative("textureValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Texture), true);
return true;
}
else if (type == typeof(UnityEngine.Vector2))
{
objectValue = objProperty.FindPropertyRelative("vector2Value");
objectValue.vector2Value = EditorGUILayout.Vector2Field(new GUIContent(label), objectValue.vector2Value);
return true;
}
else if (type == typeof(UnityEngine.Vector3))
{
objectValue = objProperty.FindPropertyRelative("vector3Value");
objectValue.vector3Value = EditorGUILayout.Vector3Field(new GUIContent(label), objectValue.vector3Value);
return true;
}
else if (type.IsSubclassOf(typeof(UnityEngine.Object)))
{
objectValue = objProperty.FindPropertyRelative("objectValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, type, true);
return true;
}
else if (type.IsEnum)
{
var enumNames = Enum.GetNames(type);
objectValue = objProperty.FindPropertyRelative("intValue");
objectValue.intValue = EditorGUILayout.Popup(label, objectValue.intValue, enumNames);
return true;
}
return false;
}
private string[] GetFungusVariablesByType(List<Variable> variables, Type type)
{
string[] result = new string[0];
if (type == typeof(int))
{
result = (from v in variables where v.GetType() == typeof(IntegerVariable) select v.key).ToArray();
}
else if (type == typeof(bool))
{
result = (from v in variables where v.GetType() == typeof(BooleanVariable) select v.key).ToArray();
}
else if (type == typeof(float))
{
result = (from v in variables where v.GetType() == typeof(FloatVariable) select v.key).ToArray();
}
else if (type == typeof(string))
{
result = (from v in variables where v.GetType() == typeof(StringVariable) select v.key).ToArray();
}
else if (type == typeof(Color))
{
result = (from v in variables where v.GetType() == typeof(ColorVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.GameObject))
{
result = (from v in variables where v.GetType() == typeof(GameObjectVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Material))
{
result = (from v in variables where v.GetType() == typeof(MaterialVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Sprite))
{
result = (from v in variables where v.GetType() == typeof(SpriteVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Texture))
{
result = (from v in variables where v.GetType() == typeof(TextureVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Vector2))
{
result = (from v in variables where v.GetType() == typeof(Vector2Variable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Vector3))
{
result = (from v in variables where v.GetType() == typeof(Vector3Variable) select v.key).ToArray();
}
else if (type.IsSubclassOf(typeof(UnityEngine.Object)))
{
result = (from v in variables where v.GetType() == typeof(ObjectVariable) select v.key).ToArray();
}
return result;
}
private string FormatParameters(ParameterInfo[] paramInfo)
{
string result = " (";
for (int i = 0; i < paramInfo.Length; i++)
{
var pi = paramInfo[i];
result += pi.ParameterType.Name; // " arg" + (i + 1);
if (i < paramInfo.Length - 1)
{
result += ", ";
}
}
return result + ")";
}
private object GetDefaultValue(Type t)
{
if (t.IsValueType)
return Activator.CreateInstance(t);
return null;
}
if (index != -1)
{
if (targetMethodTextProp.stringValue != methodText[index])
{
// reset
methodParametersProp.ClearArray();
methodParametersProp.arraySize = methods[index].GetParameters().Length;
saveReturnValueProp.boolValue = false;
returnValueKeyProp.stringValue = null;
}
targetMethodTextProp.stringValue = methodText[index];
targetMethodProp.stringValue = methods[index].Name;
result = methods[index];
}
else
{
targetMethodTextProp.stringValue = null;
targetMethodProp.stringValue = null;
}
objTarget.ApplyModifiedProperties();
}
return result;
}
private void ShowParameters(SerializedObject objTarget, GameObject gameObject, MethodInfo method)
{
var methodParametersProp = objTarget.FindProperty("methodParameters");
var objParams = method.GetParameters();
if (objParams.Length > 0)
{
GUILayout.Space(20);
EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
for (int i = 0; i < objParams.Length; i++)
{
var objParam = objParams[i];
GUILayout.BeginHorizontal();
string labelFormat = string.Format("{0}: {1}", objParam.ParameterType.Name, objParam.Name);
var objItemProp = methodParametersProp.GetArrayElementAtIndex(i);
var serObjValueProp = objItemProp.FindPropertyRelative("objValue");
var serVariableKeyProp = objItemProp.FindPropertyRelative("variableKey");
var serValueTypeAssemblynameProp = serObjValueProp.FindPropertyRelative("typeAssemblyname");
var serValueTypeFullnameProp = serObjValueProp.FindPropertyRelative("typeFullname");
serValueTypeAssemblynameProp.stringValue = objParam.ParameterType.AssemblyQualifiedName;
serValueTypeFullnameProp.stringValue = objParam.ParameterType.FullName;
bool isDrawn = true;
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue))
{
isDrawn = DrawTypedPropertyInput(labelFormat, serObjValueProp, objParam.ParameterType);
}
if (isDrawn)
{
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().variables, objParam.ParameterType);
var values = new string[] { "<Value>" };
var displayValue = values.Concat(vars).ToList();
int index = displayValue.IndexOf(serVariableKeyProp.stringValue);
if (index == -1)
{
index = 0;
}
if (string.IsNullOrEmpty(serVariableKeyProp.stringValue))
{
index = EditorGUILayout.Popup(index, displayValue.ToArray(), GUILayout.MaxWidth(80));
}
else
{
index = EditorGUILayout.Popup(labelFormat, index, displayValue.ToArray());
}
if (index > 0)
{
serVariableKeyProp.stringValue = displayValue[index];
}
else
{
serVariableKeyProp.stringValue = null;
}
}
else
{
var style = EditorStyles.label;
var prevColor = style.normal.textColor;
style.normal.textColor = Color.red;
EditorGUILayout.LabelField(new GUIContent(objParam.ParameterType.Name + " cannot be drawn, don´t use this method in the flowchart."), style);
style.normal.textColor = prevColor;
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
objTarget.ApplyModifiedProperties();
}
}
private void ShowReturnValue(SerializedObject objTarget, MethodInfo method)
{
var saveReturnValueProp = objTarget.FindProperty("saveReturnValue");
var returnValueKeyProp = objTarget.FindProperty("returnValueVariableKey");
var returnValueTypeProp = objTarget.FindProperty("returnValueType");
var callModeProp = objTarget.FindProperty("callMode");
returnValueTypeProp.stringValue = method.ReturnType.FullName;
if (method.ReturnType == typeof(IEnumerator))
{
GUILayout.Space(20);
EditorGUILayout.PropertyField(callModeProp);
}
else if (method.ReturnType != typeof(void))
{
GUILayout.Space(20);
EditorGUILayout.LabelField("Return Value", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
saveReturnValueProp.boolValue = EditorGUILayout.Toggle("Save return value", saveReturnValueProp.boolValue);
if (saveReturnValueProp.boolValue)
{
var vars = GetFungusVariablesByType(targetMethod.GetFlowchart().variables, method.ReturnType).ToList();
int index = vars.IndexOf(returnValueKeyProp.stringValue);
index = EditorGUILayout.Popup(method.ReturnType.Name, index, vars.ToArray());
if (index != -1)
{
returnValueKeyProp.stringValue = vars[index];
}
}
EditorGUILayout.EndVertical();
}
else
{
saveReturnValueProp.boolValue = false;
}
objTarget.ApplyModifiedProperties();
}
private bool DrawTypedPropertyInput(string label, SerializedProperty objProperty, Type type)
{
SerializedProperty objectValue = null;
if (type == typeof(int))
{
objectValue = objProperty.FindPropertyRelative("intValue");
objectValue.intValue = EditorGUILayout.IntField(new GUIContent(label), objectValue.intValue);
return true;
}
else if (type == typeof(bool))
{
objectValue = objProperty.FindPropertyRelative("boolValue");
objectValue.boolValue = EditorGUILayout.Toggle(new GUIContent(label), objectValue.boolValue);
return true;
}
else if (type == typeof(float))
{
objectValue = objProperty.FindPropertyRelative("floatValue");
objectValue.floatValue = EditorGUILayout.FloatField(new GUIContent(label), objectValue.floatValue);
return true;
}
else if (type == typeof(string))
{
objectValue = objProperty.FindPropertyRelative("stringValue");
objectValue.stringValue = EditorGUILayout.TextField(new GUIContent(label), objectValue.stringValue);
return true;
}
else if (type == typeof(Color))
{
objectValue = objProperty.FindPropertyRelative("colorValue");
objectValue.colorValue = EditorGUILayout.ColorField(new GUIContent(label), objectValue.colorValue);
return true;
}
else if (type == typeof(UnityEngine.GameObject))
{
objectValue = objProperty.FindPropertyRelative("gameObjectValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.GameObject), true);
return true;
}
else if (type == typeof(UnityEngine.Material))
{
objectValue = objProperty.FindPropertyRelative("materialValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Material), true);
return true;
}
else if (type == typeof(UnityEngine.Sprite))
{
objectValue = objProperty.FindPropertyRelative("spriteValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Sprite), true);
return true;
}
else if (type == typeof(UnityEngine.Texture))
{
objectValue = objProperty.FindPropertyRelative("textureValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, typeof(UnityEngine.Texture), true);
return true;
}
else if (type == typeof(UnityEngine.Vector2))
{
objectValue = objProperty.FindPropertyRelative("vector2Value");
objectValue.vector2Value = EditorGUILayout.Vector2Field(new GUIContent(label), objectValue.vector2Value);
return true;
}
else if (type == typeof(UnityEngine.Vector3))
{
objectValue = objProperty.FindPropertyRelative("vector3Value");
objectValue.vector3Value = EditorGUILayout.Vector3Field(new GUIContent(label), objectValue.vector3Value);
return true;
}
else if (type.IsSubclassOf(typeof(UnityEngine.Object)))
{
objectValue = objProperty.FindPropertyRelative("objectValue");
objectValue.objectReferenceValue = EditorGUILayout.ObjectField(new GUIContent(label), objectValue.objectReferenceValue, type, true);
return true;
}
else if (type.IsEnum)
{
var enumNames = Enum.GetNames(type);
objectValue = objProperty.FindPropertyRelative("intValue");
objectValue.intValue = EditorGUILayout.Popup(label, objectValue.intValue, enumNames);
return true;
}
return false;
}
private string[] GetFungusVariablesByType(List<Variable> variables, Type type)
{
string[] result = new string[0];
if (type == typeof(int))
{
result = (from v in variables where v.GetType() == typeof(IntegerVariable) select v.key).ToArray();
}
else if (type == typeof(bool))
{
result = (from v in variables where v.GetType() == typeof(BooleanVariable) select v.key).ToArray();
}
else if (type == typeof(float))
{
result = (from v in variables where v.GetType() == typeof(FloatVariable) select v.key).ToArray();
}
else if (type == typeof(string))
{
result = (from v in variables where v.GetType() == typeof(StringVariable) select v.key).ToArray();
}
else if (type == typeof(Color))
{
result = (from v in variables where v.GetType() == typeof(ColorVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.GameObject))
{
result = (from v in variables where v.GetType() == typeof(GameObjectVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Material))
{
result = (from v in variables where v.GetType() == typeof(MaterialVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Sprite))
{
result = (from v in variables where v.GetType() == typeof(SpriteVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Texture))
{
result = (from v in variables where v.GetType() == typeof(TextureVariable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Vector2))
{
result = (from v in variables where v.GetType() == typeof(Vector2Variable) select v.key).ToArray();
}
else if (type == typeof(UnityEngine.Vector3))
{
result = (from v in variables where v.GetType() == typeof(Vector3Variable) select v.key).ToArray();
}
else if (type.IsSubclassOf(typeof(UnityEngine.Object)))
{
result = (from v in variables where v.GetType() == typeof(ObjectVariable) select v.key).ToArray();
}
return result;
}
private string FormatParameters(ParameterInfo[] paramInfo)
{
string result = " (";
for (int i = 0; i < paramInfo.Length; i++)
{
var pi = paramInfo[i];
result += pi.ParameterType.Name; // " arg" + (i + 1);
if (i < paramInfo.Length - 1)
{
result += ", ";
}
}
return result + ")";
}
private object GetDefaultValue(Type t)
{
if (t.IsValueType)
return Activator.CreateInstance(t);
return null;
}
}
}

41
Assets/Fungus/Flowchart/Scripts/Block.cs

@ -142,26 +142,25 @@ namespace Fungus
return executionCount;
}
public virtual bool Execute(Action onComplete = null)
/// <summary>
/// Execute the Block in a coroutine. Only one running instance of each Block is permitted.
/// </summary>
/// <param name="commandIndex">Index of command to start execution at</param>
/// <param name="onComplete">Delegate function to call when execution completes</param>
public virtual IEnumerator Execute(int commandIndex = 0, Action onComplete = null)
{
if (executionState != ExecutionState.Idle)
{
return false;
}
if (!executionInfoSet)
{
SetExecutionInfo();
}
if (executionState != ExecutionState.Idle)
{
yield break;
}
executionCount++;
StartCoroutine(ExecuteBlock(onComplete));
if (!executionInfoSet)
{
SetExecutionInfo();
}
return true;
}
executionCount++;
protected virtual IEnumerator ExecuteBlock(Action onComplete = null)
{
Flowchart flowchart = GetFlowchart();
executionState = ExecutionState.Executing;
@ -175,6 +174,8 @@ namespace Fungus
}
#endif
jumpToCommandIndex = commandIndex;
int i = 0;
while (true)
{
@ -248,10 +249,10 @@ namespace Fungus
executionState = ExecutionState.Idle;
activeCommand = null;
if (onComplete != null)
{
onComplete();
}
if (onComplete != null)
{
onComplete();
}
}
public virtual void Stop()

4
Assets/Fungus/Flowchart/Scripts/Commands/Call.cs

@ -64,12 +64,12 @@ namespace Fungus
flowchart.selectedBlock = targetBlock;
}
targetBlock.Execute(onComplete);
StartCoroutine(targetBlock.Execute(0, onComplete));
}
else
{
// Execute block in another Flowchart
targetFlowchart.ExecuteBlock(targetBlock, onComplete);
targetFlowchart.ExecuteBlock(targetBlock, 0, onComplete);
}
}

248
Assets/Fungus/Flowchart/Scripts/Commands/InvokeMethod.cs

@ -11,87 +11,87 @@ namespace Fungus
{
[CommandInfo("Scripting",
"Invoke Method",
"Invokes a method of a component via reflection. Supports passing multiple parameters and storing returned values in a Fungus variable.")]
"Invoke Method",
"Invokes a method of a component via reflection. Supports passing multiple parameters and storing returned values in a Fungus variable.")]
public class InvokeMethod : Command
{
[Tooltip("GameObject containing the component method to be invoked")]
public GameObject targetObject;
public GameObject targetObject;
[HideInInspector]
[Tooltip("Name of assembly containing the target component")]
public string targetComponentAssemblyName;
[HideInInspector]
[HideInInspector]
[Tooltip("Full name of the target component")]
public string targetComponentFullname;
[HideInInspector]
[HideInInspector]
[Tooltip("Display name of the target component")]
public string targetComponentText;
[HideInInspector]
[HideInInspector]
[Tooltip("Name of target method to invoke on the target component")]
public string targetMethod;
[HideInInspector]
[HideInInspector]
[Tooltip("Display name of target method to invoke on the target component")]
public string targetMethodText;
[HideInInspector]
[HideInInspector]
[Tooltip("List of parameters to pass to the invoked method")]
public InvokeMethodParameter[] methodParameters;
[HideInInspector]
[HideInInspector]
[Tooltip("If true, store the return value in a flowchart variable of the same type.")]
public bool saveReturnValue;
[HideInInspector]
[HideInInspector]
[Tooltip("Name of Fungus variable to store the return value in")]
public string returnValueVariableKey;
[HideInInspector]
[HideInInspector]
[Tooltip("The type of the return value")]
public string returnValueType;
[HideInInspector]
[HideInInspector]
[Tooltip("If true, list all inherited methods for the component")]
public bool showInherited;
public bool showInherited;
[HideInInspector]
[HideInInspector]
[Tooltip("The coroutine call behavior for methods that return IEnumerator")]
public Fungus.Call.CallMode callMode;
public Fungus.Call.CallMode callMode;
protected Type componentType;
protected Type componentType;
protected Component objComponent;
protected Type[] parameterTypes = null;
protected MethodInfo objMethod;
protected virtual void Awake()
{
protected virtual void Awake()
{
if (componentType == null)
{
componentType = ReflectionHelper.GetType(targetComponentAssemblyName);
}
if (objComponent == null)
{
objComponent = targetObject.GetComponent(componentType);
}
if (parameterTypes == null)
{
parameterTypes = GetParameterTypes();
}
if (objMethod == null)
{
objMethod = UnityEvent.GetValidMethodInfo(objComponent, targetMethod, parameterTypes);
}
}
public override void OnEnter()
{
}
public override void OnEnter()
{
try
{
if (targetObject == null || string.IsNullOrEmpty(targetComponentAssemblyName) || string.IsNullOrEmpty(targetMethod))
@ -99,29 +99,29 @@ namespace Fungus
Continue();
return;
}
if (returnValueType != "System.Collections.IEnumerator")
{
var objReturnValue = objMethod.Invoke(objComponent, GetParameterValues());
if (saveReturnValue)
{
SetVariable(returnValueVariableKey, objReturnValue, returnValueType);
}
Continue();
}
else
{
StartCoroutine(ExecuteCoroutine());
if (callMode == Call.CallMode.Continue)
{
Continue();
}
else if(callMode == Call.CallMode.Stop)
{
StopParentBlock();
StopParentBlock();
}
}
}
@ -131,45 +131,45 @@ namespace Fungus
}
}
protected virtual IEnumerator ExecuteCoroutine()
{
yield return StartCoroutine((IEnumerator)objMethod.Invoke(objComponent, GetParameterValues()));
protected virtual IEnumerator ExecuteCoroutine()
{
yield return StartCoroutine((IEnumerator)objMethod.Invoke(objComponent, GetParameterValues()));
if (callMode == Call.CallMode.WaitUntilFinished)
{
Continue();
}
}
if (callMode == Call.CallMode.WaitUntilFinished)
{
Continue();
}
}
public override Color GetButtonColor()
{
return new Color32(235, 191, 217, 255);
}
public override string GetSummary()
{
if (targetObject == null)
{
return "Error: targetObject is not assigned";
}
public override string GetSummary()
{
if (targetObject == null)
{
return "Error: targetObject is not assigned";
}
return targetObject.name + "." + targetComponentText + "." + targetMethodText;
}
return targetObject.name + "." + targetComponentText + "." + targetMethodText;
}
protected System.Type[] GetParameterTypes()
{
System.Type[] types = new System.Type[methodParameters.Length];
{
System.Type[] types = new System.Type[methodParameters.Length];
for (int i = 0; i < methodParameters.Length; i++)
{
var item = methodParameters[i];
var objType = ReflectionHelper.GetType(item.objValue.typeAssemblyname);
for (int i = 0; i < methodParameters.Length; i++)
{
var item = methodParameters[i];
var objType = ReflectionHelper.GetType(item.objValue.typeAssemblyname);
types[i] = objType;
}
types[i] = objType;
}
return types;
}
return types;
}
protected object[] GetParameterValues()
{
@ -308,90 +308,90 @@ namespace Fungus
[System.Serializable]
public class InvokeMethodParameter
{
[SerializeField]
public ObjectValue objValue;
[SerializeField]
public ObjectValue objValue;
[SerializeField]
public string variableKey;
[SerializeField]
public string variableKey;
}
[System.Serializable]
public class ObjectValue
{
public string typeAssemblyname;
public string typeFullname;
public int intValue;
public bool boolValue;
public float floatValue;
public string stringValue;
public Color colorValue;
public GameObject gameObjectValue;
public Material materialValue;
public UnityEngine.Object objectValue;
public Sprite spriteValue;
public Texture textureValue;
public Vector2 vector2Value;
public Vector3 vector3Value;
public object GetValue()
{
switch (typeFullname)
{
case "System.Int32":
return intValue;
case "System.Boolean":
return boolValue;
case "System.Single":
return floatValue;
case "System.String":
return stringValue;
case "UnityEngine.Color":
return colorValue;
case "UnityEngine.GameObject":
return gameObjectValue;
case "UnityEngine.Material":
return materialValue;
case "UnityEngine.Sprite":
return spriteValue;
case "UnityEngine.Texture":
return textureValue;
case "UnityEngine.Vector2":
return vector2Value;
case "UnityEngine.Vector3":
return vector3Value;
default:
var objType = ReflectionHelper.GetType(typeAssemblyname);
if (objType.IsSubclassOf(typeof(UnityEngine.Object)))
{
return objectValue;
}
else if (objType.IsEnum())
return System.Enum.ToObject(objType, intValue);
public string typeAssemblyname;
public string typeFullname;
public int intValue;
public bool boolValue;
public float floatValue;
public string stringValue;
public Color colorValue;
public GameObject gameObjectValue;
public Material materialValue;
public UnityEngine.Object objectValue;
public Sprite spriteValue;
public Texture textureValue;
public Vector2 vector2Value;
public Vector3 vector3Value;
public object GetValue()
{
switch (typeFullname)
{
case "System.Int32":
return intValue;
case "System.Boolean":
return boolValue;
case "System.Single":
return floatValue;
case "System.String":
return stringValue;
case "UnityEngine.Color":
return colorValue;
case "UnityEngine.GameObject":
return gameObjectValue;
case "UnityEngine.Material":
return materialValue;
case "UnityEngine.Sprite":
return spriteValue;
case "UnityEngine.Texture":
return textureValue;
case "UnityEngine.Vector2":
return vector2Value;
case "UnityEngine.Vector3":
return vector3Value;
default:
var objType = ReflectionHelper.GetType(typeAssemblyname);
if (objType.IsSubclassOf(typeof(UnityEngine.Object)))
{
return objectValue;
}
else if (objType.IsEnum())
return System.Enum.ToObject(objType, intValue);
break;
}
break;
}
return null;
}
return null;
}
}
public static class ReflectionHelper
{
static Dictionary<string, System.Type> types = new Dictionary<string, System.Type>();
static Dictionary<string, System.Type> types = new Dictionary<string, System.Type>();
public static System.Type GetType(string typeName)
{
if (types.ContainsKey(typeName))
return types[typeName];
public static System.Type GetType(string typeName)
{
if (types.ContainsKey(typeName))
return types[typeName];
types[typeName] = System.Type.GetType(typeName);
types[typeName] = System.Type.GetType(typeName);
return types[typeName];
}
return types[typeName];
}
}
}

131
Assets/Fungus/Flowchart/Scripts/Flowchart.cs

@ -371,61 +371,50 @@ namespace Fungus
}
/**
* Start running another Flowchart by executing a specific child block.
* The block must be in an idle state to be executed.
* Execute a child block in the Flowchart.
* You can use this method in a UI event. e.g. to handle a button click.
* Returns true if the Block started execution.
*/
public virtual void ExecuteBlock(string blockName)
{
Block [] blocks = GetComponentsInChildren<Block>();
foreach (Block block in blocks)
{
if (block.blockName == blockName)
{
ExecuteBlock(block);
}
}
}
/**
* Sends a message to this Flowchart only.
* Any block with a matching MessageReceived event handler will start executing.
*/
public virtual void SendFungusMessage(string messageName)
{
MessageReceived[] eventHandlers = GetComponentsInChildren<MessageReceived>();
foreach (MessageReceived eventHandler in eventHandlers)
{
eventHandler.OnSendFungusMessage(messageName);
}
}
/**
* Sends a message to all Flowchart objects in the current scene.
* Any block with a matching MessageReceived event handler will start executing.
*/
public static void BroadcastFungusMessage(string messageName)
public virtual bool ExecuteBlock(string blockName)
{
MessageReceived[] eventHandlers = GameObject.FindObjectsOfType<MessageReceived>();
foreach (MessageReceived eventHandler in eventHandlers)
{
eventHandler.OnSendFungusMessage(messageName);
}
Block block = null;
foreach (Block b in GetComponentsInChildren<Block>())
{
if (b.blockName == blockName)
{
block = b;
break;
}
}
if (block == null)
{
Debug.LogError("Block " + blockName + "does not exist");
return false;
}
return ExecuteBlock(block);
}
/**
* Start executing a specific child block in the flowchart.
* Execute a child block in the flowchart.
* The block must be in an idle state to be executed.
* This version provides extra options to control how the block is executed.
* Returns true if the Block started execution.
*/
public virtual bool ExecuteBlock(Block block, Action onComplete = null)
public virtual bool ExecuteBlock(Block block, int commandIndex = 0, Action onComplete = null)
{
// Block must be a component of the Flowchart game object
if (block == null ||
block.gameObject != gameObject)
{
return false;
}
if (block == null)
{
Debug.LogError("Block must not be null");
return false;
}
if (block.gameObject != gameObject)
{
Debug.LogError("Block must belong to the same gameobject as this Flowchart");
return false;
}
// Can't restart a running block, have to wait until it's idle again
if (block.IsExecuting())
@ -433,10 +422,10 @@ namespace Fungus
return false;
}
// Execute the first command in the command list
block.Execute(onComplete);
// Start executing the Block as a new coroutine
StartCoroutine(block.Execute(commandIndex, onComplete));
return true;
return true;
}
/**
@ -454,6 +443,32 @@ namespace Fungus
}
}
/**
* Sends a message to this Flowchart only.
* Any block with a matching MessageReceived event handler will start executing.
*/
public virtual void SendFungusMessage(string messageName)
{
MessageReceived[] eventHandlers = GetComponentsInChildren<MessageReceived>();
foreach (MessageReceived eventHandler in eventHandlers)
{
eventHandler.OnSendFungusMessage(messageName);
}
}
/**
* Sends a message to all Flowchart objects in the current scene.
* Any block with a matching MessageReceived event handler will start executing.
*/
public static void BroadcastFungusMessage(string messageName)
{
MessageReceived[] eventHandlers = GameObject.FindObjectsOfType<MessageReceived>();
foreach (MessageReceived eventHandler in eventHandlers)
{
eventHandler.OnSendFungusMessage(messageName);
}
}
/**
* Returns a new variable key that is guaranteed not to clash with any existing variable in the list.
*/
@ -590,6 +605,26 @@ namespace Fungus
}
}
/**
* Returns the variable with the specified key, or null if the key is not found.
* You will need to cast the returned variable to the correct sub-type.
* You can then access the variable's value using the Value property. e.g.
* BooleanVariable boolVar = flowchart.GetVariable("MyBool") as BooleanVariable;
* boolVar.Value = false;
*/
public Variable GetVariable(string key)
{
foreach (Variable variable in variables)
{
if (variable != null && variable.key == key)
{
return variable;
}
}
return null;
}
/**
* Returns the variable with the specified key, or null if the key is not found.
* You can then access the variable's value using the Value property. e.g.

2
Assets/Fungus/Narrative/Scripts/Commands/Say.cs

@ -99,7 +99,7 @@ namespace Fungus
string subbedText = flowchart.SubstituteVariables(displayText);
sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeWhenDone, voiceOverClip, stopVoiceover, delegate {
sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeWhenDone, stopVoiceover, voiceOverClip, delegate {
Continue();
});
}

10
Assets/Fungus/Narrative/Scripts/MenuDialog.cs

@ -13,8 +13,11 @@ namespace Fungus
// Currently active Menu Dialog used to display Menu options
public static MenuDialog activeMenuDialog;
protected Button[] cachedButtons;
protected Slider cachedSlider;
[NonSerialized]
public Button[] cachedButtons;
[NonSerialized]
public Slider cachedSlider;
public static MenuDialog GetMenuDialog()
{
@ -139,7 +142,7 @@ namespace Fungus
return addedOption;
}
protected virtual void HideSayDialog()
public virtual void HideSayDialog()
{
SayDialog sayDialog = SayDialog.GetSayDialog();
if (sayDialog != null)
@ -150,7 +153,6 @@ namespace Fungus
public virtual void ShowTimer(float duration, Block targetBlock)
{
if (cachedSlider != null)
{
cachedSlider.gameObject.SetActive(true);

10
Assets/Fungus/Narrative/Scripts/SayDialog.cs

@ -126,12 +126,12 @@ namespace Fungus
}
}
public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, bool stopVoiceover, Action onComplete)
public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, bool stopVoiceover, AudioClip voiceOverClip, Action onComplete)
{
StartCoroutine(SayInternal(text, clearPrevious, waitForInput, fadeWhenDone, voiceOverClip, stopVoiceover, onComplete));
StartCoroutine(SayInternal(text, clearPrevious, waitForInput, fadeWhenDone, stopVoiceover, voiceOverClip, onComplete));
}
protected virtual IEnumerator SayInternal(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, bool stopVoiceover, Action onComplete)
public virtual IEnumerator SayInternal(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, bool stopVoiceover, AudioClip voiceOverClip, Action onComplete)
{
Writer writer = GetWriter();
@ -144,6 +144,8 @@ namespace Fungus
}
}
gameObject.SetActive(true);
this.fadeWhenDone = fadeWhenDone;
// Voice over clip takes precedence over a character sound effect if provided
@ -158,8 +160,8 @@ namespace Fungus
{
soundEffectClip = speakingCharacter.soundEffect;
}
writer.Write(text, clearPrevious, waitForInput, stopVoiceover, soundEffectClip, onComplete);
yield return writer.Write(text, clearPrevious, waitForInput, stopVoiceover, soundEffectClip, onComplete);
}
protected virtual void LateUpdate()

414
Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs vendored

@ -5,215 +5,215 @@ using System.Text;
namespace Ideafixxxer.CsvParser
{
public class CsvParser
{
private const char CommaCharacter = ',';
private const char QuoteCharacter = '"';
#region Nested types
private abstract class ParserState
{
public static readonly LineStartState LineStartState = new LineStartState();
public static readonly ValueStartState ValueStartState = new ValueStartState();
public static readonly ValueState ValueState = new ValueState();
public static readonly QuotedValueState QuotedValueState = new QuotedValueState();
public static readonly QuoteState QuoteState = new QuoteState();
public abstract ParserState AnyChar(char ch, ParserContext context);
public abstract ParserState Comma(ParserContext context);
public abstract ParserState Quote(ParserContext context);
public abstract ParserState EndOfLine(ParserContext context);
}
private class LineStartState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return ValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
return QuotedValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddLine();
return LineStartState;
}
}
private class ValueStartState : LineStartState
{
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class ValueState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return ValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
context.AddChar(QuoteCharacter);
return ValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class QuotedValueState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return QuotedValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddChar(CommaCharacter);
return QuotedValueState;
}
public override ParserState Quote(ParserContext context)
{
return QuoteState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddChar('\r');
context.AddChar('\n');
return QuotedValueState;
}
}
private class QuoteState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
//undefined, ignore "
context.AddChar(ch);
return QuotedValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
context.AddChar(QuoteCharacter);
return QuotedValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class ParserContext
{
private readonly StringBuilder _currentValue = new StringBuilder();
private readonly List<string[]> _lines = new List<string[]>();
private readonly List<string> _currentLine = new List<string>();
public void AddChar(char ch)
{
_currentValue.Append(ch);
}
public void AddValue()
{
_currentLine.Add(_currentValue.ToString());
_currentValue.Remove(0, _currentValue.Length);
}
public void AddLine()
{
_lines.Add(_currentLine.ToArray());
_currentLine.Clear();
}
public List<string[]> GetAllLines()
{
if (_currentValue.Length > 0)
{
AddValue();
}
if (_currentLine.Count > 0)
{
AddLine();
}
return _lines;
}
}
#endregion
public string[][] Parse(string csvData)
{
var context = new ParserContext();
public class CsvParser
{
private const char CommaCharacter = ',';
private const char QuoteCharacter = '"';
#region Nested types
private abstract class ParserState
{
public static readonly LineStartState LineStartState = new LineStartState();
public static readonly ValueStartState ValueStartState = new ValueStartState();
public static readonly ValueState ValueState = new ValueState();
public static readonly QuotedValueState QuotedValueState = new QuotedValueState();
public static readonly QuoteState QuoteState = new QuoteState();
public abstract ParserState AnyChar(char ch, ParserContext context);
public abstract ParserState Comma(ParserContext context);
public abstract ParserState Quote(ParserContext context);
public abstract ParserState EndOfLine(ParserContext context);
}
private class LineStartState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return ValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
return QuotedValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddLine();
return LineStartState;
}
}
private class ValueStartState : LineStartState
{
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class ValueState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return ValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
context.AddChar(QuoteCharacter);
return ValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class QuotedValueState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
context.AddChar(ch);
return QuotedValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddChar(CommaCharacter);
return QuotedValueState;
}
public override ParserState Quote(ParserContext context)
{
return QuoteState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddChar('\r');
context.AddChar('\n');
return QuotedValueState;
}
}
private class QuoteState : ParserState
{
public override ParserState AnyChar(char ch, ParserContext context)
{
//undefined, ignore "
context.AddChar(ch);
return QuotedValueState;
}
public override ParserState Comma(ParserContext context)
{
context.AddValue();
return ValueStartState;
}
public override ParserState Quote(ParserContext context)
{
context.AddChar(QuoteCharacter);
return QuotedValueState;
}
public override ParserState EndOfLine(ParserContext context)
{
context.AddValue();
context.AddLine();
return LineStartState;
}
}
private class ParserContext
{
private readonly StringBuilder _currentValue = new StringBuilder();
private readonly List<string[]> _lines = new List<string[]>();
private readonly List<string> _currentLine = new List<string>();
public void AddChar(char ch)
{
_currentValue.Append(ch);
}
public void AddValue()
{
_currentLine.Add(_currentValue.ToString());
_currentValue.Remove(0, _currentValue.Length);
}
public void AddLine()
{
_lines.Add(_currentLine.ToArray());
_currentLine.Clear();
}
public List<string[]> GetAllLines()
{
if (_currentValue.Length > 0)
{
AddValue();
}
if (_currentLine.Count > 0)
{
AddLine();
}
return _lines;
}
}
#endregion
public string[][] Parse(string csvData)
{
var context = new ParserContext();
// Handle both Windows and Mac line endings
string[] lines = csvData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
ParserState currentState = ParserState.LineStartState;
foreach (string next in lines)
{
foreach (char ch in next)
{
switch (ch)
{
case CommaCharacter:
currentState = currentState.Comma(context);
break;
case QuoteCharacter:
currentState = currentState.Quote(context);
break;
default:
currentState = currentState.AnyChar(ch, context);
break;
}
}
currentState = currentState.EndOfLine(context);
}
List<string[]> allLines = context.GetAllLines();
return allLines.ToArray();
}
}
ParserState currentState = ParserState.LineStartState;
foreach (string next in lines)
{
foreach (char ch in next)
{
switch (ch)
{
case CommaCharacter:
currentState = currentState.Comma(context);
break;
case QuoteCharacter:
currentState = currentState.Quote(context);
break;
default:
currentState = currentState.AnyChar(ch, context);
break;
}
}
currentState = currentState.EndOfLine(context);
}
List<string[]> allLines = context.GetAllLines();
return allLines.ToArray();
}
}
}

6
Assets/Fungus/UI/Scripts/Commands/Write.cs

@ -86,14 +86,14 @@ namespace Fungus
if (!waitUntilFinished)
{
writer.Write(newText, clearText, false, true, null, null);
StartCoroutine(writer.Write(newText, clearText, false, true, null, null));
Continue();
}
else
{
writer.Write(newText, clearText, false, true, null,
StartCoroutine(writer.Write(newText, clearText, false, true, null,
() => { Continue (); }
);
));
}
}

8
Assets/Fungus/UI/Scripts/Writer.cs

@ -317,7 +317,7 @@ namespace Fungus
}
}
public virtual void Write(string content, bool clear, bool waitForInput, bool stopAudio, AudioClip audioClip, Action onComplete)
public virtual IEnumerator Write(string content, bool clear, bool waitForInput, bool stopAudio, AudioClip audioClip, Action onComplete)
{
if (clear)
{
@ -326,7 +326,7 @@ namespace Fungus
if (!HasTextObject())
{
return;
yield break;
}
// If this clip is null then WriterAudio will play the default sound effect (if any)
@ -341,7 +341,9 @@ namespace Fungus
TextTagParser tagParser = new TextTagParser();
List<TextTagParser.Token> tokens = tagParser.Tokenize(tokenText);
StartCoroutine(ProcessTokens(tokens, stopAudio, onComplete));
gameObject.SetActive(true);
yield return StartCoroutine(ProcessTokens(tokens, stopAudio, onComplete));
}
virtual protected bool CheckParamCount(List<string> paramList, int count)

72
Assets/Tests/Scripting/Scripting.unity

@ -196,7 +196,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -209,8 +209,7 @@ MonoBehaviour:
width: 1114
height: 859
selectedBlock: {fileID: 115525222}
selectedCommands:
- {fileID: 115525219}
selectedCommands: []
variables: []
description:
stepPause: 0
@ -279,7 +278,10 @@ MonoBehaviour:
itemId: 1
errorMessage:
indentLevel: 0
duration: 3
_duration:
floatRef: {fileID: 0}
floatVal: 3
durationOLD: 0
--- !u!114 &169310213
MonoBehaviour:
m_ObjectHideFlags: 2
@ -330,7 +332,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -433,7 +435,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -967,7 +969,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -1073,7 +1075,10 @@ MonoBehaviour:
itemId: 3
errorMessage:
indentLevel: 0
duration: 1
_duration:
floatRef: {fileID: 0}
floatVal: 1
durationOLD: 0
--- !u!114 &575910003
MonoBehaviour:
m_ObjectHideFlags: 2
@ -1134,6 +1139,7 @@ MonoBehaviour:
extendPrevious: 0
fadeWhenDone: 1
waitForClick: 1
stopVoiceover: 1
setSayDialog: {fileID: 0}
--- !u!114 &575910006
MonoBehaviour:
@ -1185,7 +1191,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -1310,7 +1316,10 @@ MonoBehaviour:
itemId: 3
errorMessage:
indentLevel: 0
duration: 1
_duration:
floatRef: {fileID: 0}
floatVal: 1
durationOLD: 0
--- !u!114 &590474777
MonoBehaviour:
m_ObjectHideFlags: 2
@ -1398,7 +1407,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -1530,7 +1539,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -1595,7 +1604,10 @@ MonoBehaviour:
itemId: 3
errorMessage:
indentLevel: 0
duration: 1
_duration:
floatRef: {fileID: 0}
floatVal: 1
durationOLD: 0
--- !u!114 &636123612
MonoBehaviour:
m_ObjectHideFlags: 2
@ -1708,7 +1720,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 61dddfdc5e0e44ca298d8f46f7f5a915, type: 3}
m_Name:
m_EditorClassIdentifier:
selectedFlowchart: {fileID: 115525223}
selectedFlowchart: {fileID: 1618689129}
--- !u!4 &646902075
Transform:
m_ObjectHideFlags: 1
@ -1736,7 +1748,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!114 &676156675
MonoBehaviour:
m_ObjectHideFlags: 0
@ -2320,7 +2332,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
@ -2334,7 +2346,7 @@ MonoBehaviour:
height: 873
selectedBlock: {fileID: 1618689131}
selectedCommands:
- {fileID: 1618689152}
- {fileID: 1618689150}
variables:
- {fileID: 1618689138}
- {fileID: 1618689141}
@ -2719,7 +2731,7 @@ MonoBehaviour:
callMode: 0
--- !u!114 &1618689140
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -2858,7 +2870,7 @@ MonoBehaviour:
callMode: 0
--- !u!114 &1618689147
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -2884,7 +2896,7 @@ MonoBehaviour:
- {fileID: 1618689148}
--- !u!114 &1618689148
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -2948,7 +2960,7 @@ MonoBehaviour:
Culture=neutral, PublicKeyToken=null
--- !u!114 &1618689149
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -2975,7 +2987,7 @@ MonoBehaviour:
callMode: 0
--- !u!114 &1618689150
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -2993,7 +3005,7 @@ MonoBehaviour:
targetComponentFullname: UnityEngine.Component[]
targetComponentText: Flowchart
targetMethod: ExecuteBlock
targetMethodText: 'ExecuteBlock (String): Void'
targetMethodText: 'ExecuteBlock (String): Boolean'
methodParameters:
- objValue:
typeAssemblyname: System.String, mscorlib, Version=2.0.0.0, Culture=neutral,
@ -3014,12 +3026,12 @@ MonoBehaviour:
variableKey:
saveReturnValue: 0
returnValueVariableKey:
returnValueType: System.Void
returnValueType: System.Boolean
showInherited: 0
callMode: 0
--- !u!114 &1618689151
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -3031,10 +3043,13 @@ MonoBehaviour:
itemId: 16
errorMessage:
indentLevel: 0
duration: 1
_duration:
floatRef: {fileID: 0}
floatVal: 1
durationOLD: 0
--- !u!114 &1618689152
MonoBehaviour:
m_ObjectHideFlags: 0
m_ObjectHideFlags: 2
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1618689128}
@ -3314,6 +3329,7 @@ Canvas:
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
@ -3438,7 +3454,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 1.0
version: 1
scrollPos: {x: 0, y: 0}
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1

Loading…
Cancel
Save