Example #1
0
        /// <summary>
        /// Creates a command which runs a coroutine.
        /// </summary>
        /// <param name='command'>
        /// The command to generate the coroutine.
        /// </param>
        /// <remarks>
        /// The reason this method doesn't just except an IEnumerator is that
        /// IEnumerators created from continuations can't be reset, (a continuation is
        /// any method containing a yield statement, and returning an IEnumerator).  This means
        /// that coroutines would break when executed within a repeat command.
        /// By encapsulating the call to create the IEnumerator in a delegate, it is possible for a
        /// user to call the coroutine however they please, and for it to be repeatable.
        /// </remarks>
        /// <example>
        /// <code>
        ///     private CommandQueue _queue = new CommandQueue();
        ///
        ///     IEnumerator<CommandDelegate> CoroutineMethod(int firstVal, int secondVal, int thirdVal)
        ///     {
        ///			Debug.Log(firstVal);
        ///         yield return Commands.WaitForSeconds(1.0f); // You can return any CommandDelegate here.
        ///         Debug.Log(secondVal);
        ///         yield return null; // Wait a single frame.
        ///         Debug.Log(thirdVal);
        ///         yield break; // Force exits the coroutine.
        ///     }
        ///
        ///     IEnumerator<CommandDelegate> CoroutineNoArguments()
        ///     {
        ///        yield return Commands.WaitForSeconds(2.0);
        ///     }
        ///
        ///     void Start()
        ///     {
        ///         _queue.Enqueue(
        ///             Commands.Coroutine( () => CoroutineMethod(1,2,3)),
        ///             Commands.Coroutine(CoroutineNoArguments)
        ///         );
        ///     }
        ///
        ///     void Update()
        ///     {
        ///         _queue.Update(Time.deltaTime);
        ///     }
        ///
        /// </code>
        /// </example>
        public static CommandDelegate Coroutine(CommandCoroutine command)
        {
            CheckArgumentNonNull(command);
            IEnumerator <CommandDelegate> coroutine = null;
            CommandDelegate currentCommand          = null;

            return((ref double deltaTime) => {
                // Create our coroutine, if we don't have one.
                if (coroutine == null)
                {
                    coroutine = command();
                    // Finish if we couldn't create a coroutine.
                    if (coroutine == null)
                    {
                        return true;
                    }
                }

                bool finished = true;
                while (finished)
                {
                    // Set the current command.
                    if (currentCommand == null)
                    {
                        if (!coroutine.MoveNext())
                        {
                            coroutine = null;
                            return true;
                        }
                        currentCommand = coroutine.Current;
                        if (currentCommand == null)
                        {
                            // Yield return null will wait a frame, like with
                            // Unity coroutines.
                            currentCommand = Commands.WaitForFrames(1);
                        }
                    }
                    finished = currentCommand(ref deltaTime);
                    if (finished)
                    {
                        currentCommand = null;
                    }
                }
                return false;
            });
        }
Example #2
0
        /// <summary>
        /// Creates a command which runs a coroutine.
        /// </summary>
        /// <param name='command'>
        /// The command to generate the coroutine.
        /// </param>
        /// <remarks>
        /// The reason this method doesn't just except an IEnumerator is that
        /// IEnumerators created from continuations can't be reset, (a continuation is
        /// any method containing a yield statement, and returning an IEnumerator).  This means
        /// that coroutines would break when executed within a repeat command.
        /// By encapsulating the call to create the IEnumerator in a delegate, it is possible for a
        /// user to call the coroutine however they please, and for it to be repeatable.
        /// </remarks>
        /// <example>
        /// <code>
        /// 	private CommandQueue _queue = new CommandQueue();
        /// 
        ///     IEnumerator<CommandDelegate> CoroutineMethod(int firstVal, int secondVal, int thirdVal)
        ///     {
        ///			Debug.Log(firstVal);
        /// 		yield return Commands.WaitForSeconds(1.0f); // You can return any CommandDelegate here.
        /// 		Debug.Log(secondVal);
        /// 		yield return null; // Wait a single frame.
        /// 		Debug.Log(thirdVal);
        /// 		yield break; // Force exits the coroutine.
        ///     }
        ///     
        ///     IEnumerator<CommandDelegate> CoroutineNoArguments()
        ///     {
        ///        yield return Commands.WaitForSeconds(2.0);
        ///     }
        /// 
        ///     void Start() 
        /// 	{ 
        /// 		_queue.Enqueue(
        /// 			Commands.Coroutine( () => CoroutineMethod(1,2,3)),
        ///             Commands.Coroutine(CoroutineNoArguments)
        /// 		);
        /// 	}
        /// 
        /// 	void Update()
        /// 	{
        /// 		_queue.Update(Time.deltaTime);
        /// 	}
        /// 	
        /// </code>
        /// </example>
        public static CommandDelegate Coroutine(CommandCoroutine command)
        {
            CheckArgumentNonNull(command);
            IEnumerator<CommandDelegate> coroutine = null;
            CommandDelegate currentCommand = null;

            return (ref double deltaTime) => {
            // Create our coroutine, if we don't have one.
            if (coroutine == null) {
                coroutine = command();
                // Finish if we couldn't create a coroutine.
                if (coroutine == null) { return true; }
            }

            bool finished = true;
            while (finished) {
                // Set the current command.
                if (currentCommand == null) {
                    if (!coroutine.MoveNext()) {
                        coroutine = null;
                        return true;
                    }
                    currentCommand = coroutine.Current;
                    if (currentCommand == null) {
                        // Yield return null will wait a frame, like with
                        // Unity coroutines.
                        currentCommand = Commands.WaitForFrames(1);
                    }
                }
                finished = currentCommand(ref deltaTime);
                if (finished) { currentCommand = null; }
            }
            return false;
            };
        }