Exemple #1
0
        public override void OnStart()
        {
            int count = ChildCount();

            ChildStatuses = new Status[count];

            // Set the branch iterators. Branch iterators have this parallel node as their root.
            // Offset level order by +1 since the parallel parent is not included in branch traversal.
            BranchIterators = Enumerable
                              .Range(0, count)
                              .Select(i => new BehaviourIterator(Tree, levelOrder + 1))
                              .ToArray();

            // Assign the branch iterator to nodes not under any parallel nodes.
            // Children under parallel nodes will have iterators assigned by the local parallel parent.
            // Each branch under a parallel node use their own branch iterator.
            for (int i = 0; i < count; i++)
            {
                BehaviourIterator branchIterator = BranchIterators[i];
                foreach (BehaviourNode node in TreeTraversal.PreOrderSkipChildren(GetChildAt(i), n => n is ParallelComposite))
                {
                    node.Iterator = branchIterator;
                }
            }
        }
Exemple #2
0
        public void Interrupt(BehaviourNode subroot, bool bFullInterrupt = false)
        {
            // Interrupt this subtree.
            subroot.Iterator.StepBackInterrupt(subroot, bFullInterrupt);

            // Look for parallel nodes under the subroot.
            // Since the parallel count is usually small, we
            // can just do a linear iteration to interrupt multiple
            // parallel nodes.
            for (int pIndex = 0; pIndex < _parallelNodeCount; ++pIndex)
            {
                Parallel p = _parallelNodes[pIndex];

                if (IsUnderSubtree(subroot, p))
                {
                    for (int itrIndex = 0; itrIndex < p.ChildCount(); ++itrIndex)
                    {
                        BehaviourIterator itr = p.GetIterator(itrIndex);

                        // Only interrupt running iterators.
                        if (itr.IsRunning)
                        {
                            // Get the child of the parallel node, and interrupt the child subtree.
                            int           childIndex = itr.FirstInTraversal;
                            BehaviourNode firstNode  = allNodes[childIndex];

                            itr.StepBackInterrupt(firstNode.Parent, bFullInterrupt);
                        }
                    }
                }
            }
        }
        // Helper method to pre-process the tree before calling Start on nodes.
        // Mainly does caching and sets node index orders.
        private void PreProcess()
        {
            SetPostandLevelOrders();

            mainIterator = new BehaviourIterator(this, 0);
            activeTimers = new Utility.UpdateList <Utility.Timer>();

            SetRootIteratorReferences();
        }
Exemple #4
0
        /// <summary>
        /// Processes the tree to calculate certain properties like node priorities,
        /// caching observers, and syncinc parallel iterators.
        /// The root must be set.
        /// </summary>
        private void preProcess()
        {
            if (_root == null)
            {
                Debug.Log("The tree must have a valid root in order to be pre-processed");
                return;
            }

            CalculateTreeOrders();

            _mainIterator = new BehaviourIterator(this, 0);

            // Setup a new list for the observer nodes.
            _observerAborts = new List <ConditionalAbort>();

            cacheObservers();
            syncIterators();
        }
Exemple #5
0
        private void SyncIterators()
        {
            SyncParallelIterators();

            _root._iterator = _mainIterator;

            BehaviourIterator itr = _mainIterator;
            var parallelRoots     = new Stack <BehaviourNode>();

            // This function handles assigning the iterator and skipping nodes.
            // The parallel root uses the same iterator as its parent, but the children
            // of the parallel node use their own iterator.
            Func <BehaviourNode, bool> skipAndAssign = (node) =>
            {
                node._iterator = itr;

                bool bIsParallel = node as Parallel != null;

                if (bIsParallel)
                {
                    parallelRoots.Push(node);
                }

                return(bIsParallel);
            };

            Action <BehaviourNode> nothing = (node) => { };

            // Assign the main iterator to nodes not under any parallel nodes.
            TreeIterator <BehaviourNode> .Traverse(_root, nothing, skipAndAssign);

            while (parallelRoots.Count != 0)
            {
                BehaviourNode parallel = parallelRoots.Pop();

                // Do passes for each child, using the sub iterator associated with that child.
                for (int i = 0; i < parallel.ChildCount(); ++i)
                {
                    itr = (parallel as Parallel).GetIterator(i);
                    TreeIterator <BehaviourNode> .Traverse(parallel.GetChildAt(i), nothing, skipAndAssign);
                }
            }
        }