Skip to content

Engine signals with Gd<T> parameters can receive null #1663

Description

@Bromeon

Signal parameters of object type are generated as Gd<T>, which is non-nullable. But Godot passes null for some of them, so
connecting a handler to such a signal can panic and isn't easily avoidable by the user.

The clearest case is EditorPlugin::scene_changed, whose scene_root is null when the last scene tab is closed:

#[godot_api]
impl IEditorPlugin for MyPlugin {
    fn enter_tree(&mut self) {
        self.signals()
            .scene_changed()
            .connect(|scene_root: Gd<Node>| {
                // Never runs -- closing the last scene tab passes null, and conversion panics before we get here.
                godot_print!("now editing {scene_root}");
            });
    }
}

EditorPlugin::resource_saved (resource: Resource) has the same problem. There are likely more.


Some ideas:

  1. Use Option<Gd<T>> everywhere.

    • Technically correct, but requires unwrap() even if object parameters are guaranteed non-null.
  2. Keep Gd<T>, add a *_nullable overload with Option<Gd<T>>, deprecating the original.

    • Can be added incrementally, as users report problems.
    • Increases API surface, deprecation churn.
    • Note: nullability is per-object, not per-signal. Needs decision on what to do for signals with multiple object parameters.
  3. Same signal uses either Gd or Option<Gd> (exclusive).

    • Hand-maintained list of affected (class, signal, parameter) triples in godot-codegen/src/special_cases.rs (but also true for other approaches).
    • Needs ahead-of-time work to find out which are nullable and which not; hard to correct later without minor version bump.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugc: engineGodot classes (nodes, resources, ...)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions