Initial Commit
This commit is contained in:
		
						commit
						8f1ce37f3b
					
				|  | @ -0,0 +1,26 @@ | |||
| 
 | ||||
| using Godot; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   [GlobalClass] | ||||
|   public partial class ActionList : RJAction | ||||
|   { | ||||
|     [Export] | ||||
|     public RJAction[] actions; | ||||
|     [Export] | ||||
|     public bool triggerDirectChildren = true; | ||||
|      | ||||
|     protected override void _OnTrigger() | ||||
|     { | ||||
|       for ( int i = 0; i < actions.Length; i++ ) | ||||
|       {  | ||||
|         Actions.Trigger( actions[ i ] ); | ||||
|       }       | ||||
| 
 | ||||
|        | ||||
| 
 | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,19 @@ | |||
| 
 | ||||
| using Godot; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public class Actions | ||||
|   { | ||||
|     public static Trigger( RJAction action ) | ||||
|     { | ||||
|       if ( action == null ) | ||||
|       { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       action.Trigger(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,74 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System; | ||||
| using System.Linq; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
| 
 | ||||
|   public class ReadonlyEventProperty<T>: EventSlot<T> | ||||
|   { | ||||
|     protected T _value; | ||||
|     public T value | ||||
|     { | ||||
|       get { return _value; } | ||||
|       protected set { } | ||||
|     }     | ||||
|   }   | ||||
| 
 | ||||
|   public class EventProperty<T>:ReadonlyEventProperty<T> | ||||
|   { | ||||
|     public new T value | ||||
|     { | ||||
|       get { return _value; } | ||||
|       set  | ||||
|       {  | ||||
|         if ( IsEqual( _value, value ) ) | ||||
|         { | ||||
|           return; | ||||
|         } | ||||
| 
 | ||||
|         _value = value;  | ||||
|         DispatchEvent(); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     public virtual void DispatchEvent() | ||||
|     { | ||||
|        _actions.ForEach( a => { if ( a != null ){ a( _value ); } } ); | ||||
|        | ||||
|       _ClearOnceActions(); | ||||
| 
 | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     protected bool IsEqual( T oldValue, T newValue ) | ||||
|     { | ||||
|       if ( oldValue == null && newValue == null ) | ||||
|       { | ||||
|         return true; | ||||
|       } | ||||
| 
 | ||||
|       if ( oldValue == null || newValue == null ) | ||||
|       { | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       if ( EqualityComparer<T>.Default.Equals( oldValue , newValue ) ) | ||||
|       { | ||||
|         return true; | ||||
|       } | ||||
| 
 | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     public void SetSilent( T value ) | ||||
|     { | ||||
|       _value = value; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,48 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System; | ||||
| using System.Linq; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {    | ||||
|   public class EventSlot<T> | ||||
|   { | ||||
|     protected List<Action<T>> _actions = new List<Action<T>>(); | ||||
|     List<Action<T>> _once = new List<Action<T>>(); | ||||
| 
 | ||||
|     public bool hasListeners => _once.Count > 0 || _actions.Count > 0; | ||||
| 
 | ||||
|     public void AddAction( Action<T> action ) | ||||
|     { | ||||
|       _actions.Add( action ); | ||||
|     } | ||||
| 
 | ||||
|     public void RemoveAction( Action<T> action ) | ||||
|     { | ||||
|       _actions.Remove( action ); | ||||
|     } | ||||
| 
 | ||||
|     public void Once( Action<T> action ) | ||||
|     { | ||||
|       _actions.Add( action ); | ||||
|       _once.Add( action ); | ||||
|     } | ||||
| 
 | ||||
|     protected void _ClearOnceActions() | ||||
|     { | ||||
|       _once.ForEach( a => { _actions.Remove( a ); } ); | ||||
|       _once.Clear(); | ||||
|     }  | ||||
| 
 | ||||
|     public void DispatchEvent( T t ) | ||||
|     { | ||||
|       _actions.ForEach( a => { if ( a != null ){ a( t ); } } ); | ||||
|        | ||||
|       _ClearOnceActions(); | ||||
| 
 | ||||
|     } | ||||
|   } | ||||
|    | ||||
| } | ||||
|  | @ -0,0 +1,15 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System; | ||||
| using System.Linq; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public class Null | ||||
|   {  | ||||
|     private Null(){} | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| using Godot; | ||||
| using System.Text; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public class HierarchyName | ||||
|   { | ||||
|     public static string Of( Node node, string seperator = "/" ) | ||||
|     { | ||||
|       if ( node == null ) | ||||
|       { | ||||
|         return "null"; | ||||
|       } | ||||
| 
 | ||||
|       var list = new List<string>(); | ||||
| 
 | ||||
|       var it = node; | ||||
| 
 | ||||
|       while ( it != null ) | ||||
|       { | ||||
|         list.Add( it.Name ); | ||||
|         it = it.GetParent(); | ||||
|       } | ||||
| 
 | ||||
|       list.Reverse(); | ||||
| 
 | ||||
| 
 | ||||
|       var sb = new StringBuilder(); | ||||
| 
 | ||||
|       for ( int i = 0; i < list.Count; i++) | ||||
|       { | ||||
|         if ( i != 0 ) | ||||
|         { | ||||
|           sb.Append( seperator ); | ||||
|         } | ||||
| 
 | ||||
|         sb.Append( list[ i ] ); | ||||
|       } | ||||
| 
 | ||||
|       return sb.ToString(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,73 @@ | |||
| using Godot; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public class Nodes | ||||
|   { | ||||
|     public static T GetSibling<T>( Node node ) where T:Node | ||||
|     { | ||||
|       if ( node == null ) | ||||
|       { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       var parent = node.GetParent(); | ||||
| 
 | ||||
|       if ( parent == null ) | ||||
|       { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       return GetDirectChild<T>( parent ); | ||||
|     } | ||||
| 
 | ||||
|     public static T GetDirectChild<T>( Node parent ) where T:Node | ||||
|     { | ||||
|       if ( parent == null ) | ||||
|       { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       var numChildren = parent.GetChildCount(); | ||||
|        | ||||
|       for ( int i = 0; i < numChildren; i++ ) | ||||
|       { | ||||
|         var node = parent.GetChild( i ); | ||||
| 
 | ||||
|         if ( node is T ) | ||||
|         { | ||||
|           return (T)node; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       return null; | ||||
|     } | ||||
| 
 | ||||
|     static NodesWalker nodesWalker = new NodesWalker(); | ||||
| 
 | ||||
|     public static T GetAnyChild<T>( Node parent ) where T:Node | ||||
|     { | ||||
|       return (T) nodesWalker.Find( parent, ( n )=> n is T, true ); | ||||
|     } | ||||
| 
 | ||||
|     public static void Enable( Node n, bool affectProcess = true, bool affectPhysicsProcess = true, bool affectInput = true ) | ||||
|     { | ||||
|       SetState.SetStateOfNode( NodeStateType.Enabled, n, affectProcess, affectPhysicsProcess, affectInput ); | ||||
|     } | ||||
| 
 | ||||
|     public static void Disable( Node n, bool affectProcess = true, bool affectPhysicsProcess = true, bool affectInput = true ) | ||||
|     { | ||||
|       SetState.SetStateOfNode( NodeStateType.Disabled, n, affectProcess, affectPhysicsProcess, affectInput ); | ||||
|     } | ||||
| 
 | ||||
|     public static void Iterate( Node[] nodes, System.Action<Node> callback ) | ||||
|     { | ||||
|       for ( int i = 0; i < nodes.Length; i++ ) | ||||
|       { | ||||
|         nodesWalker.Iterate( nodes[ i ], callback ); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,44 @@ | |||
| using Godot; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public class NodesWalker: TreeWalker<Node> | ||||
|   {  | ||||
|     static NodesWalker _singleton = new NodesWalker(); | ||||
|     public static NodesWalker Get()  | ||||
|     { | ||||
|       return _singleton; | ||||
|     } | ||||
| 
 | ||||
|     public override Node Parent( Node n ) | ||||
|     { | ||||
|       if ( n == null ) | ||||
|       { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       return n.GetParent(); | ||||
|     } | ||||
| 
 | ||||
|     public override Node ChildAt( Node n, int index ) | ||||
|     { | ||||
|       if ( n == null ) | ||||
|       { | ||||
|         return null; | ||||
|       } | ||||
| 
 | ||||
|       return n.GetChild( index ); | ||||
|     } | ||||
| 
 | ||||
|     public override int NumChildren( Node n ) | ||||
|     { | ||||
|       if ( n == null ) | ||||
|       { | ||||
|         return 0; | ||||
|       } | ||||
| 
 | ||||
|       return n.GetChildCount(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| using Godot; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| {   | ||||
|   public partial class Root:Node | ||||
|   { | ||||
|     private static Root _singleton; | ||||
| 
 | ||||
|     public override void _Ready() | ||||
|     { | ||||
|       _singleton = this; | ||||
|     } | ||||
| 
 | ||||
|     public static SceneTree Tree() | ||||
|     { | ||||
|       return _singleton.GetTree(); | ||||
|     } | ||||
| 
 | ||||
|     public static Window Window() | ||||
|     { | ||||
|       return Tree().Root; | ||||
|     } | ||||
| 
 | ||||
|     public static Root Get() | ||||
|     { | ||||
|       var r = Window(); | ||||
|       return _singleton; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,24 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| using Godot; | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class Unique<N> where N:Node | ||||
|   { | ||||
|     private static N _singleton; | ||||
| 
 | ||||
|     public static N Get() | ||||
|     { | ||||
|       if ( _singleton != null ) | ||||
|       { | ||||
|         return _singleton; | ||||
|       } | ||||
| 
 | ||||
|       _singleton = Nodes.GetAnyChild<N>( Root.Window() ); | ||||
|        | ||||
|       return _singleton; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,56 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class ChildrenIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     N parent; | ||||
|     N current; | ||||
|     N end; | ||||
|     N next; | ||||
|     TreeWalker<N> walker; | ||||
|      | ||||
|     public static ChildrenIterator<N> Create( TreeWalker<N> walker, N node ) | ||||
|     { | ||||
|       var iterator = new ChildrenIterator<N>(); | ||||
| 
 | ||||
|       iterator.walker = walker; | ||||
|       iterator.current = null; | ||||
|       iterator.parent = node; | ||||
|       iterator.end = walker.IterationEndOf( node ); | ||||
|       iterator.next = walker.NextNode( node ); | ||||
| 
 | ||||
|       if ( iterator.next == iterator.end ) | ||||
|       { | ||||
|         iterator.next = null; | ||||
|       } | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       return next != null; | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       current = next; | ||||
| 
 | ||||
|       next = walker.NextNode( current ); | ||||
| 
 | ||||
|       if ( next == end ) | ||||
|       { | ||||
|         next = null; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,42 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class DirectChildrenIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     N parent; | ||||
|     N current; | ||||
|     int index = 0; | ||||
|     TreeWalker<N> walker; | ||||
|      | ||||
|     public static DirectChildrenIterator<N> Create( TreeWalker<N> walker, N node ) | ||||
|     { | ||||
|       var iterator = new DirectChildrenIterator<N>(); | ||||
| 
 | ||||
|       iterator.parent = node; | ||||
|       iterator.walker = walker; | ||||
|       iterator.current = null; | ||||
|       iterator.index = -1; | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       return ( index + 1 ) < walker.NumChildren( parent ); | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       index ++; | ||||
|       current = walker.ChildAt( parent, index ); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,50 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class NodesIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     N node; | ||||
|     N current; | ||||
|     bool isForward = true; | ||||
|     TreeWalker<N> walker; | ||||
| 
 | ||||
|     public static NodesIterator<N> Create( TreeWalker<N> walker, N node, bool forward ) | ||||
|     { | ||||
|       var iterator = new NodesIterator<N>(); | ||||
| 
 | ||||
|       iterator.walker = walker; | ||||
|       iterator.node = node; | ||||
|       iterator.current = null; | ||||
|       iterator.isForward = forward; | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       return node != null; | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       if ( isForward ) | ||||
|       { | ||||
|         node =  walker.NextNode( node ); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         node =  walker.PreviousNode( node ); | ||||
|       } | ||||
| 
 | ||||
|       current = node; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,40 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class ParentsIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     N iterator; | ||||
|     N current; | ||||
|     TreeWalker<N> walker; | ||||
|      | ||||
|     public static ParentsIterator<N> Create( TreeWalker<N> walker, N start ) | ||||
|     { | ||||
|       var iterator = new ParentsIterator<N>(); | ||||
| 
 | ||||
|       iterator.current = null; | ||||
|       iterator.iterator = start; | ||||
|       iterator.walker = walker; | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       return walker.HasParent( iterator ); | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       iterator = walker.Parent( iterator ); | ||||
|       current = iterator; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,66 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public class SiblingsIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     bool nextSiblings = true; | ||||
| 
 | ||||
|     N parent; | ||||
|     N current; | ||||
|     int index = 0; | ||||
|     int nodeIndex = 0; | ||||
|     TreeWalker<N> walker; | ||||
| 
 | ||||
|     public static SiblingsIterator<N> Create( TreeWalker<N> walker, N node, bool previous = true, bool next = true ) | ||||
|     { | ||||
|       var iterator = new SiblingsIterator<N>(); | ||||
| 
 | ||||
|       iterator.parent = node; | ||||
|       iterator.walker = walker; | ||||
|       iterator.current = null;      | ||||
|       iterator.nodeIndex = walker.ChildIndexOf( node ); | ||||
|       iterator.index = previous ? -1 : iterator.nodeIndex; | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       if ( ! nextSiblings ) | ||||
|       { | ||||
|         return ( index + 1 ) < nodeIndex; | ||||
|       } | ||||
| 
 | ||||
|       var nextIndex = index + 1; | ||||
| 
 | ||||
|       if ( nextIndex == nodeIndex ) | ||||
|       { | ||||
|         nextIndex ++; | ||||
|       } | ||||
|        | ||||
|       return nextIndex < walker.NumChildren( parent ); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       index ++; | ||||
|        | ||||
|       if ( index == nodeIndex ) | ||||
|       { | ||||
|         index ++; | ||||
|       } | ||||
| 
 | ||||
|       current = walker.ChildAt( parent, index ); | ||||
|     } | ||||
|   } | ||||
|    | ||||
| } | ||||
|  | @ -0,0 +1,38 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori.Core | ||||
| { | ||||
|   public class SinlgeIterator<N>: TreeIterator<N> where N:class | ||||
|   { | ||||
|     N node; | ||||
|     N current; | ||||
| 
 | ||||
|     public static SinlgeIterator<N> Create( N node ) | ||||
|     { | ||||
|       var iterator = new SinlgeIterator<N>(); | ||||
| 
 | ||||
|       iterator.node = node; | ||||
|       iterator.current = null; | ||||
| 
 | ||||
|       return iterator; | ||||
|     } | ||||
| 
 | ||||
|     public override bool HasNext() | ||||
|     { | ||||
|       return node != null; | ||||
|     } | ||||
| 
 | ||||
|     public override N Current() | ||||
|     { | ||||
|       return current; | ||||
|     }  | ||||
| 
 | ||||
|     protected override void _MoveToNext() | ||||
|     { | ||||
|       current = node; | ||||
|       node = null;       | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,165 @@ | |||
| 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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,322 @@ | |||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| 
 | ||||
| namespace Rokojori | ||||
| { | ||||
|   public abstract class TreeWalker<N> where N:class | ||||
|   { | ||||
|     public abstract N Parent( N node );   | ||||
|      | ||||
|     public abstract N ChildAt( N node, int index );   | ||||
|      | ||||
|     public abstract int NumChildren( N node );   | ||||
|      | ||||
|     public bool HasChildren( N node ) | ||||
|     { | ||||
|   		return NumChildren( node ) > 0; | ||||
|   	} | ||||
|   	 | ||||
|     public bool HasParent( N node ) | ||||
|     { | ||||
|   		return Parent( node ) != null; | ||||
|   	} | ||||
|   	 | ||||
|      | ||||
|     public int ChildIndexOf( N node ) | ||||
|     { | ||||
|       var p = Parent( node ); | ||||
| 
 | ||||
|       if ( p == null ) | ||||
|       { | ||||
|         return -1; | ||||
|       } | ||||
|        | ||||
|       var numKids = NumChildren( p ); | ||||
|        | ||||
|       for ( var i = 0; i<numKids; i++ ) | ||||
|       { | ||||
|         if ( ChildAt( p, i ) == node ) | ||||
|         { | ||||
|           return i; | ||||
|         } | ||||
|       } | ||||
|        | ||||
|       return -1; | ||||
|        | ||||
|     } | ||||
|   	 | ||||
|     public N SiblingAt( N node, int index ) | ||||
|   	{ | ||||
|   		var p = Parent( node ); | ||||
|        | ||||
|   		if ( p == null || index<0 || index >= NumChildren( p ) ) | ||||
|   		{ return null; } | ||||
| 
 | ||||
|   		return ChildAt( p, index ); | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public N NextSibling( N node ) | ||||
|     { | ||||
|       var index = ChildIndexOf( node );       | ||||
|       return SiblingAt( node, index+1 ); | ||||
|     } | ||||
|      | ||||
|      | ||||
|     public N PreviousSibling( N node ) | ||||
|     { | ||||
|       var index = ChildIndexOf( node );       | ||||
|       return SiblingAt( node, index-1 ); | ||||
|     } | ||||
|      | ||||
|      | ||||
|     public bool HasSiblingAt( N node, int index ) | ||||
|   	{ | ||||
|   		var p = Parent( node ); | ||||
|   		if ( p == null || index<0 || index >= NumChildren( p ) ) | ||||
|   		{ return false; } | ||||
|   		return true; | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public N FirstChild( N node ) | ||||
|     { | ||||
|   		return NumChildren( node )<=0?null:ChildAt( node, 0 ); | ||||
|   	} | ||||
|   	 | ||||
|   	 | ||||
|     public N LastChild( N node ) | ||||
|     { | ||||
|   		var num = NumChildren( node ); | ||||
|   		return num <= 0 ? null : ChildAt( node, num - 1 ); | ||||
|   	} | ||||
|   	 | ||||
|   	 | ||||
|     public N NextNode( N node ) | ||||
|     { | ||||
|   		if ( HasChildren( node ) ) | ||||
|   		{ | ||||
|   			return FirstChild( node ); | ||||
|   		} | ||||
|   		 | ||||
|   		var next = NextSibling( node ); | ||||
|   		 | ||||
|   		if ( next != null ) | ||||
|   		{ | ||||
|   			return next; | ||||
|   		} | ||||
| 
 | ||||
|   		var parent = Parent( node ); | ||||
|   		 | ||||
|   		while ( parent != null ) | ||||
|   		{ | ||||
|   			var n = NextSibling( parent ); | ||||
| 
 | ||||
|   			if ( n != null ) | ||||
|   			{ | ||||
|   				return n; | ||||
|   			} | ||||
| 
 | ||||
|   			parent = Parent( parent ); | ||||
|   		} | ||||
|   		return null; | ||||
|   	} | ||||
|   	 | ||||
|   	 | ||||
|     public N PreviousNode( N node ) | ||||
|     { | ||||
|   		var prev = PreviousSibling( node ); | ||||
|   		 | ||||
|   		if ( prev != null ) | ||||
|   		{ | ||||
|   			while ( HasChildren( prev ) ) | ||||
|   			{ | ||||
|   				prev = LastChild( prev ); | ||||
|   			} | ||||
|   			return prev; | ||||
|   		} | ||||
| 
 | ||||
|   		return Parent( node ); | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public N RootParent( N node ) | ||||
|     { | ||||
|   		node = Parent( node ); | ||||
| 
 | ||||
|   		if ( node == null ) | ||||
|   		{ | ||||
|   			return null; | ||||
|   		} | ||||
| 
 | ||||
|   		while ( HasParent( node ) ) | ||||
|   		{ | ||||
|   			node = Parent( node ); | ||||
|   		} | ||||
| 
 | ||||
|   		return node; | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public N LastGrandChild( N node ) | ||||
|     { | ||||
|   		if ( HasChildren( node ) ) | ||||
|   		{ | ||||
|   			node = LastChild( node ); | ||||
| 
 | ||||
|   			while ( HasChildren( node ) ) | ||||
|   			{ | ||||
|   				node = LastChild( node ); | ||||
|   			} | ||||
|          | ||||
|   			return node; | ||||
|   		} | ||||
|        | ||||
|   		return null; | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public bool IsChildOf( N child, N parent ) | ||||
|   	{ | ||||
|   		var p = Parent( child ); | ||||
| 
 | ||||
|   		while ( p != null ) | ||||
|   		{ | ||||
|   			if ( p == parent ) | ||||
|   			{ | ||||
|   				return true; | ||||
|   			} | ||||
|   			p = Parent( p ); | ||||
|   		} | ||||
| 
 | ||||
|   		return false; | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public int NumParents( N node ) | ||||
|     { | ||||
|   		var num = 0; | ||||
|   		var p = Parent( node ); | ||||
| 
 | ||||
|   		while ( p != null ) | ||||
|   		{ | ||||
|   			num++; | ||||
|   			p = Parent( p ); | ||||
|   		} | ||||
| 
 | ||||
|   		return num; | ||||
|   	} | ||||
|      | ||||
|      | ||||
|     public N LastOuterNode( N node ) | ||||
|     {  	 | ||||
|       var its = 0; | ||||
|       var max = 10000; | ||||
| 
 | ||||
| 			while ( HasChildren( node ) ) | ||||
| 			{ | ||||
|         its++; | ||||
| 
 | ||||
|         if ( its > max ) | ||||
|         { | ||||
|           throw new System.Exception(); | ||||
|         } | ||||
|          | ||||
| 				node = LastChild( node ); | ||||
| 			} | ||||
| 
 | ||||
|   		return node; | ||||
|   	} | ||||
|   	 | ||||
|   	 | ||||
|     public N NextNonChild( N node ) | ||||
|     { | ||||
|   		return NextNode( LastOuterNode( node ) ); | ||||
|   	}     | ||||
|      | ||||
|     public N IterationEndOf( N node ) | ||||
|     { | ||||
|       return NextNonChild( node ); | ||||
|     } | ||||
| 
 | ||||
|     public void Iterate( N node, System.Action<N> callback, bool childrenOnly = false ) | ||||
|     { | ||||
|       var end = IterationEndOf( node ); | ||||
|       var it = node; | ||||
| 
 | ||||
|       if ( childrenOnly ) | ||||
|       { | ||||
|         it = NextNode( it );  | ||||
|       } | ||||
| 
 | ||||
|       while ( it != end ) | ||||
|       { | ||||
|         callback( it ); | ||||
|         it = NextNode( it ); | ||||
|       }  | ||||
|     } | ||||
| 
 | ||||
|     public N Find( N node, System.Predicate<N> predicate, bool childrenOnly ) | ||||
|     { | ||||
|       var end = IterationEndOf( node ); | ||||
|       var it = node; | ||||
| 
 | ||||
|       if ( childrenOnly ) | ||||
|       { | ||||
|         it = NextNode( it );  | ||||
|       } | ||||
| 
 | ||||
|       while ( it != end ) | ||||
|       { | ||||
|         if ( predicate( it ) ) | ||||
|         { | ||||
|           return it; | ||||
|         } | ||||
| 
 | ||||
|         it = NextNode( it ); | ||||
|       }  | ||||
| 
 | ||||
|       return null; | ||||
|     } | ||||
| 
 | ||||
|     public void Filter( List<N> list, N node, System.Predicate<N> predicate, bool childrenOnly ) | ||||
|     { | ||||
|       System.Action<N> addToList = ( N n ) =>  | ||||
|       { | ||||
|         if ( predicate( n ) ) | ||||
|         { | ||||
|           list.Add( n ); | ||||
|         } | ||||
|       }; | ||||
| 
 | ||||
|       Iterate( node, addToList, childrenOnly ); | ||||
|     } | ||||
| 
 | ||||
|     public void FilterAndMap<U>( List<U> list, N node, System.Predicate<N> predicate, System.Func<N,U> mapper, bool childrenOnly ) | ||||
|     { | ||||
|       System.Action<N> addToList = ( N n ) =>  | ||||
|       { | ||||
|         if ( predicate( n ) ) | ||||
|         { | ||||
|           list.Add( mapper( n ) ); | ||||
|         } | ||||
|       }; | ||||
| 
 | ||||
|       Iterate( node, addToList, childrenOnly ); | ||||
|     } | ||||
| 
 | ||||
|     public void Map<U>( List<U> list, N node, System.Predicate<N> predicate, System.Func<N,U> mapper, bool childrenOnly ) | ||||
|     { | ||||
|       System.Action<N> addToList = ( N n ) =>  | ||||
|       { | ||||
|         list.Add( mapper( n ) ); | ||||
|       }; | ||||
| 
 | ||||
|       Iterate( node, addToList, childrenOnly ); | ||||
|     } | ||||
|      | ||||
|      | ||||
|   } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	 Josef
						Josef