diff --git a/Assets/Fungus/Scripts/Components/Block.cs b/Assets/Fungus/Scripts/Components/Block.cs
index 41278dfd..9be9693f 100644
--- a/Assets/Fungus/Scripts/Components/Block.cs
+++ b/Assets/Fungus/Scripts/Components/Block.cs
@@ -213,6 +213,7 @@ namespace Fungus
var flowchart = GetFlowchart();
executionState = ExecutionState.Executing;
+ BlockSignals.DoBlockStart(this);
#if UNITY_EDITOR
// Select the executing block & the first command
@@ -278,6 +279,7 @@ namespace Fungus
// This icon timer is managed by the FlowchartWindow class, but we also need to
// set it here in case a command starts and finishes execution before the next window update.
command.ExecutingIconTimer = Time.realtimeSinceStartup + FungusConstants.ExecutingIconFadeTime;
+ BlockSignals.DoCommandExecute(this, command, i, commandList.Count);
command.Execute();
// Wait until the executing command sets another command to jump to via Command.Continue()
@@ -298,6 +300,7 @@ namespace Fungus
executionState = ExecutionState.Idle;
activeCommand = null;
+ BlockSignals.DoBlockEnd(this);
if (onComplete != null)
{
diff --git a/Assets/Fungus/Scripts/Signals/BlockSignals.cs b/Assets/Fungus/Scripts/Signals/BlockSignals.cs
new file mode 100644
index 00000000..0492d850
--- /dev/null
+++ b/Assets/Fungus/Scripts/Signals/BlockSignals.cs
@@ -0,0 +1,36 @@
+using Fungus.Utils;
+
+namespace Fungus
+{
+ ///
+ /// Block event signalling system.
+ /// You can use this to be notified about various events in the Block execution process.
+ ///
+ public static class BlockSignals
+ {
+ #region Public members
+
+ ///
+ /// BlockStart signal. Sent when the Block starts execution.
+ ///
+ public static event BlockStartHandler OnBlockStart;
+ public delegate void BlockStartHandler(Block block);
+ public static void DoBlockStart(Block block) { if (OnBlockStart != null) OnBlockStart(block); }
+
+ ///
+ /// BlockEnd signal. Sent when the Block ends execution.
+ ///
+ public static event BlockEndHandler OnBlockEnd;
+ public delegate void BlockEndHandler(Block block);
+ public static void DoBlockEnd(Block block) { if (OnBlockEnd != null) OnBlockEnd(block); }
+
+ ///
+ /// CommandExecute signal. Sent just before a Command in a Block executes.
+ ///
+ public static event CommandExecuteHandler OnCommandExecute;
+ public delegate void CommandExecuteHandler(Block block, Command command, int commandIndex, int maxCommandIndex);
+ public static void DoCommandExecute(Block block, Command command, int commandIndex, int maxCommandIndex) { if (OnCommandExecute != null) OnCommandExecute(block, command, commandIndex, maxCommandIndex); }
+
+ #endregion
+ }
+}
diff --git a/Assets/Fungus/Scripts/Signals/BlockSignals.cs.meta b/Assets/Fungus/Scripts/Signals/BlockSignals.cs.meta
new file mode 100644
index 00000000..d3c70701
--- /dev/null
+++ b/Assets/Fungus/Scripts/Signals/BlockSignals.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 12109e10b0f034bbab8a7a5d700bc070
+timeCreated: 1474988491
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Fungus/Scripts/Signals/WriterSignals.cs b/Assets/Fungus/Scripts/Signals/WriterSignals.cs
index 01b1a67d..ff9680d5 100644
--- a/Assets/Fungus/Scripts/Signals/WriterSignals.cs
+++ b/Assets/Fungus/Scripts/Signals/WriterSignals.cs
@@ -15,22 +15,22 @@ namespace Fungus
///
/// TextTagToken signal. Sent for each unique token when writing text.
///
- public delegate void TextTagTokenHandler(Writer writer, TextTagToken token, int index, int maxIndex);
public static event TextTagTokenHandler OnTextTagToken;
+ public delegate void TextTagTokenHandler(Writer writer, TextTagToken token, int index, int maxIndex);
public static void DoTextTagToken(Writer writer, TextTagToken token, int index, int maxIndex) { if(OnTextTagToken != null) OnTextTagToken(writer, token, index, maxIndex); }
///
/// WriterState signal. Sent when the writer changes state.
///
- public delegate void WriterStateHandler(Writer writer, WriterState writerState);
public static event WriterStateHandler OnWriterState;
+ public delegate void WriterStateHandler(Writer writer, WriterState writerState);
public static void DoWriterState(Writer writer, WriterState writerState) { if (OnWriterState != null) OnWriterState(writer, writerState); }
///
/// WriterInput signal. Sent when the writer receives player input.
///
- public delegate void WriterInputHandler(Writer writer);
public static event WriterInputHandler OnWriterInput;
+ public delegate void WriterInputHandler(Writer writer);
public static void DoWriterInput(Writer writer) { if (OnWriterInput != null) OnWriterInput(writer); }
///
diff --git a/Assets/Tests/Signals/BlockSignalsTester.cs b/Assets/Tests/Signals/BlockSignalsTester.cs
new file mode 100644
index 00000000..754d9a26
--- /dev/null
+++ b/Assets/Tests/Signals/BlockSignalsTester.cs
@@ -0,0 +1,53 @@
+using UnityEngine;
+using System.Collections;
+using Fungus.Commands;
+
+namespace Fungus
+{
+ ///
+ /// Checks if Block signals are being sent correctly.
+ ///
+ [AddComponentMenu("")]
+ public class BlockSignalsTester : MonoBehaviour
+ {
+ bool started = false;
+ bool commandExecuted = false;
+
+ void OnEnable()
+ {
+ BlockSignals.OnBlockStart += OnBlockStart;
+ BlockSignals.OnBlockEnd += OnBlockEnd;
+ BlockSignals.OnCommandExecute += OnCommandExecute;
+ }
+
+ void OnDisable()
+ {
+ BlockSignals.OnBlockStart -= OnBlockStart;
+ BlockSignals.OnBlockEnd -= OnBlockEnd;
+ BlockSignals.OnCommandExecute -= OnCommandExecute;
+ }
+
+ void OnBlockStart(Block block)
+ {
+ IntegrationTest.Assert(block.BlockName == "Start");
+
+ started = true;
+ }
+
+ void OnBlockEnd(Block block)
+ {
+ IntegrationTest.Assert(started);
+ IntegrationTest.Assert(commandExecuted);
+
+ IntegrationTest.Pass();
+ }
+
+ void OnCommandExecute(Block block, Command command, int commandIndex, int maxCommandIndex)
+ {
+ IntegrationTest.Assert(commandIndex == 0);
+ IntegrationTest.Assert(maxCommandIndex == 1);
+ IntegrationTest.Assert(command.GetType() == typeof(Wait));
+ commandExecuted = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Tests/Signals/BlockSignalsTester.cs.meta b/Assets/Tests/Signals/BlockSignalsTester.cs.meta
new file mode 100644
index 00000000..6fe2ffc5
--- /dev/null
+++ b/Assets/Tests/Signals/BlockSignalsTester.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5d396ca39a0454e2ca06d4aad7c5706c
+timeCreated: 1474988463
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Tests/Signals/SignalsTests.unity b/Assets/Tests/Signals/SignalsTests.unity
index c5fba771..c368d289 100644
--- a/Assets/Tests/Signals/SignalsTests.unity
+++ b/Assets/Tests/Signals/SignalsTests.unity
@@ -264,7 +264,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 61dddfdc5e0e44ca298d8f46f7f5a915, type: 3}
m_Name:
m_EditorClassIdentifier:
- selectedFlowchart: {fileID: 411939904}
+ selectedFlowchart: {fileID: 330763419}
--- !u!4 &286067097
Transform:
m_ObjectHideFlags: 1
@@ -278,6 +278,129 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
+--- !u!1 &330763414
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 142980, guid: 5e7fbc8d4eb714b279eeeef2262c1e1a, type: 2}
+ m_PrefabInternal: {fileID: 0}
+ serializedVersion: 4
+ m_Component:
+ - 4: {fileID: 330763415}
+ - 114: {fileID: 330763419}
+ - 114: {fileID: 330763418}
+ - 114: {fileID: 330763417}
+ - 114: {fileID: 330763416}
+ m_Layer: 0
+ m_Name: Flowchart
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &330763415
+Transform:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 467082, guid: 5e7fbc8d4eb714b279eeeef2262c1e1a, type: 2}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 330763414}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_Children: []
+ m_Father: {fileID: 467145139}
+ m_RootOrder: 0
+--- !u!114 &330763416
+MonoBehaviour:
+ m_ObjectHideFlags: 2
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 330763414}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 3315ad2ebb85443909a1203d56d9344e, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ itemId: 1
+ indentLevel: 0
+ _duration:
+ floatRef: {fileID: 0}
+ floatVal: 1
+ durationOLD: 0
+--- !u!114 &330763417
+MonoBehaviour:
+ m_ObjectHideFlags: 2
+ m_PrefabParentObject: {fileID: 11462346, guid: 5e7fbc8d4eb714b279eeeef2262c1e1a,
+ type: 2}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 330763414}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d2f6487d21a03404cb21b245f0242e79, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ parentBlock: {fileID: 330763418}
+--- !u!114 &330763418
+MonoBehaviour:
+ m_ObjectHideFlags: 2
+ m_PrefabParentObject: {fileID: 11433304, guid: 5e7fbc8d4eb714b279eeeef2262c1e1a,
+ type: 2}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 330763414}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 3d3d73aef2cfc4f51abf34ac00241f60, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ nodeRect:
+ serializedVersion: 2
+ x: 67
+ y: 70
+ width: 120
+ height: 40
+ itemId: 0
+ blockName: Start
+ description:
+ eventHandler: {fileID: 330763417}
+ commandList:
+ - {fileID: 330763416}
+--- !u!114 &330763419
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 11430050, guid: 5e7fbc8d4eb714b279eeeef2262c1e1a,
+ type: 2}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 330763414}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 7a334fe2ffb574b3583ff3b18b4792d3, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 1
+ scrollPos: {x: 0, y: 0}
+ variablesScrollPos: {x: 0, y: 0}
+ variablesExpanded: 1
+ blockViewHeight: 400
+ zoom: 1
+ scrollViewRect:
+ serializedVersion: 2
+ x: -343
+ y: -340
+ width: 1114
+ height: 859
+ selectedBlock: {fileID: 330763418}
+ selectedCommands: []
+ variables: []
+ description:
+ stepPause: 0
+ colorCommands: 1
+ hideComponents: 1
+ saveSelection: 1
+ localizationId:
+ showLineNumbers: 0
+ hideCommands: []
+ luaEnvironment: {fileID: 0}
+ luaBindingName: flowchart
--- !u!1 &411939899
GameObject:
m_ObjectHideFlags: 0
@@ -494,6 +617,58 @@ MonoBehaviour:
commandList:
- {fileID: 411939906}
- {fileID: 411939905}
+--- !u!1 &467145137
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ serializedVersion: 4
+ m_Component:
+ - 4: {fileID: 467145139}
+ - 114: {fileID: 467145138}
+ m_Layer: 0
+ m_Name: BlockSignalsTest
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &467145138
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 467145137}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: b1dba0b27b0864740a8720e920aa88c0, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ timeout: 5
+ ignored: 0
+ succeedAfterAllAssertionsAreExecuted: 0
+ expectException: 0
+ expectedExceptionList:
+ succeedWhenExceptionIsThrown: 0
+ includedPlatforms: -1
+ platformsToIgnore: []
+ dynamic: 0
+ dynamicTypeName:
+--- !u!4 &467145139
+Transform:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 467145137}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_Children:
+ - {fileID: 330763415}
+ - {fileID: 676488089}
+ m_Father: {fileID: 0}
+ m_RootOrder: 3
--- !u!1 &597475644
GameObject:
m_ObjectHideFlags: 0
@@ -581,6 +756,46 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
+--- !u!1 &676488088
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ serializedVersion: 4
+ m_Component:
+ - 4: {fileID: 676488089}
+ - 114: {fileID: 676488090}
+ m_Layer: 0
+ m_Name: BlockSignalsTester
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &676488089
+Transform:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 676488088}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_Children: []
+ m_Father: {fileID: 467145139}
+ m_RootOrder: 1
+--- !u!114 &676488090
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 676488088}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 5d396ca39a0454e2ca06d4aad7c5706c, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
--- !u!1 &759754969
GameObject:
m_ObjectHideFlags: 0
@@ -642,7 +857,7 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
- m_RootOrder: 4
+ m_RootOrder: 5
--- !u!1 &1201908855
GameObject:
m_ObjectHideFlags: 0
@@ -816,4 +1031,4 @@ Transform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
- m_RootOrder: 3
+ m_RootOrder: 4