protected IEnumerator ExecuteSubOperationAndWaitForTerminate(CoroutineOperation subOp)
        {
            bool subOpLaunchedCorrectly = Pre_ExecuteSubOperation(subOp);

            if (!subOpLaunchedCorrectly)
            {
                Terminate_Internal(success: false, subOp.Message, LogFlag.None); // don't log sub-operation failure
                yield break;
            }

            while (subOp.IsRunning)
            {
                yield return(null);
            }

            Post_ExecuteSubOperation(subOp);
        }
        bool Pre_ExecuteSubOperation(CoroutineOperation op)
        {
            if (op == null)
            {
                return(false);
            }

            // execute sub-operation if necessary
            if (!op._hasRun)
            {
                op.Execute();
            }

            if (_ongoingSubOperations == null)
            {
                _ongoingSubOperations = new List <CoroutineOperation>();
            }
            _ongoingSubOperations.Add(op);

            return(true);
        }
        protected IEnumerator ExecuteSubOperationAndWaitForSuccess(CoroutineOperation subOp)
        {
            bool subOpLaunchedCorrectly = Pre_ExecuteSubOperation(subOp);

            if (!subOpLaunchedCorrectly)
            {
                Terminate_Internal(success: false, subOp.Message, LogFlag.None); // don't log sub-operation failure
                yield break;
            }

            while (!subOp.HasSucceeded)
            {
                // terminate if sub-operation fails
                if (subOp.HasFailed)
                {
                    Terminate_Internal(success: false, subOp.Message, LogFlag.None); // don't log sub-operation failure
                    break;
                }
                yield return(null);
            }

            Post_ExecuteSubOperation(subOp);
        }
 void Post_ExecuteSubOperation(CoroutineOperation op)
 {
     _ongoingSubOperations.Remove(op);
 }