rj-action-library/Runtime/Godot/Nodes.cs

420 lines
8.4 KiB
C#

using Godot;
using System.Collections.Generic;
using System;
namespace Rokojori
{
public static class Nodes
{
public static T Find<T>( Node root, NodePathLocatorType type = NodePathLocatorType.DirectChildren, int parentOffset = 0 ) where T:Node
{
var it = root;
while ( parentOffset > 0 && it != null )
{
it = it.GetParent();
parentOffset --;
}
if ( it == null )
{
return default(T);
}
switch ( type )
{
case NodePathLocatorType.DirectChildren:
{
return GetDirectChild<T>( it );
}
case NodePathLocatorType.Siblings:
{
return GetSibling<T>( it );
}
case NodePathLocatorType.DirectChildrenAndSiblings:
{
var child = GetDirectChild<T>( it );
if ( child != null )
{
return child;
}
return GetSibling<T>( it );
}
case NodePathLocatorType.AnyChildren:
{
return GetAnyChild<T>( it );
}
case NodePathLocatorType.SiblingsAndAnyChildren:
{
var sibling = GetSibling<T>( it );
if ( sibling != null )
{
return sibling;
}
return GetAnyChild<T>( it );;
}
}
return default(T);
}
public static void ForEachInScene<T>( Action<T> callback ) where T:class
{
var root = Root.Get().GetWindow();
ForEach<T>( root, callback );
}
public static List<T> AllInScene<T>( Func<T,bool> filter = null) where T:class
{
var list = new List<T>();
ForEachInScene<T>(
t =>
{
if ( filter == null || filter( t ) )
{
list.Add( t );
}
}
);
return list;
}
public static List<T> AllIn<T>( Node root, Func<T,bool> filter = null, bool includeRoot = true) where T:class
{
var list = new List<T>();
ForEach<T>( root,
t =>
{
if ( ! includeRoot && t == root )
{
return;
}
if ( filter == null || filter( t ) )
{
list.Add( t );
}
}
);
return list;
}
public static void ForEach<T>( Node root, Action<T> callback ) where T:class
{
var walker = nodesWalker;
walker.Iterate( root,
( n )=>
{
var t = n as T;
if ( t == null )
{
return;
}
callback( t );
}
,false );
}
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 CreateChildIn<T>( Node parent, string name = null ) where T:Node,new()
{
var t = new T();
parent.AddChild( t );
t.Owner = parent.Owner;
if ( name != null )
{
t.Name = name;
}
return t;
}
public static T CreateChild<T>( this Node parent, string name = null ) where T:Node,new()
{
return CreateChildIn<T>( parent, name );
}
public static Node CopyNode( Node node, Node parent )
{
var copy = node.Duplicate();
parent.AddChild( copy );
copy.Owner = parent.Owner;
return copy;
}
public static Node DeepCopyTo( this Node node, Node parent )
{
return CopyNodeHierarchy( node, parent );
}
public static Node CopyNodeHierarchy( Node from, Node parent )
{
var copy = CopyNode( from, parent );
for ( int i = 0; i < from.GetChildCount(); i++ )
{
var child = from.GetChild( i );
CopyNodeHierarchy( child, copy );
}
return copy;
}
public static void RemoveAndDelete( Node node )
{
var parent = node.GetParent();
if ( parent != null )
{
parent.RemoveChild( node );
}
node.QueueFree();
}
public static void RemoveAndDeleteAll<N>( List<N> nodes ) where N:Node
{
nodes.ForEach( n => RemoveAndDelete( n ) );
}
public static void RemoveAndDeleteChildrenOfType<T>( Node parent, bool includeInternal = false ) where T:Node
{
if ( parent == null )
{
return;
}
var numChildren = parent.GetChildCount( includeInternal );
for ( int i = numChildren - 1; i >= 0; i-- )
{
var node = parent.GetChild( i, includeInternal );
var t = node as T;
if ( t == null )
{
continue;
}
parent.RemoveChild( node );
node.QueueFree();
}
}
public static void RemoveAndDeleteChildren( Node parent, bool includeInternal = false )
{
if ( parent == null )
{
return;
}
var numChildren = parent.GetChildCount( includeInternal );
for ( int i = numChildren - 1; i >= 0; i-- )
{
var node = parent.GetChild( i, includeInternal );
parent.RemoveChild( node );
node.QueueFree();
}
}
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;
}
public static List<T> GetDirectChildren<T>( Node parent ) where T:Node
{
if ( parent == null )
{
return null;
}
var list = new List<T>();
var numChildren = parent.GetChildCount();
for ( int i = 0; i < numChildren; i++ )
{
var node = parent.GetChild( i );
var script = node.GetScript();
// RJLog.Log( "Node is", typeof(T), node.Name, node.GetType(), script.GetType(), ">>", ( node is T ) );
if ( ! ( node is T ) )
{
continue;
}
list.Add( node as T );
}
return list;
}
public static void ForEachDirectChild<T>( Node parent, System.Action<T> action ) where T:Node
{
if ( parent == null || action == null )
{
return;
}
var numChildren = parent.GetChildCount();
for ( int i = 0; i < numChildren; i++ )
{
var node = parent.GetChild( i );
if ( ! ( node is T ) )
{
continue;
}
action( node as T );
}
}
public static List<U> MapDirectChildren<T,U>( Node parent, System.Func<T,U> mapper ) where T:Node
{
var list = new List<U>();
ForEachDirectChild<T>( parent, c => list.Add( mapper( c ) ) );
return list;
}
public static int TypeIndex<T>( Node parent, T child ) where T:Node
{
var counter = 0;
var numChildren = parent.GetChildCount();
for ( int i = 0; i < numChildren; i++ )
{
var node = parent.GetChild( i );
if ( node is T )
{
if ( node == child )
{
return counter;
}
counter++;
}
}
return -1;
}
static NodesWalker nodesWalker = new NodesWalker();
public static T GetAnyChild<T>( Node parent ) where T:Node
{
var result = nodesWalker.Find( parent,
( n )=>
{
var castedNode = n as T;
// RJLog.Log( "Testing", n.UniqueNameInOwner, castedNode != null, n.GetType() );
return castedNode != null;
},
true );
return (T) result;
}
/*
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 );
}
}
}
}