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