165 lines
3.7 KiB
C#
165 lines
3.7 KiB
C#
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<N> 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<N> callback )
|
|
{
|
|
while ( HasNext() )
|
|
{
|
|
_MoveToNext();
|
|
callback( Current() );
|
|
}
|
|
}
|
|
|
|
public N Get( System.Func<N,bool> predicate )
|
|
{
|
|
while ( HasNext() )
|
|
{
|
|
_MoveToNext();
|
|
|
|
var current = Current();
|
|
var result = predicate( current );
|
|
|
|
if ( result )
|
|
{
|
|
return current;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public bool Has( System.Func<N,bool> predicate )
|
|
{
|
|
return Get( predicate ) != null;
|
|
}
|
|
|
|
public List<N> All( System.Func<N,bool> predicate )
|
|
{
|
|
var list = new List<N>();
|
|
|
|
while ( HasNext() )
|
|
{
|
|
_MoveToNext();
|
|
|
|
var current = Current();
|
|
var result = predicate( current );
|
|
|
|
if ( result )
|
|
{
|
|
list.Add( current );
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static TreeIterator<N> GetIterator( TreeIteratorType type, N node, TreeWalker<N> walker )
|
|
{
|
|
|
|
switch ( type )
|
|
{
|
|
case TreeIteratorType.Parent:
|
|
return SinlgeIterator<N>.Create( walker.Parent( node ) );
|
|
|
|
case TreeIteratorType.NextSibling:
|
|
return SinlgeIterator<N>.Create( walker.NextSibling( node ) );
|
|
|
|
case TreeIteratorType.PreviousSibling:
|
|
return SinlgeIterator<N>.Create( walker.PreviousSibling( node ) );
|
|
|
|
case TreeIteratorType.FirstChild:
|
|
return SinlgeIterator<N>.Create( walker.ChildAt( node, 0 ) );
|
|
|
|
case TreeIteratorType.LastChild:
|
|
return SinlgeIterator<N>.Create( walker.ChildAt( node, walker.NumChildren( node ) - 1 ) );
|
|
|
|
case TreeIteratorType.LastGrandChild:
|
|
return SinlgeIterator<N>.Create( walker.LastGrandChild( node ) );
|
|
|
|
case TreeIteratorType.NextNode:
|
|
return SinlgeIterator<N>.Create( walker.NextNode( node ) );
|
|
|
|
case TreeIteratorType.PreviousNode:
|
|
return SinlgeIterator<N>.Create( walker.PreviousNode( node ) );
|
|
|
|
|
|
case TreeIteratorType.Parents:
|
|
return ParentsIterator<N>.Create( walker, node );
|
|
|
|
|
|
case TreeIteratorType.DirectChildren:
|
|
return DirectChildrenIterator<N>.Create( walker, node );
|
|
|
|
case TreeIteratorType.Children:
|
|
return ChildrenIterator<N>.Create( walker, node );
|
|
|
|
|
|
case TreeIteratorType.Siblings:
|
|
return SiblingsIterator<N>.Create( walker, node, true, true );
|
|
|
|
case TreeIteratorType.PreviousSiblings:
|
|
return SiblingsIterator<N>.Create( walker, node, true, false );
|
|
|
|
case TreeIteratorType.NextSiblings:
|
|
return SiblingsIterator<N>.Create( walker, node, false, true );
|
|
|
|
|
|
case TreeIteratorType.NextNodes:
|
|
return NodesIterator<N>.Create( walker, node, true );
|
|
|
|
case TreeIteratorType.PreviousNodes:
|
|
return NodesIterator<N>.Create( walker, node, false );
|
|
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
} |