Browse Source

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.
master
chrisgregan 10 years ago
parent
commit
a1e3d4f587
  1. 14
      Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs
  2. 84
      Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs
  3. 4
      Assets/Fungus/FungusScript/Editor/SequenceEditor.cs
  4. 16
      Assets/Fungus/FungusScript/Editor/SequenceInspector.cs
  5. 31
      Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs
  6. 13
      Assets/Fungus/FungusScript/Scripts/Command.cs
  7. 29
      Assets/Fungus/FungusScript/Scripts/FungusScript.cs
  8. 10
      Assets/Fungus/FungusScript/Scripts/Sequence.cs

14
Assets/Fungus/FungusScript/Editor/FungusScriptEditor.cs

@ -31,20 +31,6 @@ namespace Fungus
fungusScript.UpdateHideFlags(); 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, SequenceEditor.SequenceField(startSequenceProp,
new GUIContent("Start Sequence", "First sequence to execute when the Fungus Script executes"), new GUIContent("Start Sequence", "First sequence to execute when the Fungus Script executes"),
new GUIContent("<None>"), new GUIContent("<None>"),

84
Assets/Fungus/FungusScript/Editor/FungusScriptWindow.cs

@ -18,13 +18,11 @@ namespace Fungus
// so we just implement dragging ourselves. // so we just implement dragging ourselves.
protected int dragWindowId = -1; protected int dragWindowId = -1;
protected Vector2 startDragPosition; protected Vector2 startDragPosition;
protected Sequence selectedSequence;
protected const float minZoomValue = 0.25f; protected const float minZoomValue = 0.25f;
protected const float maxZoomValue = 1f; protected const float maxZoomValue = 1f;
protected static SequenceInspector sequenceInspector; protected static SequenceInspector sequenceInspector;
protected bool followExecution = true;
[MenuItem("Window/Fungus Script")] [MenuItem("Window/Fungus Script")]
static void Init() static void Init()
@ -32,13 +30,19 @@ namespace Fungus
GetWindow(typeof(FungusScriptWindow), false, "Fungus Script"); GetWindow(typeof(FungusScriptWindow), false, "Fungus Script");
} }
public virtual void OnEnable() protected void OnInspectorUpdate()
{
// Ensure the Sequence Inspector is always showing the currently selected sequence
FungusScript fungusScript = GetFungusScript();
if (fungusScript.selectedSequence != null)
{
if (sequenceInspector == null)
{ {
followExecution = true; ShowSequenceInspector(fungusScript);
}
sequenceInspector.sequence = fungusScript.selectedSequence;
} }
protected void OnInspectorUpdate()
{
Repaint(); Repaint();
} }
@ -78,38 +82,27 @@ namespace Fungus
// Delete any scheduled objects // Delete any scheduled objects
foreach (Sequence deleteSequence in deleteList) foreach (Sequence deleteSequence in deleteList)
{ {
bool isSelected = (fungusScript.selectedSequence == deleteSequence);
foreach (Command command in deleteSequence.commandList) foreach (Command command in deleteSequence.commandList)
{ {
Undo.DestroyObjectImmediate(command); Undo.DestroyObjectImmediate(command);
} }
Undo.DestroyObjectImmediate(deleteSequence); Undo.DestroyObjectImmediate(deleteSequence);
SetSelectedSequence(fungusScript, null);
fungusScript.ClearSelectedCommands(); fungusScript.ClearSelectedCommands();
if (isSelected)
{
// Revert to showing properties for the Fungus Script
Selection.activeGameObject = fungusScript.gameObject;
}
} }
deleteList.Clear(); deleteList.Clear();
DrawScriptView(fungusScript); DrawScriptView(fungusScript);
DrawOverlay(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 // Redraw on next frame to get crisp refresh rate
Repaint(); Repaint();
} }
@ -188,14 +181,12 @@ namespace Fungus
if (Event.current.button == 0 && if (Event.current.button == 0 &&
Event.current.type == EventType.MouseDown) Event.current.type == EventType.MouseDown)
{ {
selectedSequence = fungusScript.selectedSequence; fungusScript.selectedSequence = null;
SetSelectedSequence(fungusScript, null);
if (!EditorGUI.actionKey) if (!EditorGUI.actionKey)
{ {
fungusScript.ClearSelectedCommands(); fungusScript.ClearSelectedCommands();
} }
Selection.activeGameObject = fungusScript.gameObject; Selection.activeGameObject = fungusScript.gameObject;
followExecution = false;
} }
// Draw connections // Draw connections
@ -223,8 +214,7 @@ namespace Fungus
// Hack to support legacy design where sequences were child gameobjects (will be removed soon) // Hack to support legacy design where sequences were child gameobjects (will be removed soon)
sequence.UpdateSequenceName(); 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.width = Mathf.Max(120, nodeWidth);
sequence.nodeRect.height = 30; sequence.nodeRect.height = 30;
@ -321,7 +311,8 @@ namespace Fungus
{ {
Sequence newSequence = fungusScript.CreateSequence(position); Sequence newSequence = fungusScript.CreateSequence(position);
Undo.RegisterCreatedObjectUndo(newSequence, "New Sequence"); Undo.RegisterCreatedObjectUndo(newSequence, "New Sequence");
SetSelectedSequence(fungusScript, newSequence); ShowSequenceInspector(fungusScript);
fungusScript.selectedSequence = newSequence;
fungusScript.ClearSelectedCommands(); fungusScript.ClearSelectedCommands();
return newSequence; return newSequence;
@ -335,7 +326,6 @@ namespace Fungus
} }
Undo.DestroyObjectImmediate(sequence); Undo.DestroyObjectImmediate(sequence);
SetSelectedSequence(fungusScript, null);
fungusScript.ClearSelectedCommands(); fungusScript.ClearSelectedCommands();
} }
@ -349,8 +339,7 @@ namespace Fungus
Event.current.type == EventType.MouseDown) Event.current.type == EventType.MouseDown)
{ {
// Check if might be start of a window drag // Check if might be start of a window drag
if (Event.current.button == 0 && if (Event.current.button == 0)
Event.current.mousePosition.y < 26)
{ {
dragWindowId = windowId; dragWindowId = windowId;
startDragPosition.x = sequence.nodeRect.x; startDragPosition.x = sequence.nodeRect.x;
@ -361,24 +350,24 @@ namespace Fungus
{ {
Undo.RecordObject(fungusScript, "Select"); Undo.RecordObject(fungusScript, "Select");
SetSelectedSequence(fungusScript, sequence); ShowSequenceInspector(fungusScript);
GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus) fungusScript.selectedSequence = sequence;
if (Application.isPlaying) GUIUtility.keyboardControl = 0; // Fix for textarea not refeshing (change focus)
{
// If user selected a non-executing sequence then stop following execution
followExecution = (fungusScript.selectedSequence == fungusScript.executingSequence);
}
} }
} }
GUIStyle nodeStyle = null; GUIStyle nodeStyle = null;
if (fungusScript.selectedSequence == sequence || if (fungusScript.selectedSequence == sequence)
fungusScript.executingSequence == sequence)
{ {
// Green node // Green node
nodeStyle = new GUIStyle("flow node 3"); nodeStyle = new GUIStyle("flow node 3");
} }
else if (sequence.IsExecuting())
{
// Blue node
nodeStyle = new GUIStyle("flow node 2");
}
else else
{ {
// Yellow node // 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) if (sequenceInspector == null)
{ {
// Create a Scriptable Object with a custom editor which we can use to inspect the selected sequence. // 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.hideFlags = HideFlags.DontSave;
} }
sequenceInspector.sequence = sequence;
if (sequence != null)
{
Selection.activeObject = sequenceInspector; Selection.activeObject = sequenceInspector;
}
EditorUtility.SetDirty(sequenceInspector); EditorUtility.SetDirty(sequenceInspector);
} }

4
Assets/Fungus/FungusScript/Editor/SequenceEditor.cs

@ -27,9 +27,9 @@ namespace Fungus
UpdateIndentLevels(sequence); UpdateIndentLevels(sequence);
SerializedProperty sequenceNameProperty = serializedObject.FindProperty("sequenceName"); 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")); 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("")); EditorGUI.PropertyField(sequenceNameRect, sequenceNameProperty, new GUIContent(""));
SerializedProperty commandListProperty = serializedObject.FindProperty("commandList"); SerializedProperty commandListProperty = serializedObject.FindProperty("commandList");

16
Assets/Fungus/FungusScript/Editor/SequenceInspector.cs

@ -21,26 +21,26 @@ namespace Fungus
{ {
public override void OnInspectorGUI () public override void OnInspectorGUI ()
{ {
SequenceInspector t = target as SequenceInspector; SequenceInspector sequenceInspector = target as SequenceInspector;
Sequence s = t.sequence; Sequence sequence = sequenceInspector.sequence;
if (s == null) if (sequence == null)
{ {
return; 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); sequenceEditor.DrawCommandListGUI(fungusScript);
DestroyImmediate(sequenceEditor); DestroyImmediate(sequenceEditor);
Command inspectCommand = null; Command inspectCommand = null;
if (Application.isPlaying && if (Application.isPlaying &&
fungusScript.executingSequence != null) sequence.activeCommand != null)
{ {
inspectCommand = fungusScript.executingSequence.activeCommand; inspectCommand = sequence.activeCommand;
} }
else if (fungusScript.selectedCommands.Count == 1) else if (fungusScript.selectedCommands.Count == 1)
{ {
@ -49,7 +49,7 @@ namespace Fungus
if (Application.isPlaying && if (Application.isPlaying &&
inspectCommand != null && inspectCommand != null &&
inspectCommand.parentSequence != s) inspectCommand.parentSequence != sequence)
{ {
Repaint(); Repaint();
return; return;

31
Assets/Fungus/FungusScript/Editor/VariableListAdaptor.cs

@ -130,43 +130,24 @@ namespace Fungus
return; return;
} }
// Highlight if an active or selected command is referencing this variable
bool highlight = false; bool highlight = false;
if (fungusScript.selectedSequence != null)
// Is an executing command referencing this variable?
if (Application.isPlaying)
{ {
if (fungusScript.executingSequence != null && if (Application.isPlaying && fungusScript.selectedSequence.IsExecuting())
fungusScript.executingSequence.activeCommand != null)
{ {
if (fungusScript.executingSequence.activeCommand.HasReference(variable)) highlight = fungusScript.selectedSequence.activeCommand.HasReference(variable);
{
highlight = true;
} }
} else if (!Application.isPlaying && fungusScript.selectedCommands.Count > 0)
}
else
{
// Is an expanded command referencing this variable?
if (fungusScript.selectedSequence != null &&
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 && if (selectedCommand.HasReference(variable))
command.HasReference(variable))
{ {
highlight = true; highlight = true;
break; break;
} }
} }
if (highlight)
{
break;
}
}
} }
} }

13
Assets/Fungus/FungusScript/Scripts/Command.cs

@ -91,10 +91,21 @@ namespace Fungus
OnExit(); OnExit();
if (parentSequence != null) if (parentSequence != null)
{ {
parentSequence.Stop();
FungusScript fungusScript = parentSequence.GetFungusScript(); FungusScript fungusScript = parentSequence.GetFungusScript();
// Record the currently selected sequence because Stop() will clear it.
Sequence selectedSequence = fungusScript.selectedSequence;
parentSequence.Stop();
if (fungusScript != null) 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); fungusScript.ExecuteSequence(s);
} }
} }

