/// <summary>
        /// Tells the iterator to abort the current running subtree and jump to the aborter.
        /// </summary>
        /// <param name="aborter"></param>
        public void OnAbort(ConditionalAbort aborter)
        {
            BehaviourNode parent           = aborter.Parent;
            int           terminatingIndex = BehaviourNode.kInvalidOrder;

            if (parent)
            {
                terminatingIndex = parent.preOrderIndex;
            }

            // If an abort node is the root, then we need to empty the entire traversal.
            // We can achieve this by setting the terminating index to the invalid index, which is an invalid index
            // and will empty the traversal.
            while (_traversal.Count != 0 && _traversal.Peek() != terminatingIndex)
            {
                StepBackAbort();
            }

            // Only composite nodes need to worry about which of their subtrees fired an abort.
            if (parent.MaxChildCount() > 1)
            {
                parent.OnAbort(aborter);
            }

            // Any requested traversals are cancelled on abort.
            _requestedTraversals.Clear();

            Traverse(aborter);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Test if the aborter may abort the node.
        /// Make sure that the node orders are pre-computed before calling this function.
        /// This method is mainly used by the editor.
        /// </summary>
        /// <param name="aborter">The node to perform the abort.</param>
        /// <param name="node">The node that gets aborted.</param>
        /// <returns></returns>
        public static bool IsAbortable(ConditionalAbort aborter, BehaviourNode node)
        {
            // This makes sure that dangling nodes do not show that they can abort nodes under main tree.
            if (aborter.preOrderIndex == kInvalidOrder)
            {
                return(false);
            }

            // Parallel subtrees cannot abort each other.
            if (aborter.Parent && aborter.Parent is Parallel)
            {
                return(false);
            }

            switch (aborter.abortType)
            {
            case AbortType.LowerPriority:
                return
                    (!BehaviourTree.IsUnderSubtree(aborter, node) &&
                     BehaviourTree.IsUnderSubtree(aborter.Parent, node) &&
                     aborter.Priority() > GetSubtree(aborter.Parent, node).Priority());

            // Self aborts always interrupt, regardless of the condition.
            case AbortType.Self:
                return(BehaviourTree.IsUnderSubtree(aborter, node));

            case AbortType.Both:
                return
                    (BehaviourTree.IsUnderSubtree(aborter, node) ||
                     (BehaviourTree.IsUnderSubtree(aborter.Parent, node) &&
                      aborter.Priority() > GetSubtree(aborter.Parent, node).Priority()));
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Called when a composite node has a child that activates when it aborts.
        /// </summary>
        /// <param name="child"></param>
        protected internal override void OnAbort(ConditionalAbort child)
        {
            // The default behaviour is to set the current child index of the composite
            // node to this child's index.
            if (IsChild(child))
            {
                _currentChildIndex = child._indexOrder;
            }

            else
            {
                Debug.LogError("The node is not parented to this composite node.");
            }
        }
Ejemplo n.º 4
0
        // Note on multiple aborts:
        // If there are multiple satisfied aborts, then
        // the tree picks the highest order abort (left most).
        private void TickObservers()
        {
            for (int i = 0; i < _observerAborts.Count; ++i)
            {
                ConditionalAbort node = _observerAborts[i];

                // The iterator must be running since aborts can only occur under
                // actively running subtrees.
                if (!node.Iterator.IsRunning)
                {
                    continue;
                }

                // If the condition is true then apply an abort.
                if (node.IsAbortSatisfied())
                {
                    node.Iterator.OnAbort(node);
                }
            }
        }
Ejemplo n.º 5
0
 // Does nothing since tasks do not have children.
 protected internal sealed override void OnAbort(ConditionalAbort aborter)
 {
 }
 /// <summary>
 /// Called when a child fires an abort.
 /// </summary>
 /// <param name="aborter"></param>
 public virtual void OnAbort(ConditionalAbort aborter)
 {
 }
Ejemplo n.º 7
0
 // Does nothing since tasks do not have children.
 public sealed override void OnAbort(ConditionalAbort aborter)
 {
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Called when a child fires an abort.
 /// </summary>
 /// <param name="aborter"></param>
 protected internal virtual void OnAbort(ConditionalAbort aborter)
 {
 }