using Godot; using System.Collections.Generic; using System; using Rokojori.Extensions; namespace Rokojori; [RokojoriActionCoreExport] public static class NodeState { public static bool IsVisible( this Node n ) { if ( n is Node3D ) { return ( n as Node3D ).Visible; } if ( n is Node2D ) { return ( n as Node2D ).Visible; } if ( n is CanvasItem ) { return ( n as CanvasItem ).Visible; } return false; } public static bool IsProcessingInHierarchy( this Node n ) { if ( n.ProcessMode == Node.ProcessModeEnum.Disabled ) { return false; } if ( n.ProcessMode == Node.ProcessModeEnum.Always ) { return true; } var paused = n.GetTree().Paused; if ( n.ProcessMode == Node.ProcessModeEnum.Pausable ) { return ! paused; } if ( n.ProcessMode == Node.ProcessModeEnum.WhenPaused ) { return paused; } var p = n.GetParent(); if ( p == null ) { return ! paused; } return p.IsProcessingInHierarchy(); } public static void ConfigureWith( Node target, NodeStateConfiguration configuration ) { PartialConfigure( target, configuration.processEnabled, configuration.inputEnabled, configuration.physicsEnabled, configuration.signalsEnabled, configuration.visible, configuration.setProcessMode, configuration.processMode ); } public static void SetNodeState( this Node target, NodeStateConfiguration configuration ) { ConfigureWith( target, configuration ); } public static void SetVisibility( this Node target, bool visible ) { PartialConfigure( target, Trillean.Any, Trillean.Any, Trillean.Any, Trillean.Any, TrilleanLogic.FromBool( visible ), false, Node.ProcessModeEnum.Inherit ); } public static void PartialConfigure( Node target, Trillean processEnabled, Trillean inputEnabled,Trillean physicsEnabled, Trillean signalsEnabled,Trillean visible, bool setProcessMode, Node.ProcessModeEnum processMode ) { if ( ! Node.IsInstanceValid( target ) ) { return; } if ( Trillean.Any != processEnabled ) { target.SetProcess( TrilleanLogic.ToBool( processEnabled ) ); } if ( Trillean.Any != inputEnabled ) { target.SetProcessInput( TrilleanLogic.ToBool( inputEnabled ) ); } if ( Trillean.Any != physicsEnabled ) { target.SetPhysicsProcess( TrilleanLogic.ToBool( physicsEnabled ) ); } if ( Trillean.Any != signalsEnabled ) { target.SetBlockSignals( ! TrilleanLogic.ToBool( signalsEnabled ) ); } if ( setProcessMode ) { target.ProcessMode = processMode; } if ( Trillean.Any != visible ) { var n = target; var visibleFlag = TrilleanLogic.ToBool( visible ); if ( n is Node3D ) { ( n as Node3D ).Visible = visibleFlag; } if ( n is Node2D ) { ( n as Node2D ).Visible = visibleFlag; } if ( n is CanvasItem ) { ( n as CanvasItem ).Visible = visibleFlag; } } DispatchNodeStateChanged( target ); } static void DispatchNodeStateChanged( Node target) { #if !ROKOJORI_ACTION_CORE_GD if ( target is iNodeState ins ) { ins.OnNodeStateChanged(); } #else /* if target.has_method( "on_node_state_changed" ): var ins:Variant = target ins.on_node_state_changed() */ GDGlue.CommentToGD(); #endif } public static void Configure( Node n, bool processEnabled, bool inputEnabled, bool physicsEnabled, bool signalsEnabled, Node.ProcessModeEnum processMode, bool visible ) { if ( n == null || ! Node.IsInstanceValid( n ) ) { return; } n.SetProcess( processEnabled ); n.SetProcessInput( inputEnabled ); n.SetPhysicsProcess( physicsEnabled ); n.SetBlockSignals( ! signalsEnabled ); n.ProcessMode = processMode; if ( n is Node3D n3 ) { n3.Visible = visible; } if ( n is Node2D n2 ) { n2.Visible = visible; } if ( n is CanvasItem ci ) { ci.Visible = visible; } DispatchNodeStateChanged( n ); if ( n is CollisionShape3D cs ) { cs.Disabled = ! physicsEnabled; } } public static void SetNode( Node n, bool enabled ) { Configure( n, enabled, enabled, enabled, enabled, enabled ? Node.ProcessModeEnum.Inherit : Node.ProcessModeEnum.Disabled, enabled ); } public static void SetAll( Node[] nodes, bool enabled ) { foreach ( var n in nodes ) { SetNode( n, enabled ); } } public static void Enable( this Node n ) { SetNode( n, true ); } public static void EnableAll( params Node[] n ) { SetAll( n, true ); } public static void Disable( this Node n ) { SetNode( n, false ); } public static void DisableAll( params Node[] n ) { SetAll( n, false ); } public static void SetEnabledState( this Node n, bool isEnabled ) { if ( isEnabled ) { n.Enable(); } else { n.Disable(); } } } public interface iNodeState { public void OnNodeStateChanged(); }