module Godot::NodeContext

Overview

=========================================================================== NodeContext: Active Execution Context for Ergonomic Node Lookups

Manages the active Godot::Node context on the calling thread/fiber, allowing bare/unary operators like ~("$Path") and ~("%Unique") to resolve relative to self without explicit receiver notation.

Performance & Zero-Cost Guarantees:

Defined in:

libgodot/node_context.cr

Class Method Summary

Class Method Detail

def self.current : Node | Nil #

Returns the currently executing Godot::Node, if any.

Used internally by unary operators like ~"Path" to resolve relative paths without requiring an explicit receiver reference.


def self.current=(node : Node | Nil) #

Sets the currently executing Godot::Node.

Prefer using NodeContext.scope instead of setting this directly to ensure that the previous context is always restored even if an exception occurs.


def self.current? : Node | Nil #

Nilable alias for NodeContext.current.


def self.resolve_active_node(path : String) : Node #

Resolves a node path against the active node context.

Raises Godot::NodeNotFoundError if no node context is active or if the node cannot be found at the given relative or unique path.

Supported Syntax:

  • Relative child: ~"Sprite2D" or ~"Visuals/MeshInstance3D"
  • Scene Unique Node: ~"%HealthBar"
  • Absolute tree path: ~"/root/Main/Player"
  • Parent navigation: ~"../Sibling"

def self.resolve_active_node_as(type : T.class, preferred_name : String | Nil = nil) : T forall T #

Resolves a typed node against the active node context.

Search order:

  1. Direct child by class name (e.g., "Sprite2D" for Sprite2D)
  2. Scene Unique Node by class name (e.g., "%Sprite2D")
  3. First child in children that matches type T (or inherits from T in native ClassDB)

Raises Godot::NodeNotFoundError if no matching node is found.

Example:

cam = NodeContext.resolve_active_node_as(Camera3D)
cam.fov = 75.0_f32

def self.resolve_active_node_or_nil(type : T.class, preferred_name : String | Nil = nil) : T | Nil forall T #

Resolves a node against the active node context or returns nil (get_node_or_null parity).

Handles Class types and nilable union types like (Sprite2D | Nil), returning typed T?.

Search order:

  1. Direct child by class name
  2. Scene Unique Node by class name ("%TypeName")
  3. First child in children that matches type T (or inherits from T in native ClassDB)

Returns nil if no matching child node exists or if no node context is active.

Example:

if weapon = NodeContext.resolve_active_node_or_nil(WeaponSlot?)
  weapon.equip(sword)
end

def self.resolve_active_node_path_as(path : String, type : T.class) forall T #

Resolves a typed node at a specific path relative to the active node context. Handles nilable types (e.g., MyNodeType?) by returning nil if missing.

Example:

sprite = NodeContext.resolve_active_node_path_as("Visuals/Sprite2D", Sprite2D)
opt_cam = NodeContext.resolve_active_node_path_as("Camera3D", Camera3D?)

def self.resolve_active_regex(regex : Regex) : Node | Nil #

Resolves a node against the active node context matching a regex pattern.


def self.resolve_active_regex_all(regex : Regex) : Array(Node) #

Resolves all nodes against the active node context matching a regex pattern.


def self.scope(node : Node | Nil, &) #

Scopes execution of a block to the specified node context, restoring previous context upon exit even if an exception is raised.

All virtual methods (_ready, _process, _physics_process, etc.) are automatically wrapped in this scope by _godot_call_virtual.

Example:

NodeContext.scope(player_node) do
  sprite = ~"Sprite2D" # Resolves relative to player_node
  sprite.modulate = Godot::Color.new(1.0, 0.0, 0.0)
end

def self.scope(obj : Object, &) #

Scopes execution of a block if the object is a Node, or executes directly.

Allows safe, uniform scoping over arbitrary Godot::Object instances.