public static void SetupDefaults(GetTreeNodeChildren <TTreeNode> getChildren, GetTreeNodeParent <TTreeNode> getParent = null) { GetChildrenMethod = getChildren ?? throw new ArgumentNullException("getChildren", "The default getChildren method cannot be null"); if (getParent != null) { GetParentMethod = getParent; } }
/// <summary> /// Create parameters to the tree traversal /// </summary> /// <param name="root">The tree's root</param> /// <param name="flowDirection">The direction to traverse</param> /// <param name="strategy">The traversal strategy</param> /// <param name="getChildrenMethodOverride">The get children method to use (or null to use default)</param> /// <param name="getParentMethodOverride">The get parent method to use (or null to use default)</param> public TreeTraversalParameters(TTreeNode root, eTraversalFlowDirection flowDirection, eTraversalStrategy strategy, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { this.Root = root; this.FlowDirection = flowDirection; this.ChildTraversalStrategy = strategy; this.TypeMatching = null; this.Predicate = null; this.PruneAfterFirstFind = false; this.MaxNumberOfEvaluations = -1; // All this.TrackReentrancy = false; this.DepthLimits = null; m_getChildrenMethodOverride = getChildrenMethodOverride; m_getParentMethodOverride = getParentMethodOverride; }
public static TTreeNode ParentNodeFromPath(TTreeNode root, TreeNodePath nodePath, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { GetTreeNodeChildren <TTreeNode> getChildren = getChildrenMethodOverride ?? GetChildrenMethod; TTreeNode eval = root; for (int pathIndex = 0; pathIndex < nodePath.Count - 1; ++pathIndex) { eval = getChildren(eval).ElementAtOrDefault(nodePath[pathIndex]); if (eval == null) { return(null); } } return(eval); }
public static TTreeNode NodeAt(TTreeNode start, TreeNodePath nodePath, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { GetTreeNodeChildren <TTreeNode> getChildren = getChildrenMethodOverride ?? GetChildrenMethod; TTreeNode eval = start; foreach (int ind in nodePath) { eval = getChildren(eval).ElementAtOrDefault(ind); if (eval == null) { return(null); } } return(eval); }
public static T GetFirstParentOfType <T> (TTreeNode root, TTreeNode start, Predicate <T> predicate = null, bool includeSelf = true, bool canTypeBeAncestor = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) where T : class, TTreeNode { var iter = IterateOverNodesOfType <T>(root, start, predicate, eTraversalFlowDirection.ThroughParents, eTraversalStrategy.Default, includeSelf, canTypeBeAncestor, depthLimits, getChildrenMethodOverride, getParentMethodOverride); if (iter != TreeIter <TTreeNode> .End) { return((T)iter.Node); } return(null); }
/// <summary> /// Creates a basic tree iterator /// </summary> /// <param name="root">The tree root, will search from start up if not specified - if this is undesired, pass in start for root (or call overloaded function without root which uses start for root)</param> /// <param name="start">The starting point</param> /// <param name="strategy">The traversal strategy to use</param> /// <param name="flowDirection">How the traversal flows through the tree</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>The iterator that was created</returns> public static TreeIter <TTreeNode> CreateIterator(TTreeNode root, TTreeNode start, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(CreateIterator(start, new TreeTraversalParameters <TTreeNode>(root ?? FindRoot(start, getParentMethodOverride), flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride) )); }
internal void SetGetChildrenGetParentOverrideMethods(GetTreeNodeChildren <TTreeNode> getChildren, GetTreeNodeParent <TTreeNode> getParent) { m_getChildrenMethodOverride = getChildren; m_getParentMethodOverride = getParent; }
/// <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()); }
public static TTreeNode GetFirstChildWhichPasses(TTreeNode start, Predicate <TTreeNode> predicate, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(GetFirstChildWhichPasses(null, start, predicate, flowDirection, strategy, includeSelf, depthLimits, getChildrenMethodOverride, getParentMethodOverride)); }
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)); }
/// <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)); }
/// <summary> /// Creates an iterator for iterating over all nodes which pass a predicate /// </summary> /// <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="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>The iterator created</returns> public static TreeIter <TTreeNode> IterateOverAllNodesWhichPass(TTreeNode root, TTreeNode start, Predicate <TTreeNode> predicate, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { var iter = CreateIterator(start, new TreeTraversalParameters <TTreeNode>(root ?? FindRoot(start, getParentMethodOverride), flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride) { Predicate = predicate, DepthLimits = depthLimits }); return(FinalizeAndReturnIter(iter, includeSelf, predicate)); }
public static IEnumerable <TTreeNode> All(TTreeNode root, TTreeNode start, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { TreeIter <TTreeNode> iter = CreateIterator(root, start, flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride); if (!includeSelf) { ++iter; } while (iter != TreeIter <TTreeNode> .End) { yield return(iter.Node); ++iter; } }
public static IEnumerable <TTreeNode> All(TTreeNode start, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, bool includeSelf = true, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(All(FindRoot(start), start, flowDirection, strategy, includeSelf, getChildrenMethodOverride, getParentMethodOverride)); }
public static TTreeNode FindNextSiblingOrCousin(TTreeNode start, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(FindNextSiblingOrCousin(null, start, getChildrenMethodOverride, getParentMethodOverride)); }
public static TTreeNode FindNextSiblingOrCousin(TTreeNode root, TTreeNode start, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { root = root ?? FindRoot(start, getParentMethodOverride); var getChildren = getChildrenMethodOverride ?? GetChildrenMethod; var getParent = getParentMethodOverride ?? GetParentMethod; return(_DoFindNextSiblingOrCousin(start)); TTreeNode _DoFindNextSiblingOrCousin(TTreeNode eval) { if (eval == root) { return(null); } var parent = getParent(eval); var children = getChildren(parent).SkipWhile(c => c != eval).Skip(1); if (children.Any()) { return(children.First()); } else { return(_DoFindNextSiblingOrCousin(parent)); } } }
public static T GetFirstChildOfType <T> (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 { return(GetFirstChildOfType <T>(null, start, predicate, flowDirection, strategy, includeSelf, canTypeBeAncestor, depthLimits, getChildrenMethodOverride, getParentMethodOverride)); }
/// <summary> /// Tree constructor /// </summary> /// <param name="root">The tree root node</param> /// <param name="getChildrenOverride">A local override to the default TreeTraverser registered GetChildren</param> /// <param name="getParentOverride">A local override to the default TreeTraverser registered GetParent</param> public TreeTraverser(TTreeNode root, GetTreeNodeChildren <TTreeNode> getChildrenOverride = null, GetTreeNodeParent <TTreeNode> getParentOverride = null) { this.Root = root; this.GetChildrenOverride = getChildrenOverride; this.GetParentOverride = getParentOverride; }
public static TTreeNode GetFirstParentWhichPasses(TTreeNode start, Predicate <TTreeNode> predicate, bool includeSelf = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(GetFirstParentWhichPasses(null, start, predicate, includeSelf, depthLimits, getChildrenMethodOverride, getParentMethodOverride)); }
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); }
public static TTreeNode GetFirstParentWhichPasses(TTreeNode root, TTreeNode start, Predicate <TTreeNode> predicate, bool includeSelf = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { var iter = IterateOverAllNodesWhichPass(root, start, predicate, eTraversalFlowDirection.ThroughParents, eTraversalStrategy.Default, includeSelf, depthLimits, getChildrenMethodOverride, getParentMethodOverride); if (iter != TreeIter <TTreeNode> .End) { return(iter.Node); } return(null); }
public static T GetFirstParentOfType <T> (TTreeNode start, Predicate <T> predicate = null, bool includeSelf = true, bool canTypeBeAncestor = true, LevelRestriction depthLimits = null, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) where T : class, TTreeNode { return(GetFirstParentOfType <T>(null, start, predicate, includeSelf, canTypeBeAncestor, depthLimits, getChildrenMethodOverride, getParentMethodOverride)); }
/// <summary> /// Creates a basic tree iterator /// </summary> /// <param name="start">The starting point (also the acting root of the tree)</param> /// <param name="strategy">The traversal strategy to use</param> /// <returns>The iterator that was created</returns> public static TreeIter <TTreeNode> CreateIterator(TTreeNode start, eTraversalFlowDirection flowDirection = DefaultTraversalFlowDirection, eTraversalStrategy strategy = DefaultTraversalStrategy, GetTreeNodeChildren <TTreeNode> getChildrenMethodOverride = null, GetTreeNodeParent <TTreeNode> getParentMethodOverride = null) { return(CreateIterator(null, start, flowDirection, strategy, getChildrenMethodOverride, getParentMethodOverride)); }