/** * Unregisters an ExecutionInterrupter from this BTExecutor. * * @param interrupter * the ExecutionInterrupter to unregister. */ public void UnregisterInterrupter(ExecutionInterrupter interrupter) { if (_interrupters.ContainsKey((ModelInterrupter)interrupter.ModelTask) == false) { return; } _interrupters.Remove((ModelInterrupter)interrupter.ModelTask); }
/** * Registers an ExecutionInterrupter with this BTExecutor. * * @param interrupter * the ExecutionInterrupter to register. */ public void RegisterInterrupter(ExecutionInterrupter interrupter) { if (_interrupters.ContainsKey((ModelInterrupter)interrupter.ModelTask)) { return; } _interrupters.Add((ModelInterrupter)interrupter.ModelTask, interrupter); }
public void TicksTheInterruptBranchTheSpecifiedNumberOfTimes() { var model = new ModelInterrupter(null, new ModelSuccess(null) { Interrupter = new InterrupterBranchTask(null) }) { NumInterrupterBranchTicks = 10 }; var context = new BasicContext(); var executor = new ExecutionInterrupter(model, new BTExecutor(model, context), null); executor.Spawn(context); executor.Interrupt(Status.Success); Assert.AreEqual(10, TestInterrupterExecutor.RecordedTicks); }
/** * Checks if there is an active guard with a priority higher than that of the active child. If * there is such a task, it terminates the active child and spawns the child of the guard with * higher priority, and {@link Status#RUNNING} is returned. If there is no such task, then the * status of the active child is returned. * <p> * If the spawning process failed, this method just returns {@link Status#FAILURE}. If the * spawning process has not finished yet, this method keeps evaluating the guards, and returns * {@link Status#RUNNING}. * * @see jbt.execution.core.ExecutionTask#internalTick() */ protected override Status InternalTick() { /* If the spawning process failed, return failure. */ if (_spawnFailed) { return(Status.Failure); } /* Evaluate guards. */ Tuple <Status, int> activeGuard = EvaluateGuards(); /* * If no child has been spawned yet (not all the guards had completed yet in the * internalSpawn() method)... */ if (_stillNotSpawned) { /* If all the guards have failed, return failure. */ if (activeGuard.Item1 == Status.Failure) { return(Status.Failure); } if (activeGuard.Item1 == Status.Running) { /* * If not all the guards have finished, do no nothing (return RUNNING). */ } else { /* * If all the guards have been evaluated and one succeeded, spawn the child. */ _spawnFailed = false; _stillNotSpawned = false; _activeChildIndex = activeGuard.Item2; _activeChild = _children[_activeChildIndex].CreateExecutor(Executor, this); _activeChild.AddTaskListener(this); _activeChild.Spawn(Context); /* Reset the guards evaluators. */ ResetGuardsEvaluation(); } return(Status.Running); } /* If this point has been reached, there must be an active child. */ if (activeGuard.Item1 == Status.Failure) { /* If all the guards have failed, return failure. */ return(Status.Failure); } if (activeGuard.Item1 == Status.Running) { /* * If the guards are being evaluated, return the status of the active child. */ return(_activeChild.Status); } if (activeGuard.Item2 != _activeChildIndex) { /* * If the child with the highest priority guard has changed, terminate the currently * active child. */ if (_activeChild.ModelTask.Interrupter != null) { var executor = new BTExecutor(_activeChild.ModelTask.Interrupter, Context); ExecutionInterrupter.RunInterrupterBranch(executor, 10); } _activeChild.Terminate(); _activeChildIndex = activeGuard.Item2; /* * Spawn the new child. */ _activeChild = _children[_activeChildIndex].CreateExecutor(Executor, this); _activeChild.AddTaskListener(this); _activeChild.Spawn(Context); ResetGuardsEvaluation(); return(Status.Running); } /* * If the child with the highest priority guard has not changed, return the status * of the active child. */ ResetGuardsEvaluation(); return(_activeChild.Status); }