예제 #1
0
        /// <summary>
        /// Pushes a list of nodes as a new stack frame onto the call stack.
        /// </summary>
        /// <param name="label">
        /// The list of nodes to push onto the call stack.
        /// </param>
        public void Inject(List <Node> nodes)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException(nameof(nodes));
            }

            Stack.Push(new StackFrame(nodes));

            Yield = null;
            Continue();
        }
예제 #2
0
        public Rumor(SerializationInfo info, StreamingContext context)
        {
            Nodes       = info.GetValue <Dictionary <string, List <Node> > >("nodes");
            State       = info.GetValue <RumorState>("state");
            Scope       = info.GetValue <RumorScope>("scope");
            Stack       = info.GetValue <Stack <StackFrame> >("stack");
            FinishCount = info.GetValue <int>("finishCount");
            CancelCount = info.GetValue <int>("cancelCount");
            Yield       = info.GetValue <Yield>("yield");
            AutoAdvance = info.GetValue <float>("autoAdvance");

            Bindings = new RumorBindings();
        }
예제 #3
0
        /// <summary>
        /// This should be called after any operation that may allow execution
        /// to continue.
        /// </summary>
        private void Continue()
        {
            // There is nothing to do
            if (Stack.Count == 0)
            {
                return;
            }

            while (Stack.Count > 0)
            {
                // Check if the current yield is finished
                if (Yield != null)
                {
                    if (Yield.Finished == true)
                    {
                        Yield = null;
                    }

                    // Auto-advance, if applicable
                    else if (Yield is ForAdvance &&
                             AutoAdvance >= 0 && Yield.Elapsed >= AutoAdvance)
                    {
                        Yield = null;
                    }

                    // Wait for the current yield to finish
                    else
                    {
                        return;
                    }
                }

                // Check if this frame is complete
                var frame = Stack.Peek();
                if (frame.Done)
                {
                    Stack.Pop();
                    continue;
                }

                // Execute the next node in the stack frame
                Yield = frame.Execute(this);
                if (Yield is ForAdvance && AutoAdvance != 0)
                {
                    OnWaitForAdvance?.Invoke();
                    return;
                }
                else if (Yield is ForChoose)
                {
                    OnWaitForChoose?.Invoke(State.GetChoices());
                    OnWaitForChooseTimeout?.Invoke(
                        State.GetChoices(),
                        (Yield as ForChoose).Timeout
                        );
                    return;
                }
                else if (Yield is ForSeconds)
                {
                    return;
                }
            }

            OnFinish?.Invoke();
            FinishCount++;
        }