godot-rust / godot-rust/gdext

Support for `gd_self` in custom getters/setters

Open
#1,692 6 comments 1 reaction 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.