You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -37,52 +37,88 @@ If you need to hide this property in Godot editor, use `no_editor` option:
37
37
enemy_count:i32,
38
38
```
39
39
40
-
## Property access hooks
40
+
## Property get/set
41
41
42
-
You can add hooks to call methods before and after property value was retrieved or changed.
42
+
Properties can register `set` and `get` methods to be called from Godot.
43
43
44
-
Note that unlike [GDScript's `setget` keyword](https://docs.godotengine.org/en/3.3/getting_started/scripting/gdscript/gdscript_basics.html?#setters-getters), this does _not_ register a custom setter or getter. Instead, it registers a callback which is invoked _before or after_ the set/get occurs, and lacks both parameter and return value.
44
+
Default get/set functions can be registered as per the following example:
45
+
46
+
```rs
45
47
46
-
```rust
47
48
#[derive(NativeClass, Default)]
48
49
#[inherit(Node)]
49
50
structGodotApi {
50
-
// before get
51
-
#[property(before_get ="Self::before_get")]
52
-
prop_before_get:i32,
53
-
54
-
// before set
55
-
#[property(before_set ="Self::before_set")]
56
-
prop_before_set:i32,
51
+
// property registration
52
+
// Note: This is actually equivalent to #[property]
53
+
#[property(get, set)]
54
+
prop:i32,
55
+
}
56
+
```
57
57
58
-
// after get
59
-
#[property(after_get ="Self::after_get")]
60
-
prop_after_get:i32,
58
+
If you need custom setters and getters, you can set them in the `property` attribute such as in the following example:
61
59
62
-
// after set
63
-
#[property(after_set ="Self::after_set")]
64
-
prop_after_set:i32,
60
+
```rust
61
+
#[derive(NativeClass)]
62
+
#[inherit(Node)]
63
+
structHelloWorld {
64
+
// property registration
65
+
#[property(get ="Self::get", set ="Self::set")]
66
+
prop:i32,
65
67
}
66
68
67
-
implGodotApi {
69
+
implHelloWorld {
68
70
fnnew(_owner:&Node) ->Self {
69
-
Self::default()
71
+
HelloWorld { prop:0i32 }
70
72
}
73
+
}
71
74
72
-
fnbefore_get(&self, _owner:TRef<Node>) {
73
-
godot_print!("Before get");
75
+
#[methods]
76
+
implHelloWorld {
77
+
fnget(&self, _owner:TRef<Node>) ->i32 {
78
+
godot_print!("get() -> {}", &self.prop);
79
+
self.prop
74
80
}
75
81
76
-
fnbefore_set(&self, _owner:TRef<Node>) {
77
-
godot_print!("Before set");
82
+
fnset(&mutself, _owner:TRef<Node>, value:i32) {
83
+
godot_print!("set({})", &value);
84
+
self.prop =value;
85
+
}
86
+
}
87
+
```
88
+
89
+
### Note: `get` vs `get_ref`
90
+
91
+
There are two ways to return the property.
92
+
-`get` will return a value of `T` which _must_ result in the value being cloned.
93
+
-`get_ref` must point to a function that returns `&T`, this is useful when working with large data that would be very expensive to copy unnecessarily.
94
+
95
+
Modifying the previous example accordingly results in the following:
96
+
97
+
```rust
98
+
#[derive(NativeClass)]
99
+
#[inherit(Node)]
100
+
structGodotApi {
101
+
// property registration
102
+
#[property(get_ref ="Self::get", set ="Self::set")]
@@ -96,40 +132,42 @@ This is often the case where custom hint behavior is desired for primitive types
96
132
To do so, you can use the [`ClassBuilder`](https://docs.rs/gdnative/latest/gdnative/prelude/struct.ClassBuilder.html) -- such as in the following examples -- to manually register each property and customize how they interface in the editor.
Sometimes it can be useful to expose a value as a property instead of as a function. Properties of this type serve as a _marker_ that can be registered with Godot and viewed in the editor without containing any data in Rust.
199
+
200
+
This can be useful for data (similar to the first sample) where the count serves more as a property of `enemies` rather than as its own distinct data, such as the following:
201
+
202
+
```rs
203
+
structEnemy {
204
+
// Enemy Data
205
+
}
206
+
#[derive(NativeClass)]
207
+
structGodotApi {
208
+
enemies:Vec<Enemy>,
209
+
// Note: As the property is a "marker" property, this will never be used in code.
0 commit comments