コード例 #1
0
 /**
  * Spawns the child task.
  *
  * @see jbt.execution.core.ExecutionTask#internalSpawn()
  */
 protected override void InternalSpawn()
 {
     child = ((ModelDecorator) ModelTask).getChild().CreateExecutor(
         Executor, this);
     child.AddTaskListener(this);
     child.Spawn(Context);
 }
コード例 #2
0
        /**
         * Constructs an ExecutionTask with an associated ModelTask and a
         * BTExecutor. The ModelTask represents the conceptual task that the
         * ExecutionTask is running, and the BTExecutor is that in charge of the
         * ExecutionTask. Also, the parent of the ExecutionTask must be provided.
         *
         * @param modelTask
         *            the ModelTask this ExecutionTask will run.
         * @param executor
         *            the BTExecutor managing this task.
         * @param parent
         *            the parent ExecutionTask, or null in case this is the root of
         *            the tree.
         */

        protected ExecutionTask(ModelTask modelTask, IBTExecutor executor, ExecutionTask parent)
        {
            _modelTask  = modelTask;
            _executor   = executor as BTExecutor;
            _listeners  = new List <ITaskListener>();
            _spawnable  = true;
            _tickable   = false;
            _terminated = false;
            _status     = Status.Uninitialized;
            _parent     = parent;

            if (_modelTask != null)
            {
                AlwaysFail = modelTask.AlwaysFail;
            }

            /* Compute the position of this node. */
            if (parent == null)
            {
                _position = new Position();
            }
            else
            {
                _position = new Position(parent._position);
                var nextMove = GetMove();
                _position.AddMove(nextMove);
            }
        }
コード例 #3
0
 /**
  * Constructs an ExecutionRandomSelector to run a specific ModelRandomSelector.
  *
  * @param modelTask
  *            the ModelRandomSelector to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionRandomSelector.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionRandomSelector(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelRandomSelector))
     {
         throw new ArgumentException("The ModelTask must subclass ModelRandomSelector but it inherits from " + modelTask.GetType().Name);
     }
 }
コード例 #4
0
 /**
  * Constructs an ExecutionAction that knows how to run a ModelAction.
  *
  * @param modelTask
  *            the ModelAction to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionAction.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 protected ExecutionAction(ModelAction modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (modelTask == null )
     {
         throw new ArgumentException("The ModelTask must not be null" );
     }
 }
コード例 #5
0
 /**
  * Spawns the only child.
  *
  * @see jbt.execution.core.ExecutionTask#internalSpawn()
  */
 protected override void InternalSpawn()
 {
     /* Just spawn the only child. */
     child = ((ModelInverter) ModelTask).getChild().CreateExecutor(
         Executor, this);
     child.AddTaskListener(this);
     child.Spawn(Context);
 }
コード例 #6
0
 /**
  * Constructs an ExecutionLeaf to run a specific ModelLeaf.
  *
  * @param modelTask
  *            the ModelLeaf to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionLeaf.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 protected ExecutionLeaf(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelLeaf))
     {
         throw new ArgumentException("The ModelTask must subclass ModelLeaf but it inherits from " + modelTask.GetType().Name);
     }
 }
コード例 #7
0
 /**
  * Spawns the first child of the sequence.
  *
  * @see jbt.execution.core.ExecutionTask#internalSpawn()
  */
 protected override void InternalSpawn()
 {
     _activeChildIndex = 0;
     _children = ModelTask.Children;
     _activeChild = _children[0].CreateExecutor(Executor, this);
     _activeChild.AddTaskListener(this);
     _activeChild.Spawn(Context);
 }
 /**
  * Spawns the child task. This method creates a new HierarchicalContext,
  * sets its parent to the context of the ExecutionHierarchicalContextManager, and spawns
  * the child task using this HierarchicalContext.
  *
  * @see jbt.execution.core.ExecutionTask#internalSpawn()
  */
 protected override void InternalSpawn()
 {
     var newContext = new HierarchicalContext();
     newContext.SetParent(Context);
     _child = ((ModelDecorator) ModelTask).getChild().CreateExecutor(
         Executor, this);
     _child.AddTaskListener(this);
     _child.Spawn(newContext);
 }
