Ejemplo n.º 1
0
        /// <summary>
        /// Specialized constructor for creating a ThroughChildren iterator at a node path. Basically, we create an iterator at the parent
        /// then queue up the remaining siblings for next evals in iter state. That allows us to start at a path and not miss the siblings
        /// </summary>
        /// <param name="nodeParent"></param>
        /// <param name="nodePath"></param>
        /// <param name="traversalParameters"></param>
        /// <param name="getChildrenMethodOverride"></param>
        /// <param name="getParentMethodOverride"></param>
        private TreeIter(TTreeNode nodeParent, TreeNodePath nodePath, TreeTraversalParameters <TTreeNode> traversalParameters, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null)
        {
            this.TraversalParameters = traversalParameters;

            //int finalIndex = nodePath.Last();
            //TTreeNode currentTarget = this.State.GetChildrenMethod(nodeParent).ElementAt(finalIndex);
            this.State = new TreeIterState <TTreeNode>(nodeParent, traversalParameters, nodePath);
            this.State.ProcessNextEvaluations(nodePath.Last());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a customizable tree iterator
        /// </summary>
        /// <param name="start">The starting point</param>
        /// <param name="traversalParameters">The custom parameters used to control the traversal</param>
        /// <returns>The iterator that was created</returns>
        public static TreeIter <TTreeNode> CreateIterator(TTreeNode start, TreeTraversalParameters <TTreeNode> traversalParameters)
        {
            if (start == null)
            {
                return(TreeIter <TTreeNode> .End);
            }

            return(new TreeIter <TTreeNode>(start, traversalParameters));
        }
Ejemplo n.º 3
0
        public static TreeIter <TTreeNode> IteratorAt(TTreeNode root, TreeNodePath nodePath, Predicate <TTreeNode> predicate = null, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null)
        {
            var traversalParams = new TreeTraversalParameters <TTreeNode>(root, flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride)
            {
                Predicate   = predicate,
                DepthLimits = depthLimits,
            };

            var iter = TreeIter <TTreeNode> .CreateIteratorAtNodePath(root, nodePath, traversalParams);

            return(FinalizeAndReturnIter(iter, includeSelf, traversalParams.Predicate, start: false));
        }
Ejemplo n.º 4
0
        internal TreeIterState(TTreeNode node, TreeTraversalParameters <TTreeNode> traversalParameters, TreeNodePath nodePath = null)
        {
            m_traversalParameters = traversalParameters;

            this.Target = node;
            this.CurrentNumberOfEvaluations = 0;

            if (nodePath != null)
            {
                this.TargetPath = nodePath;
            }
            else
            {
                this.TargetPath = new TreeNodePath();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Iterate over all the nodes of a particaulr type
        /// </summary>
        /// <typeparam name="T">Tree node type</typeparam>
        /// <param name="root">The tree's root node</param>
        /// <param name="start">The starting point</param>
        /// <param name="predicate">The predicate</param>
        /// <param name="flowDirection">The direction the traversal flows through the tree</param>
        /// <param name="strategy">The traversal strategy</param>
        /// <param name="includeSelf">Should the start node be included</param>
        /// <param name="canTypeBeAncestor">Can the type be derivitive of the passed in type, or must it be an exact match (default is true)</param>
        /// <param name="depthLimits">Depth limits</param>
        /// <param name="getChildrenMethodOverride">The override to the default GetTreeNodeChildren method specified in <see cref="TreeTraversal{TTreeNode}"/>.SetupDefaults, or null to use the default</param>
        /// <param name="getParentMethodOverride">The override to the default GetTreeNodeParents method specified in <see cref="TreeTraversal{TTreeNode}"/>.SetupDefaults, or null to use the default</param>
        /// <returns></returns>
        public static TreeIter <TTreeNode> IterateOverNodesOfType <T> (TTreeNode root, TTreeNode start, Predicate <T> predicate = null, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, bool canTypeBeAncestor = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null)
            where T : class
        {
            var traversalParams = new TreeTraversalParameters <TTreeNode>(root ?? FindRoot(start, getParentMethodOverride), flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride)
            {
                TypeMatching        = new TypeEval(typeof(T), canTypeBeAncestor),
                PruneAfterFirstFind = false,
                DepthLimits         = depthLimits,
            };

            if (predicate != null)
            {
                traversalParams.Predicate = (_obj) => predicate(_obj as T);
            }

            var iter = CreateIterator(start, traversalParams);

            return(FinalizeAndReturnIter(iter, includeSelf, traversalParams.Predicate));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Specialty constructor for creating iter from a root node
        /// </summary>
        /// <param name="start">The root node</param>
        /// <param name="traversalParameters">The parameters to the tree traversal</param>
        /// <param name="getChildrenMethodOverride">An override to the default GetChildren method</param>
        /// <param name="getParentMethodOverride">An override to the default GetParent method</param>
        internal TreeIter(TTreeNode start, TreeTraversalParameters <TTreeNode> traversalParameters)
        {
            this.TraversalParameters = traversalParameters;

            // We want our paths to be root-centric so if start is not root (and there is a root listed)
            //  then we need to give ourselves a starter path from root
            TreeNodePath pathFromRoot = null;

            if (traversalParameters.Root != null && start != traversalParameters.Root)
            {
                var       treePath = new Stack <int>();
                TTreeNode target   = start;
                while (target != null && target != traversalParameters.Root)
                {
                    var parent = this.TraversalParameters.GetParentMethod(target);
                    if (parent == null)
                    {
                        break;
                    }

                    // To path in this way, we must gurantee that the children we get are indexable
                    //  thus this will throw if they are not of IList
                    var children = this.TraversalParameters.GetChildrenMethod.Invoke(parent);
                    if (children is IList listChild)
                    {
                        treePath.Push(listChild.IndexOf(target));
                    }
                    else
                    {
                        treePath.Push(children.Count(_ => _ != target));
                    }

                    target = parent;
                }

                pathFromRoot = new TreeNodePath(treePath);
            }
            this.State = new TreeIterState <TTreeNode>(start, traversalParameters, pathFromRoot);
            this.State.ProcessNextEvaluations();
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Basic constructor
 /// </summary>
 internal TreeIter(TreeIterState <TTreeNode> state, TreeTraversalParameters <TTreeNode> traversalParameters)
 {
     this.State = state;
     this.TraversalParameters = traversalParameters;
 }
Ejemplo n.º 8
0
        internal static TreeIter <TTreeNode> CreateIteratorAtNodePath(TTreeNode root, TreeNodePath nodePath, TreeTraversalParameters <TTreeNode> traversalParameters, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null)
        {
            // If the node path is empty, then we're creating one from the root
            if (nodePath.Count == 0)
            {
                return(new TreeIter <TTreeNode>(root, traversalParameters));
            }

            if (traversalParameters.FlowDirection == eTraversalFlowDirection.ThroughParents)
            {
                // Why is this not supported
                Debug.Fail("Node pathing through parents is not supported");
            }
            else if (traversalParameters.FlowDirection == eTraversalFlowDirection.ThroughChildren)
            {
                // Otherwise we are creating an iterator for the node's parent, but with the next evaluations stocked starting at the final nodepath piece,
                //  then we can just increment by one. This enables us to use the siblings to the indicated start node.
                TTreeNode parentNode = TreeTraversal <TTreeNode> .ParentNodeFromPath(root, nodePath);

                if (parentNode == null)
                {
                    return(End);
                }

                var justBeforeIter = new TreeIter <TTreeNode>(parentNode, nodePath, traversalParameters, getChildrenMethodOverride, getParentMethodOverride);
                return(++justBeforeIter);
            }
            else if (traversalParameters.FlowDirection == eTraversalFlowDirection.ReversedThroughChildren)
            {
                Debug.Fail("Node pathing through parents is not supported");
            }

            return(End);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates a customizable tree iterator
 /// </summary>
 /// <param name="startNode">The node of the tree to start at, or null to start at the root</param>
 /// <param name="traversalParameters">The custom parameters used to control the traversal</param>
 /// <returns>The iterator that was created</returns>
 public TreeIter <TTreeNode> CreateIterator(TTreeNode startNode, TreeTraversalParameters <TTreeNode> traversalParameters)
 {
     traversalParameters.Root = this.Root;
     traversalParameters.SetGetChildrenGetParentOverrideMethods(this.GetChildrenOverride, this.GetParentOverride);
     return(TreeTraversal <TTreeNode> .CreateIterator(startNode ?? this.Root, traversalParameters));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Creates a customizable tree iterator
 /// </summary>
 /// <param name="traversalParameters">The custom parameters used to control the traversal</param>
 /// <returns>The iterator that was created</returns>
 public TreeIter <TTreeNode> CreateIterator(TreeTraversalParameters <TTreeNode> traversalParameters)
 {
     return(this.CreateIterator(this.Root, traversalParameters));
 }