Engine signals with `Gd<T>` parameters can receive null
- Dominant language
- Rust
- Stars
- 5.2k
- Forks
- 312
- Avg merge
- 12h 59m
- Merged PRs (30d)
- 9
Description
Signal parameters of object type are generated as `Gd`, 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:
```rust
#[godot_api]
impl IEditorPlugin for MyPlugin {
fn enter_tree(&mut self) {
self.signals()
.scene_changed()
.connect(|scene_root: Gd| {
// 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>` everywhere.
- Technically correct, but requires `unwrap()` even if object parameters are guaranteed non-null.
2. Keep `Gd`, add a `*_nullable` overload with `Option>`, 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` (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.
Contributor guide
Research direction
Start by reviewing the signal parameter generation and the proposed hand-maintained list in godot-codegen/src/special_cases.rs, using EditorPlugin::scene_changed and EditorPlugin::resource_saved as concrete cases. Determine and document the nullability strategy before changing the affected bindings. Done means nullable Godot object signal parameters no longer panic when Godot passes null, while non-nullable parameters retain appropriate handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100