コード例 #9
0
 /**
  * Constructs an ExecutionSafeContextManager that knows how to run a
  * ModelSafeContextManager.
  *
  * @param modelTask
  *            the ModelSafeContextManager to run.
  * @param executor
  *            the BTExecutor that will manage this
  *            ExecutionSafeContextManager.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionSafeContextManager(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelSafeContextManager))
     {
         throw new ArgumentException("The ModelTask must subclass ModelSafeContextManager but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #10
0
 /**
  * Creates an ExecutionStaticPriorityList that is able to run a
  * ModelStaticPriorityList task and that is managed by a BTExecutor.
  *
  * @param modelTask
  *            the ModelStaticPriorityList that this
  *            ExecutionStaticPriorityList is going to run.
  * @param executor
  *            the BTExecutor in charge of running this
  *            ExecutionStaticPriorityList.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionStaticPriorityList(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelStaticPriorityList))
     {
         throw new ArgumentException("The ModelTask must subclass ModelStaticPriorityList but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #11
0
 /**
  * Creates an ExecutionPerformInterruption that is able to run a
  * ModelPerformInterruption task and that is managed by a BTExecutor.
  *
  * @param modelTask
  *            the ModelPerformInterruption that this
  *            ExecutionPerformInterruption is going to run.
  * @param executor
  *            the BTExecutor in charge of running this
  *            ExecutionPerformInterruption.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionPerformInterruption(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelPerformInterruption))
     {
         throw new ArgumentException("The ModelTask must subclass ModelPerformInterruption but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #12
0
 /**
  * Spawns the child task. This method creates a new SafeOutputContext, and
  * spawns the child task using this SafeContext. The input context of the
  * SafeOutputContext is that of this ExecutionSafeOutputContextManager task.
  * The list of output variables of the SafeOutputContext is retrieved from
  * the ModelSafeOutputContextManager associated to this task.
  *
  * @see jbt.execution.core.ExecutionTask#internalSpawn()
  */
 protected override void InternalSpawn()
 {
     var newContext = new SafeOutputContext(Context,
         ((ModelSafeOutputContextManager) ModelTask).getOutputVariables());
     child = ((ModelDecorator) ModelTask).getChild().CreateExecutor(
         Executor, this);
     child.AddTaskListener(this);
     child.Spawn(newContext);
 }