29
Assets/Fungus/FungusScript/Scripts/FungusScript.cs

@ -13,12 +13,6 @@ namespace Fungus
*/ */
public class FungusScript : MonoBehaviour public class FungusScript : MonoBehaviour
{ {
/**
* Currently executing sequence.
*/
[System.NonSerialized]
public Sequence executingSequence;
/** /**
* Scroll position of Fungus Script editor window. * Scroll position of Fungus Script editor window.
*/ */
@ -147,24 +141,37 @@ namespace Fungus
return; return;
} }
// Show start sequence by default
selectedSequence = startSequence;
ExecuteSequence(startSequence); ExecuteSequence(startSequence);
} }
/** /**
* Start running the Fungus Script by executing a specific child sequence. * 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 // Sequence must be a child of the parent Fungus Script
if (sequence == null || if (sequence == null ||
sequence.transform.parent != transform && sequence.transform != transform) sequence.transform.parent != transform &&
sequence.transform != transform)
{ {
return; return false;
} }
executingSequence = sequence; // Can't restart a running sequence, have to wait until it's idle again
selectedSequence = sequence; if (sequence.IsExecuting())
{
return false;
}
// Execute the first command in the command list
sequence.ExecuteNextCommand(); sequence.ExecuteNextCommand();
return true;
} }
/** /**

10
Assets/Fungus/FungusScript/Scripts/Sequence.cs

@ -56,17 +56,15 @@ namespace Fungus
return false; return false;
} }
public virtual bool IsRunning() public virtual bool IsExecuting()
{ {
FungusScript fungusScript = GetFungusScript(); FungusScript fungusScript = GetFungusScript();
if (fungusScript == null)
if (fungusScript == null ||
fungusScript.executingSequence == null)
{ {
return false; return false;
} }
return (fungusScript.executingSequence == this); return (activeCommand != null);
} }
public virtual int GetExecutionCount() public virtual int GetExecutionCount()
@ -138,8 +136,6 @@ namespace Fungus
} }
activeCommand = null; activeCommand = null;
fungusScript.executingSequence = null;
fungusScript.selectedSequence = null;
fungusScript.ClearSelectedCommands(); fungusScript.ClearSelectedCommands();
} }

Loading…
Cancel
Save