using Godot; using System.Collections.Generic; using System; namespace Rokojori { public static class Nodes { public static T Find( 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( it ); } case NodePathLocatorType.Siblings: { return GetSibling( it ); } case NodePathLocatorType.DirectChildrenAndSiblings: { var child = GetDirectChild( it ); if ( child != null ) { return child; } return GetSibling( it ); } case NodePathLocatorType.AnyChildren: { return GetAnyChild( it ); } case NodePathLocatorType.SiblingsAndAnyChildren: { var sibling = GetSibling( it ); if ( sibling != null ) { return sibling; } return GetAnyChild( it );; } } return default(T); } public static void ForEachInScene( Action callback ) where T:class { var root = Root.Get().GetWindow(); ForEach( root, callback ); } public static List AllInScene( Func filter = null) where T:class { var list = new List(); ForEachInScene( t => { if ( filter == null || filter( t ) ) { list.Add( t ); } } ); return list; } public static List AllIn( Node root, Func filter = null, bool includeRoot = true) where T:class { var list = new List(); ForEach( root, t => { if ( ! includeRoot && t == root ) { return; } if ( filter == null || filter( t ) ) { list.Add( t ); } } ); return list; } public static void ForEach( Node root, Action 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( Node node ) where T:Node { if ( node == null ) { return null; } var parent = node.GetParent(); if ( parent == null ) { return null; } return GetDirectChild( parent ); } public static T CreateChildIn( 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( this Node parent, string name = null ) where T:Node,new() { return CreateChildIn( 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( List nodes ) where N:Node { nodes.ForEach( n => RemoveAndDelete( n ) ); } public static void RemoveAndDeleteChildrenOfType( 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( 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 GetDirectChildren( Node parent ) where T:Node { if ( parent == null ) { return null; } var list = new List(); 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( Node parent, System.Action 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 MapDirectChildren( Node parent, System.Func mapper ) where T:Node { var list = new List(); ForEachDirectChild( parent, c => list.Add( mapper( c ) ) ); return list; } public static int TypeIndex( 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( 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 callback ) { for ( int i = 0; i < nodes.Length; i++ ) { nodesWalker.Iterate( nodes[ i ], callback ); } } } }