using Godot; using System.Collections.Generic; using System; using System.Threading.Tasks; using System.Reflection; namespace Rokojori { public static class NodeExtensions { public static void CallDeferred( this Node node, System.Action action ) { Callable.From( action ).CallDeferred(); } public static int GetChildCountOfType( this Node node ) { var count = 0; for ( int i = 0; i < node.GetChildCount(); i++ ) { if ( node.GetChild( i ) is N ) { count ++; } } return count; } public static void EnsureChildCount( this Node node, int neededChildCount, Action callback = null ) where N:Node,new() { var segments = neededChildCount; var ownCount = node.GetChildCount(); if ( ownCount == segments ) { return; } if ( ownCount > segments ) { node.DestroyChildrenRange( segments, ownCount - segments ); ownCount = segments; } for ( int i = ownCount; i < segments; i++ ) { var n = node.CreateChild(); if ( callback != null ) { callback( n ); } } } public static List MapDirectChildren( this Node node, Func mapper ) where T:Node { var list = new List(); node.ForEachDirectChild( n => { if ( n is T t) { list.Add( mapper( t ) ); } } ); return list; } public static bool HasDirectChildWithName( this Node node, string name, bool includeInternal = false ) { return IndexOfDirectChildWithName( node, name, includeInternal ) != -1; } public static int IndexOfDirectChildWithName( this Node node, string name, bool includeInternal = false ) { var numKids = node.GetChildCount( includeInternal ); for ( int i = 0; i < numKids; i++ ) { var child = node.GetChild( i, includeInternal ); if ( child is T t && child.Name == name ) { return i; } } return -1; } public static T GetNextSiblingOrChild( this Node node ) where T:Node { var index = node.GetIndex(); var p = node.GetParent(); for ( int i = index + 1; i < p.GetChildCount(); i++ ) { var child = p.GetChild( i ); if ( child != null && child is T t ) { return t; } } return Nodes.GetAnyChild( node ); } } }