Support for `gd_self` in custom getters/setters
- Dominant language
- Rust
- Stars
- 5.2k
- Forks
- 312
- Avg merge
- 12h 59m
- Merged PRs (30d)
- 9
Description
`gd_self` is great in virtual functions for preventing double-borrow issues. I frequently want to write code like this.
```rust
#[derive(GodotClass)]
#[class(base = Node2D)]
pub struct Player {
#[var(pub, set)]
health: i32,
}
#[godot_api]
impl Player {
#[signal]
pub fn health_updated();
#[func]
pub fn set_health(&mut self, health: i32) {
self.health = health;
self.signals().health_updated().emit();
}
}
```
Problem is, I still hold a `&mut self` while that signal (and anyone who responds to it) is firing, which means it's basically impossible to respond to this signal on the Rust side without double-borrowing. I'd *like* to write
```rust
#[func]
pub fn set_health(this: Gd, health: i32) {
this.bind_mut().health = health;
// Mutable borrow via bind_mut() ends here.
this.signals().health_updated().emit();
}
```
But `#[var]` is hard-coded to look for `&self` and `&mut self`. It would be great to be able to (possibly with an argument to `#[var]`) take `Gd` in getters/setters as well.
Contributor guide
Research direction
Start by tracing how the #[var] attribute handles &self and &mut self getters and setters, then compare that path with the gd_self pattern using Gd and bind_mut(). Determine how custom getters/setters could release the mutable borrow before emitting a signal, and define how any #[var] argument should select that behavior. Done means a custom setter can use Gd and safely emit health_updated without a double borrow, with coverage for the example behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100