rj-action-library/Runtime/Graphs/Trees/TreeIterator.cs

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;
}
}
}