Initial Commit

This commit is contained in:
Josef 2024-05-04 10:26:16 +02:00
commit 8f1ce37f3b
18 changed files with 1178 additions and 0 deletions

View File

@ -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 ] );
}
}
}
}

View File

@ -0,0 +1,19 @@
using Godot;
namespace Rokojori
{
public class Actions
{
public static Trigger( RJAction action )
{
if ( action == null )
{
return;
}
action.Trigger();
}
}
}

View File

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

View File

@ -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();
}
}
}

15
Runtime/Events/Null.cs Normal file
View File

@ -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(){}
}
}

View File

@ -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();
}
}
}

73
Runtime/Godot/Nodes.cs Normal file
View File

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

View File

@ -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();
}
}
}

31
Runtime/Godot/Root.cs Normal file
View File

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

24
Runtime/Godot/Unique.cs Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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