private void ReturnToIdle()
        {
            executionState = ExecutionState.Idle;
            activeCommand  = null;
            BlockSignals.DoBlockEnd(this);

            if (lastOnCompleteAction != null)
            {
                lastOnCompleteAction();
            }
            lastOnCompleteAction = null;
        }
Exemplo n.º 2
0
        /// <summary>
        /// A coroutine method that executes all commands in the Block. 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)
            {
                yield break;
            }

            if (!executionInfoSet)
            {
                SetExecutionInfo();
            }

            executionCount++;

            var flowchart = GetFlowchart();

            executionState = ExecutionState.Executing;
            BlockSignals.DoBlockStart(this);

            #if UNITY_EDITOR
            // Select the executing block & the first command
            flowchart.SelectedBlock = this;
            if (commandList.Count > 0)
            {
                flowchart.ClearSelectedCommands();
                flowchart.AddSelectedCommand(commandList[0]);
            }
            #endif

            jumpToCommandIndex = commandIndex;

            int i = 0;
            while (true)
            {
                // Executing commands specify the next command to skip to by setting jumpToCommandIndex using Command.Continue()
                if (jumpToCommandIndex > -1)
                {
                    i = jumpToCommandIndex;
                    jumpToCommandIndex = -1;
                }

                // Skip disabled commands, comments and labels
                while (i < commandList.Count &&
                       (!commandList[i].enabled ||
                        commandList[i].GetType() == typeof(Comment) ||
                        commandList[i].GetType() == typeof(Label)))
                {
                    i = commandList[i].CommandIndex + 1;
                }

                if (i >= commandList.Count)
                {
                    break;
                }

                // The previous active command is needed for if / else / else if commands
                if (activeCommand == null)
                {
                    previousActiveCommandIndex = -1;
                }
                else
                {
                    previousActiveCommandIndex = activeCommand.CommandIndex;
                }

                var command = commandList[i];
                activeCommand = command;

                if (flowchart.IsActive())
                {
                    // Auto select a command in some situations
                    if ((flowchart.SelectedCommands.Count == 0 && i == 0) ||
                        (flowchart.SelectedCommands.Count == 1 && flowchart.SelectedCommands[0].CommandIndex == previousActiveCommandIndex))
                    {
                        flowchart.ClearSelectedCommands();
                        flowchart.AddSelectedCommand(commandList[i]);
                    }
                }

                command.IsExecuting = true;
                // 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()
                while (jumpToCommandIndex == -1)
                {
                    yield return(null);
                }

                #if UNITY_EDITOR
                if (flowchart.StepPause > 0f)
                {
                    yield return(new WaitForSeconds(flowchart.StepPause));
                }
                #endif

                command.IsExecuting = false;
            }

            executionState = ExecutionState.Idle;
            activeCommand  = null;
            BlockSignals.DoBlockEnd(this);

            if (onComplete != null)
            {
                onComplete();
            }
        }