From a1e3d4f587554e81d6983396e9061df8d34935e8 Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Wed, 12 Nov 2014 10:22:40 +0000 Subject: [PATCH] Sequences may now be executed in parallel All executing sequences are shown in blue in the Fungus Script window. A Sequence may not be executed until any previous execution has finished. If a selected sequence is deleted, selection reverts back to the Fungus Script object. --- .../FungusScript/Editor/FungusScriptEditor.cs | 14 --- .../FungusScript/Editor/FungusScriptWindow.cs | 88 ++++++++----------- .../FungusScript/Editor/SequenceEditor.cs | 4 +- .../FungusScript/Editor/SequenceInspector.cs | 16 ++-- .../Editor/VariableListAdaptor.cs | 39 +++----- Assets/Fungus/FungusScript/Scripts/Command.cs | 13 ++- .../FungusScript/Scripts/FungusScript.cs | 29 +++--- .../Fungus/FungusScript/Scripts/Sequence.cs | 10 +-- 8 files changed, 88 insertions(+), 125 deletions(-) diff --git a/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs b/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs index 249c0e33..978ec406 100644 --- a/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs @@ -31,20 +31,6 @@ namespace Fungus fungusScript.UpdateHideFlags(); - if (Application.isPlaying) - { - if (fungusScript.executingSequence == null) - { - fungusScript.ClearSelectedCommands(); - } - else - { - fungusScript.ClearSelectedCommands(); - fungusScript.AddSelectedCommand(fungusScript.executingSequence.activeCommand); - EditorUtility.SetDirty(fungusScript); - } - } - SequenceEditor.SequenceField(startSequenceProp, new GUIContent("Start Sequence", "First sequence to execute when the Fungus Script executes"), new GUIContent(""), diff --git a/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs b/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs index ba80254f..6b7dbe3f 100755 --- a/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs +++ b/Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs @@ -18,13 +18,11 @@ namespace Fungus // so we just implement dragging ourselves. protected int dragWindowId = -1; protected Vector2 startDragPosition; - protected Sequence selectedSequence; protected const float minZoomValue = 0.25f; protected const float maxZoomValue = 1f; protected static SequenceInspector sequenceInspector; - protected bool followExecution = true; [MenuItem("Window/Fungus Script")] static void Init() @@ -32,13 +30,19 @@ namespace Fungus GetWindow(typeof(FungusScriptWindow), false, "Fungus Script"); } - public virtual void OnEnable() - { - followExecution = true; - } - protected void OnInspectorUpdate() { + // Ensure the Sequence Inspector is always showing the currently selected sequence + FungusScript fungusScript = GetFungusScript(); + if (fungusScript.selectedSequence != null) + { + if (sequenceInspector == null) + { + ShowSequenceInspector(fungusScript); + } + sequenceInspector.sequence = fungusScript.selectedSequence; + } + Repaint(); } @@ -78,38 +82,27 @@ namespace Fungus // Delete any scheduled objects foreach (Sequence deleteSequence in deleteList) { + bool isSelected = (fungusScript.selectedSequence == deleteSequence); + foreach (Command command in deleteSequence.commandList) { Undo.DestroyObjectImmediate(command); } Undo.DestroyObjectImmediate(deleteSequence); - SetSelectedSequence(fungusScript, null); fungusScript.ClearSelectedCommands(); + + if (isSelected) + { + // Revert to showing properties for the Fungus Script + Selection.activeGameObject = fungusScript.gameObject; + } } deleteList.Clear(); DrawScriptView(fungusScript); DrawOverlay(fungusScript); - if (Application.isPlaying && - fungusScript.executingSequence != null && - followExecution) - { - // Set SequenceInspector object as the selected object - if (Selection.activeGameObject == fungusScript.gameObject || - Selection.activeGameObject == sequenceInspector) - { - SetSelectedSequence(fungusScript, fungusScript.executingSequence); - } - - // Make sure SequenceInspector is using the currently executing sequence - if (sequenceInspector != null) - { - sequenceInspector.sequence = fungusScript.executingSequence; - } - } - // Redraw on next frame to get crisp refresh rate Repaint(); } @@ -188,14 +181,12 @@ namespace Fungus if (Event.current.button == 0 && Event.current.type == EventType.MouseDown) { - selectedSequence = fungusScript.selectedSequence; - SetSelectedSequence(fungusScript, null); + fungusScript.selectedSequence = null; if (!EditorGUI.actionKey) { fungusScript.ClearSelectedCommands(); } Selection.activeGameObject = fungusScript.gameObject; - followExecution = false; } // Draw connections @@ -223,8 +214,7 @@ namespace Fungus // Hack to support legacy design where sequences were child gameobjects (will be removed soon) sequence.UpdateSequenceName(); - float nodeWidth = nodeStyle.CalcSize(new GUIContent(sequence.sequenceName)).x; - + float nodeWidth = nodeStyle.CalcSize(new GUIContent(sequence.sequenceName)).x + 10; sequence.nodeRect.width = Mathf.Max(120, nodeWidth); sequence.nodeRect.height = 30; @@ -321,7 +311,8 @@ namespace Fungus { Sequence newSequence = fungusScript.CreateSequence(position); Undo.RegisterCreatedObjectUndo(newSequence, "New Sequence"); - SetSelectedSequence(fungusScript, newSequence); + ShowSequenceInspector(fungusScript); + fungusScript.selectedSequence = newSequence; fungusScript.ClearSelectedCommands(); return newSequence; @@ -335,7 +326,6 @@ namespace Fungus } Undo.DestroyObjectImmediate(sequence); - SetSelectedSequence(fungusScript, null); fungusScript.ClearSelectedCommands(); } @@ -349,8 +339,7 @@ namespace Fungus Event.current.type == EventType.MouseDown) { // Check if might be start of a window drag - if (Event.current.button == 0 && - Event.current.mousePosition.y < 26) + if (Event.current.button == 0) { dragWindowId = windowId; startDragPosition.x = sequence.nodeRect.x; @@ -361,24 +350,24 @@ namespace Fungus { Undo.RecordObject(fungusScript, "Select"); - SetSelectedSequence(fungusScript, sequence); - GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) + ShowSequenceInspector(fungusScript); + fungusScript.selectedSequence = sequence; - if (Application.isPlaying) - { - // If user selected a non-executing sequence then stop following execution - followExecution = (fungusScript.selectedSequence == fungusScript.executingSequence); - } + GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) } } GUIStyle nodeStyle = null; - if (fungusScript.selectedSequence == sequence || - fungusScript.executingSequence == sequence) + if (fungusScript.selectedSequence == sequence) { // Green node nodeStyle = new GUIStyle("flow node 3"); } + else if (sequence.IsExecuting()) + { + // Blue node + nodeStyle = new GUIStyle("flow node 2"); + } else { // Yellow node @@ -540,10 +529,8 @@ namespace Fungus } } - protected static void SetSelectedSequence(FungusScript fungusScript, Sequence sequence) + protected static void ShowSequenceInspector(FungusScript fungusScript) { - fungusScript.selectedSequence = sequence; - if (sequenceInspector == null) { // Create a Scriptable Object with a custom editor which we can use to inspect the selected sequence. @@ -552,12 +539,7 @@ namespace Fungus sequenceInspector.hideFlags = HideFlags.DontSave; } - sequenceInspector.sequence = sequence; - - if (sequence != null) - { - Selection.activeObject = sequenceInspector; - } + Selection.activeObject = sequenceInspector; EditorUtility.SetDirty(sequenceInspector); } diff --git a/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs b/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs index ea55af5b..5d78455e 100644 --- a/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs +++ b/Assets/Fungus/FungusScript/Editor/SequenceEditor.cs @@ -27,9 +27,9 @@ namespace Fungus UpdateIndentLevels(sequence); SerializedProperty sequenceNameProperty = serializedObject.FindProperty("sequenceName"); - Rect sequenceLabelRect = new Rect(40, 5, 120, 16); + Rect sequenceLabelRect = new Rect(45, 5, 120, 16); EditorGUI.LabelField(sequenceLabelRect, new GUIContent("Sequence Name")); - Rect sequenceNameRect = new Rect(40, 21, 180, 16); + Rect sequenceNameRect = new Rect(45, 21, 180, 16); EditorGUI.PropertyField(sequenceNameRect, sequenceNameProperty, new GUIContent("")); SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); diff --git a/Assets/Fungus/FungusScript/Editor/SequenceInspector.cs b/Assets/Fungus/FungusScript/Editor/SequenceInspector.cs index 351843ac..b41f7793 100644 --- a/Assets/Fungus/FungusScript/Editor/SequenceInspector.cs +++ b/Assets/Fungus/FungusScript/Editor/SequenceInspector.cs @@ -21,26 +21,26 @@ namespace Fungus { public override void OnInspectorGUI () { - SequenceInspector t = target as SequenceInspector; - Sequence s = t.sequence; + SequenceInspector sequenceInspector = target as SequenceInspector; + Sequence sequence = sequenceInspector.sequence; - if (s == null) + if (sequence == null) { return; } - FungusScript fungusScript = s.GetFungusScript(); + FungusScript fungusScript = sequence.GetFungusScript(); - SequenceEditor sequenceEditor = Editor.CreateEditor(s) as SequenceEditor; + SequenceEditor sequenceEditor = Editor.CreateEditor(sequence) as SequenceEditor; sequenceEditor.DrawCommandListGUI(fungusScript); DestroyImmediate(sequenceEditor); Command inspectCommand = null; if (Application.isPlaying && - fungusScript.executingSequence != null) + sequence.activeCommand != null) { - inspectCommand = fungusScript.executingSequence.activeCommand; + inspectCommand = sequence.activeCommand; } else if (fungusScript.selectedCommands.Count == 1) { @@ -49,7 +49,7 @@ namespace Fungus if (Application.isPlaying && inspectCommand != null && - inspectCommand.parentSequence != s) + inspectCommand.parentSequence != sequence) { Repaint(); return; diff --git a/Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs b/Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs index 2dd4d30a..8bc6de96 100644 --- a/Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs +++ b/Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs @@ -129,47 +129,28 @@ namespace Fungus { return; } - + + // Highlight if an active or selected command is referencing this variable bool highlight = false; - - // Is an executing command referencing this variable? - if (Application.isPlaying) + if (fungusScript.selectedSequence != null) { - if (fungusScript.executingSequence != null && - fungusScript.executingSequence.activeCommand != null) + if (Application.isPlaying && fungusScript.selectedSequence.IsExecuting()) { - if (fungusScript.executingSequence.activeCommand.HasReference(variable)) - { - highlight = true; - } + highlight = fungusScript.selectedSequence.activeCommand.HasReference(variable); } - } - else - { - // Is an expanded command referencing this variable? - if (fungusScript.selectedSequence != null && - fungusScript.selectedCommands.Count > 0) + else if (!Application.isPlaying && fungusScript.selectedCommands.Count > 0) { - foreach (Command command in fungusScript.selectedSequence.commandList) + foreach (Command selectedCommand in fungusScript.selectedCommands) { - foreach (Command selectedCommand in fungusScript.selectedCommands) - { - if (selectedCommand == command && - command.HasReference(variable)) - { - highlight = true; - break; - } - } - - if (highlight) + if (selectedCommand.HasReference(variable)) { + highlight = true; break; } } } } - + if (highlight) { GUI.backgroundColor = Color.green; diff --git a/Assets/Fungus/FungusScript/Scripts/Command.cs b/Assets/Fungus/FungusScript/Scripts/Command.cs index 117b7e3f..269a1965 100644 --- a/Assets/Fungus/FungusScript/Scripts/Command.cs +++ b/Assets/Fungus/FungusScript/Scripts/Command.cs @@ -91,10 +91,21 @@ namespace Fungus OnExit(); if (parentSequence != null) { - parentSequence.Stop(); FungusScript fungusScript = parentSequence.GetFungusScript(); + + // Record the currently selected sequence because Stop() will clear it. + Sequence selectedSequence = fungusScript.selectedSequence; + + parentSequence.Stop(); if (fungusScript != null) { + // If the executing sequence is currently selected then follow the execution + // onto the next sequence in the inspector. + if (selectedSequence == parentSequence) + { + fungusScript.selectedSequence = s; + } + fungusScript.ExecuteSequence(s); } } diff --git a/Assets/Fungus/FungusScript/Scripts/FungusScript.cs b/Assets/Fungus/FungusScript/Scripts/FungusScript.cs index ed409a24..9ab7533b 100644 --- a/Assets/Fungus/FungusScript/Scripts/FungusScript.cs +++ b/Assets/Fungus/FungusScript/Scripts/FungusScript.cs @@ -13,12 +13,6 @@ namespace Fungus */ public class FungusScript : MonoBehaviour { - /** - * Currently executing sequence. - */ - [System.NonSerialized] - public Sequence executingSequence; - /** * Scroll position of Fungus Script editor window. */ @@ -147,24 +141,37 @@ namespace Fungus return; } + // Show start sequence by default + selectedSequence = startSequence; + ExecuteSequence(startSequence); } /** * Start running the Fungus Script by executing a specific child sequence. + * The sequence must be in an idle state to be executed. + * Returns true if the Sequence started execution. */ - public virtual void ExecuteSequence(Sequence sequence) + public virtual bool ExecuteSequence(Sequence sequence) { // Sequence must be a child of the parent Fungus Script if (sequence == null || - sequence.transform.parent != transform && sequence.transform != transform) + sequence.transform.parent != transform && + sequence.transform != transform) { - return; + return false; } - executingSequence = sequence; - selectedSequence = sequence; + // Can't restart a running sequence, have to wait until it's idle again + if (sequence.IsExecuting()) + { + return false; + } + + // Execute the first command in the command list sequence.ExecuteNextCommand(); + + return true; } /** diff --git a/Assets/Fungus/FungusScript/Scripts/Sequence.cs b/Assets/Fungus/FungusScript/Scripts/Sequence.cs index 41ba588d..98140818 100644 --- a/Assets/Fungus/FungusScript/Scripts/Sequence.cs +++ b/Assets/Fungus/FungusScript/Scripts/Sequence.cs @@ -56,17 +56,15 @@ namespace Fungus return false; } - public virtual bool IsRunning() + public virtual bool IsExecuting() { FungusScript fungusScript = GetFungusScript(); - - if (fungusScript == null || - fungusScript.executingSequence == null) + if (fungusScript == null) { return false; } - return (fungusScript.executingSequence == this); + return (activeCommand != null); } public virtual int GetExecutionCount() @@ -138,8 +136,6 @@ namespace Fungus } activeCommand = null; - fungusScript.executingSequence = null; - fungusScript.selectedSequence = null; fungusScript.ClearSelectedCommands(); }