using System.Collections; using System.Collections.Generic; namespace Rokojori { public enum TreeIteratorType { Parent, NextSibling, PreviousSibling, FirstChild, LastChild, LastGrandChild, NextNode, PreviousNode, Parents, DirectChildren, Children, Siblings, PreviousSiblings, NextSiblings, PreviousNodes, NextNodes } public abstract class TreeIterator where N:class { public abstract bool HasNext(); public abstract N Current(); protected abstract void _MoveToNext(); bool safeMoving = true; public void MoveToNext() { if ( safeMoving && ! HasNext() ) { throw new System.Exception( "Has no more elements" ); } _MoveToNext(); } public void ForEach( System.Action callback ) { while ( HasNext() ) { _MoveToNext(); callback( Current() ); } } public N Get( System.Func predicate ) { while ( HasNext() ) { _MoveToNext(); var current = Current(); var result = predicate( current ); if ( result ) { return current; } } return null; } public bool Has( System.Func predicate ) { return Get( predicate ) != null; } public List All( System.Func predicate ) { var list = new List(); while ( HasNext() ) { _MoveToNext(); var current = Current(); var result = predicate( current ); if ( result ) { list.Add( current ); } } return list; } public static TreeIterator GetIterator( TreeIteratorType type, N node, TreeWalker walker ) { switch ( type ) { case TreeIteratorType.Parent: return SingleIterator.Create( walker.Parent( node ) ); case TreeIteratorType.NextSibling: return SingleIterator.Create( walker.NextSibling( node ) ); case TreeIteratorType.PreviousSibling: return SingleIterator.Create( walker.PreviousSibling( node ) ); case TreeIteratorType.FirstChild: return SingleIterator.Create( walker.ChildAt( node, 0 ) ); case TreeIteratorType.LastChild: return SingleIterator.Create( walker.ChildAt( node, walker.NumChildren( node ) - 1 ) ); case TreeIteratorType.LastGrandChild: return SingleIterator.Create( walker.LastGrandChild( node ) ); case TreeIteratorType.NextNode: return SingleIterator.Create( walker.NextNode( node ) ); case TreeIteratorType.PreviousNode: return SingleIterator.Create( walker.PreviousNode( node ) ); case TreeIteratorType.Parents: return ParentsIterator.Create( walker, node ); case TreeIteratorType.DirectChildren: return DirectChildrenIterator.Create( walker, node ); case TreeIteratorType.Children: return ChildrenIterator.Create( walker, node ); case TreeIteratorType.Siblings: return SiblingsIterator.Create( walker, node, true, true ); case TreeIteratorType.PreviousSiblings: return SiblingsIterator.Create( walker, node, true, false ); case TreeIteratorType.NextSiblings: return SiblingsIterator.Create( walker, node, false, true ); case TreeIteratorType.NextNodes: return NodesIterator.Create( walker, node, true ); case TreeIteratorType.PreviousNodes: return NodesIterator.Create( walker, node, false ); } return null; } } }