Пример #1
0
        /// <summary>
        /// Restores the previous held workflow.
        /// </summary>
        private void RestoreWorkflow()
        {
            WorkflowInstance old = current;

            current = held_flows.Pop();

            if (old.completed != null)
            {
                foreach (var kvp in old.completed)
                {
                    current.values[kvp.Key] = kvp.Value;
                }
            }

            if (current.stage == workflows[current.name].stages.Length)
            {
                HandleWorkflowExit();
                return;
            }

            if (current != null)
            {
                StartStage(attachevent: true);
            }

            DebugLog.LogController("Restoring workflow '" + current.name + "'");
        }
Пример #2
0
        /// <summary>
        /// Starts a stage.
        /// </summary>
        /// <param name="workflow">The workflow to start from - defaults to current.</param>
        /// <param name="stage">The stage to start - defaults to current.</param>
        /// <param name="set">If the workflow and state should be updated.</param>
        /// <param name="attachevent">If an OnFinish handler should be attached to the stage.</param>
        private void StartStage(string workflow = null, int stage = -1, bool set = false, bool attachevent = false)
        {
            if (workflow == null)
            {
                workflow = current.name;
            }

            if (stage == -1)
            {
                stage = current.stage;
            }

            string[] args = ResolveArguments(stage);
            content_controller.Activate(workflows[workflow].stages[stage], args);

            DebugLog.LogController("Displaying stage " + workflows[workflow].stages[stage]);

            if (set)
            {
                current = new WorkflowInstance()
                {
                    name  = workflow,
                    stage = stage
                };
            }

            if (attachevent)
            {
                content_controller.Current.Finish += OnFinish;
            }
        }
Пример #3
0
        /// <summary>
        /// Invokes a workflow by name.
        /// </summary>
        /// <param name="name">The workflow</param>
        /// <param name="force">Whether the current workflow should be forcefully stopped if running.</param>
        public void InvokeWorkflow(string name, bool force = false)
        {
            if (current != null && !force)
            {
                throw new InvalidOperationException("Cannot invoke workflow: " + current.name + " is already active");
            }

            current = new WorkflowInstance();

            current.arguments = ParseWorkflowName(name, out current.name, current.values);

            StartStage(attachevent: true);

            DebugLog.LogController("Invoking workflow '" + name + "'");
        }
Пример #4
0
        private void HandleWorkflowExit()
        {
            string name = current.stage < workflows[current.name].stages.Length ?
                          workflows[current.name].stages[current.stage] : null;

            current.completed = workflows[current.name].acceptor(current.values);

            DebugLog.LogController(string.Format("Stage {0}/{1}:{3} is exiting ({2})", name, current.stage, DictToString(current.completed), current.name));

            // if there's a held workflow, restore it
            if (held_flows.Count > 0)
            {
                DebugLog.LogController("Restoring");
                RestoreWorkflow();
            }
            else
            {
                DebugLog.LogController("Resetting");
                // otherwise, reset to default screen
                Reset();

                content_controller.Deactivate();
            }
        }
Пример #5
0
        /// <summary>
        /// Invoked when a content is finished. Validates the content's output, and moves to the next content if possible.
        /// </summary>
        private void OnFinish(object sender, ReferenceArgs <Dictionary <string, object> > args)
        {
            content_controller.Current.Finish -= OnFinish;

            string error = null;
            bool?  valid = workflows[current.name].validators[current.stage]?.Invoke(args.Value, out error);

            string name = current.stage < workflows[current.name].stages.Length ?
                          workflows[current.name].stages[current.stage] : null;

            string redirect = null;

            if (valid.Value || !valid.HasValue)
            {
                DebugLog.LogController(string.Format("Stage {0}/{1} has valid output ({2})", name, current.stage, DictToString(args.Value)));

                foreach (KeyValuePair <string, object> entry in args.Value)
                {
                    current.values[entry.Key] = entry.Value;
                }

                redirect = workflows[current.name].redirector?.Invoke(current.stage,
                                                                      name, valid ?? true, current.values);

                current.stage++;


                if (current.stage < workflows[current.name].stages.Length)
                {
                    StartStage(attachevent: true);
                }
            }
            else
            {
                DebugLog.LogController(string.Format("Stage {0}/{1} has invalid output ({2})", name, current.stage, DictToString(args.Value)));

                HoldWorkflow();

                InvokeWorkflow("__CancelRequest(error = " + error + ")", true);

                return;
            }

            if (redirect != null)
            {
                DebugLog.LogController(string.Format("Stage {0}/{1} is redirecting to {2}", name, current.stage, redirect));

                HoldWorkflow();

                InvokeWorkflow(redirect, true);

                return;
            }
            else
            {
                DebugLog.LogController(string.Format("Stage {0}/{1} is not redirecting", name, current.stage));
            }

            if (current.stage == workflows[current.name].stages.Length)
            {
                HandleWorkflowExit();
            }
        }
Пример #6
0
        /// <summary>
        /// Pushes the current workflow into the held workflows, but does not reset anything.
        /// </summary>
        private void HoldWorkflow()
        {
            held_flows.Push(current);

            DebugLog.LogController("Holding workflow '" + current.name + "' - stack size: " + held_flows.Count);
        }