コード例 #13
0
 /**
  * Constructs an ExecutionSubtreeLookup that knows how to run a
  * ModelSubtreeLookup.
  *
  * @param modelTask
  *            the ModelSubtreeLookup to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionSubtreeLookup.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionSubtreeLookup(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelSubtreeLookup))
     {
         throw new ArgumentException("The ModelTask must subclass ModelSubtreeLookup but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #14
0
        public static void LogTick(ExecutionTask task)
        {
            if (ActiveDebugger == null)
            {
                return;
            }

            ActiveDebugger.LogTick(task);
        }
コード例 #15
0
 /**
  * Creates an ExecutionComposite that is able to run a particular
  * ModelComposite task.
  *
  * @param modelTask
  *            the ModelComposite task to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionComposite.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 protected ExecutionComposite(ModelTask modelTask, IBTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelComposite))
     {
         throw new ArgumentException("The ModelTask must subclass " + typeof (ModelComposite).Name + " but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #16
0
 /**
  * Constructs and ExecutionUntilFail that knows how to run a ModelUntilFail.
  *
  * @param modelTask
  *            the ModelUntilFail that this ExecutionUntilFail will run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionUntilFail.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionUntilFail(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
     if (!(modelTask is ModelUntilFail))
     {
         throw new ArgumentException("The ModelTask must subclass ModelUntilFail but it inherits from " +
                                     modelTask.GetType().Name);
     }
 }
コード例 #17
0
        /**
         * Creates an ExecutionWait that is able to run a ModelWait task and that is
         * managed by a BTExecutor.
         *
         * @param modelTask
         *            the ModelWait that this ExecutionWait is going to run.
         * @param executor
         *            the BTExecutor in charge of running this ExecutionWait.
         * @param parent
         *            the parent ExecutionTask of this task.
         */
        public ExecutionWait(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
            : base(modelTask, executor, parent)
        {
            if (!(modelTask is ModelWait))
            {
                throw new ArgumentException("The ModelTask must subclass ModelWait but it inherits from " + modelTask.GetType().Name);
            }

            Initialize(modelTask);
        }
コード例 #18
0
 /**
  * Cancels a previous request of removal from one of the lists that the BTExecutor handles. If
  * no such removal request was made, this method does nothing.
  *
  * @param listType
  *            the list from which the removal request will be canceled.
  * @param t
  *            the task whose removal will be canceled.
  */
 public void CancelRemovalRequest(BTExecutorList listType, ExecutionTask t)
 {
     if (listType == BTExecutorList.Open)
     {
         _currentOpenRemovals.Remove(t);
     }
     else
     {
         _currentTickableRemovals.Remove(t);
     }
 }
コード例 #19
0
        /**
         * Creates an ExecutionLimit that knows how to run a ModelLimit.
         *
         * @param modelTask
         *            the ModelLimit to run.
         * @param executor
         *            the BTExecutor that will manage this ExecutionLimit.
         * @param parent
         *            the parent ExecutionTask of this task.
         */
        public ExecutionLimit(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
            : base(modelTask, executor, parent)
        {
            if (!(modelTask is ModelLimit))
            {
                throw new ArgumentException("The ModelTask must subclass ModelLimitbut it inherits from " + modelTask.GetType().Name);
            }

            _maxNumTimes = ((ModelLimit) ModelTask).getMaxNumTimes();
            _numRunsSoFar = 0;
        }
コード例 #20
0
        /**
         * Constructs an ExecutionVariableRenamer that knows how to run a
         * ModelVariableRenamer.
         *
         * @param modelTask
         *            the ModelVariableRenamer to run.
         * @param executor
         *            the BTExecutor in charge of running this
         *            ExecutionVariableRenamer.
         * @param parent
         *            the parent ExecutionTask of this task.
         */
        public ExecutionVariableRenamer(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
            : base(modelTask, executor, parent)
        {
            if (!(modelTask is ModelVariableRenamer))
            {
                throw new ArgumentException("The ModelTask must subclass ModelVariableRenamer but it inherits from " +
                                            modelTask.GetType().Name);
            }

            _variableName = ((ModelVariableRenamer) modelTask).VariableName;
            _newVariableName = ((ModelVariableRenamer) modelTask).NewVariableName;
        }
コード例 #21
0
        /**
         * Creates an ExecutionParallel that is able to run a ModelParallel task and
         * that is managed by a BTExecutor.
         *
         * @param modelTask
         *            the ModelParallel that this ExecutionParallel is going to run.
         * @param executor
         *            the BTExecutor in charge of running this ExecutionParallel.
         * @param parent
         *            the parent ExecutionTask of this task.
         */
        public ExecutionParallel(ModelTask modelTask, BTExecutor executor, ExecutionTask parent)
            : base(modelTask, executor, parent)
        {
            if (!(modelTask is ModelParallel))
            {
                throw new ArgumentException("The ModelTask must subclass " + typeof (ModelParallel).Name + " but it inherits from " +
                                            modelTask.GetType().Name);
            }

            _policy = ((ModelParallel)modelTask).Policy;
            _modelChildren = modelTask.Children;
            Initialize();
        }
コード例 #22
0
 /**
  * Method used to request the BTExecutor to remove an ExecutionTask from one of the list that
  * the BTExecutor handles. The removal is not performed right away, but delayed until:
  *
  * <ul>
  * <li>Either the current game AI cycle (call to {@link #tick()}) finishes. This happens if the
  * removal is requested in the middle of an AI cycle, that is, if <code>tick()</code> is still
  * running.
  * <li>Or the next AI cycle starts. This happens if the removal is requested when the BTExecutor
  * is not ticking the underlying BT. In this case, the next time <code>tick()</code> is called,
  * the removal will be processed just before the BT is actually ticked.
  * </ul>
  *
  * @param listType
  *            the type of the list from which the task will be removed.
  * @param t
  *            the task that wants to be removed from the list of type <code>listType</code>.
  */
 public void RequestRemovalFromList(BTExecutorList listType, ExecutionTask t)
 {
     if (listType == BTExecutorList.Open)
     {
         if (!_currentOpenRemovals.Contains(t))
         {
             _currentOpenRemovals.Add(t);
         }
     }
     else
     {
         if (!_currentTickableRemovals.Contains(t))
         {
             _currentTickableRemovals.Add(t);
         }
     }
 }
コード例 #23
0
        /**
         * Method used to request the BTExecutor to insert an ExecutionTask into one of the list that it
         * handles. The insertion is not performed right away, but delayed until:
         *
         * <ul>
         * <li>Either the current game AI cycle (call to {@link #tick()}) finishes. This happens if the
         * insertion is requested in the middle of an AI cycle, that is, if <code>tick()</code> is still
         * running.
         * <li>Or the next AI cycle starts. This happens if the insertion is requested when the
         * BTExecutor is not ticking the underlying BT. In this case, the next time <code>tick()</code>
         * is called, the insertion will be processed just before the BT is actually ticked.
         * </ul>
         *
         * @param listType
         *            the type of the list that the task will be inserted into.
         * @param t
         *            the task that wants to be inserted into the list of type <code>listType</code>.
         */

        public void RequestInsertionIntoList(BTExecutorList listType, ExecutionTask t)
        {
            if (listType == BTExecutorList.Open)
            {
                if (!_currentOpenInsertions.Contains(t))
                {
                    _currentOpenInsertions.Add(t);
                }
            }
            else
            {
                if (!_currentTickableInsertions.Contains(t))
                {
                    _currentTickableInsertions.Add(t);
                }
            }
        }
コード例 #24
0
        public void Tick()
        {
            /*
             * The ticking algorithm works as follows:
             *
             * If it is the very first time that this method is called, an ExecutionTask is created from
             * the root ModelTask (that is, the root of the behaviour tree that this BTExecutor is going
             * to run). Then, that task is spawned.
             *
             * From then on, tick() will just call tick() on all the ExecutionTasks in the list of
             * tickable tasks.
             *
             * It is important to note that insertions and removals from the list of tickable and open
             * tasks are processed at the very beginning and at the very end of this method, but not
             * while it is ticking the current list of tickable tasks.
             */
            var currentStatus = GetStatus();

            /* We only tick if the tree has not finished yet or if it has not started running. */
            if (currentStatus == Status.Running || currentStatus == Status.Uninitialized)
            {
                ProcessInsertionsAndRemovals();
                OnTickStarted();

                if (firstTimeTicked)
                {
                    _executionBT = _modelBT.CreateExecutor(this, null);
                    _executionBT.Spawn(_context);
                    firstTimeTicked = false;
                }
                else
                {
                    foreach (var executionTask in _tickableTasks)
                    {
                        executionTask.Tick();
                    }
                }

                OnTickCompleted();
                ProcessInsertionsAndRemovals();
            }
        }
コード例 #25
0
 /**
  * Returns a new {@link ExecutionVariableRenamer} that knows how to run this
  * ModelVariableRenamer.
  *
  * @see jbt.model.core.ModelTask#createExecutor(jbt.execution.core.BTExecutor,
  *      jbt.execution.core.ExecutionTask)
  */
 public override ExecutionTask CreateExecutor(BTExecutor executor, ExecutionTask parent)
 {
     return new ExecutionVariableRenamer(this, executor, parent);
 }
コード例 #26
0
 /**
  * Constructs an ExecutionCondition that knows how to run a ModelCondition.
  *
  * @param modelTask
  *            the ModelCondition to run.
  * @param executor
  *            the BTExecutor that will manage this ExecutionCondition.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 protected ExecutionCondition(ModelCondition modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
 }
コード例 #27
0
 /**
  * Returns an ExecutionDynamicPriorityList that is able to run this
  * ModelDynamicPriorityList.
  *
  * @see jbt.model.core.ModelTask#createExecutor(jbt.execution.core.BTExecutor,
  *      ExecutionTask)
  */
 public override ExecutionTask CreateExecutor(BTExecutor executor, ExecutionTask parent)
 {
     return new ExecutionDynamicPriorityList(this, executor, parent);
 }
コード例 #28
0
        public void Tick()
        {
            /*
             * The ticking algorithm works as follows:
             *
             * If it is the very first time that this method is called, an ExecutionTask is created from
             * the root ModelTask (that is, the root of the behaviour tree that this BTExecutor is going
             * to run). Then, that task is spawned.
             *
             * From then on, tick() will just call tick() on all the ExecutionTasks in the list of
             * tickable tasks.
             *
             * It is important to note that insertions and removals from the list of tickable and open
             * tasks are processed at the very beginning and at the very end of this method, but not
             * while it is ticking the current list of tickable tasks.
             */
            var currentStatus = GetStatus();

            /* We only tick if the tree has not finished yet or if it has not started running. */
            if (currentStatus == Status.Running || currentStatus == Status.Uninitialized)
            {
                ProcessInsertionsAndRemovals();
                OnTickStarted();

                if (firstTimeTicked)
                {
                    _executionBT = _modelBT.CreateExecutor(this, null);
                    _executionBT.Spawn(_context);
                    firstTimeTicked = false;
                }
                else
                {
                    foreach (var executionTask in _tickableTasks)
                    {
                        executionTask.Tick();
                    }
                }

                OnTickCompleted();
                ProcessInsertionsAndRemovals();
            }
        }
コード例 #29
0
 /**
  * Method used to request the BTExecutor to remove an ExecutionTask from one of the list that
  * the BTExecutor handles. The removal is not performed right away, but delayed until:
  *
  * <ul>
  * <li>Either the current game AI cycle (call to {@link #tick()}) finishes. This happens if the
  * removal is requested in the middle of an AI cycle, that is, if <code>tick()</code> is still
  * running.
  * <li>Or the next AI cycle starts. This happens if the removal is requested when the BTExecutor
  * is not ticking the underlying BT. In this case, the next time <code>tick()</code> is called,
  * the removal will be processed just before the BT is actually ticked.
  * </ul>
  *
  * @param listType
  *            the type of the list from which the task will be removed.
  * @param t
  *            the task that wants to be removed from the list of type <code>listType</code>.
  */
 public void RequestRemovalFromList(BTExecutorList listType, ExecutionTask t)
 {
     if (listType == BTExecutorList.Open)
     {
         if (!_currentOpenRemovals.Contains(t))
         {
             _currentOpenRemovals.Add(t);
         }
     }
     else
     {
         if (!_currentTickableRemovals.Contains(t))
         {
             _currentTickableRemovals.Add(t);
         }
     }
 }
コード例 #30
0
 /**
  * Method used to request the BTExecutor to insert an ExecutionTask into one of the list that it
  * handles. The insertion is not performed right away, but delayed until:
  *
  * <ul>
  * <li>Either the current game AI cycle (call to {@link #tick()}) finishes. This happens if the
  * insertion is requested in the middle of an AI cycle, that is, if <code>tick()</code> is still
  * running.
  * <li>Or the next AI cycle starts. This happens if the insertion is requested when the
  * BTExecutor is not ticking the underlying BT. In this case, the next time <code>tick()</code>
  * is called, the insertion will be processed just before the BT is actually ticked.
  * </ul>
  *
  * @param listType
  *            the type of the list that the task will be inserted into.
  * @param t
  *            the task that wants to be inserted into the list of type <code>listType</code>.
  */
 public void RequestInsertionIntoList(BTExecutorList listType, ExecutionTask t)
 {
     if (listType == BTExecutorList.Open)
     {
         if (!_currentOpenInsertions.Contains(t))
         {
             _currentOpenInsertions.Add(t);
         }
     }
     else
     {
         if (!_currentTickableInsertions.Contains(t))
         {
             _currentTickableInsertions.Add(t);
         }
     }
 }
コード例 #31
0
 /**
  * Cancels a previous request of removal from one of the lists that the BTExecutor handles. If
  * no such removal request was made, this method does nothing.
  *
  * @param listType
  *            the list from which the removal request will be canceled.
  * @param t
  *            the task whose removal will be canceled.
  */
 public void CancelRemovalRequest(BTExecutorList listType, ExecutionTask t)
 {
     if (listType == BTExecutorList.Open)
     {
         _currentOpenRemovals.Remove(t);
     }
     else
     {
         _currentTickableRemovals.Remove(t);
     }
 }
コード例 #32
0
 public StubExecutionTask(ModelTask modelTask, IBTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
 }
コード例 #33
0
 /**
  * Creates an ExecutionSequence that is able to run a ModelSequence task and
  * that is managed by a BTExecutor.
  *
  * @param modelTask
  *            the ModelSequence that this ExecutionSequence is going to run.
  * @param executor
  *            the BTExecutor in charge of running this ExecutionSequence.
  * @param parent
  *            the parent ExecutionTask of this task.
  */
 public ExecutionSequence(ModelSequence modelTask, BTExecutor executor, ExecutionTask parent)
     : base(modelTask, executor, parent)
 {
 }
コード例 #34
0
 /**
  * Returns an ExecutionRandomSelector that knows how to run this
  * ModelRandomSelector.
  *
  * @see jbt.model.core.ModelTask#createExecutor(jbt.execution.core.BTExecutor,
  *      ExecutionTask)
  */
 public override ExecutionTask CreateExecutor(BTExecutor executor, ExecutionTask parent)
 {
     return new ExecutionRandomSelector(this, executor, parent);
 }
コード例 #35
0
 /**
  * Checks if the currently active child has finished. If it has not
  * finished, returns {@link Status#SUCCESS}. If it has finished in failure,
  * returns {@link Status#FAILURE}. If it has finished successfully, it
  * checks if there is any remaining child. If so, it spawns it. Otherwise,
  * returns {@link Status#SUCCESS}.
  */
 protected override Status InternalTick()
 {
     Status childStatus = _activeChild.Status;
     if (childStatus == Status.Running)
     {
         return Status.Running;
     }
     if (childStatus == Status.Failure || childStatus == Status.Terminated)
     {
         return Status.Failure;
     }
     if (_activeChildIndex == _children.Count - 1)
     {
         /*
          * If this was the last child, return success.
          */
         return Status.Success;
     }
     /*
          * If the current child has finished successfully, but it is not
          * the last one, spawn the next child.
          */
     _activeChildIndex++;
     _activeChild = _children[_activeChildIndex].CreateExecutor(Executor, this);
     _activeChild.AddTaskListener(this);
     _activeChild.Spawn(Context);
     return Status.Running;
 }