One ready Callback, Fully Traced
1. Macros describe the user class
#[derive(GodotClass)] generates GodotClass, base/inheritance relationships,
configuration, construction hooks, and registration shards. A #[godot_api]
implementation of an engine interface records virtual methods such as ready.
2. Extension initialization registers the class
Godot loads the dynamic library and calls initialization for Core, Servers,
Scene, and Editor levels. The binding loads compatible method tables and
auto_register_classes gathers distributed registration shards. It supplies
Godot with create, free, reference, notification, and virtual lookup callbacks.
3. Godot asks for the virtual trampoline
When the scene lifecycle reaches _ready, Godot uses the registered virtual
function pointer. Generated code chooses the callback for this class/API
version and receives raw engine pointers and argument slots.
4. The callback validates and borrows the Rust instance
The trampoline recovers InstanceStorage<T> associated with the Godot object.
A mutable virtual acquires the same exclusive dynamic borrow represented by
GdMut<T>. Re-entrant shared or mutable access fails instead of creating
aliased &mut T.
5. Typed Rust code runs
Arguments have already crossed GodotFfi/conversion traits. The user method
receives &mut self; its Base<Node> provides controlled access to inherited
engine behavior. OnReady fields are initialized before the callback and
validated for required editor assignments.
6. The result returns through the ABI
Return conversion writes the correct Godot representation. The borrow guard is dropped before control returns. The trampoline catches a panic so unwinding cannot cross into C++, reports context, and supplies ABI-appropriate failure behavior.
The engine owns invocation; the binding owns validation and the temporary Rust borrow; user code owns only its class state.