1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//! Provides utilities for bidirectional support between Rust and
//! GDScript for `async` and `await`.
//!
//! This crate provides two macros, both intended for interoperability
//! with GDScript: [`godot_async`] and [`godot_await`]. If you are
//! writing a pure-Rust project that does not need to inter-operate
//! with GDScript, then you probably do NOT need this crate.
//!
//! # Features
//!
//! * `macros` - Exposes the attribute macro `#[gdext_async]`. Enabled
//! by default. This requires the `syn` crate as a dependency.
use *;
use OnceCell;
use Rc;
// Only public for use in macro.
/// If the object is a `GDScriptFunctionState`, await it. If not,
/// return it unmodified. Note that, unlike GDScript, this function
/// does NOT attempt to detect and await signals. Only actual
/// `GDScriptFunctionState` objects will be awaited.
///
/// This is the function used under-the-hood by the [`godot_await!`]
/// macro, but it can also be used independently, for instance, if you
/// need to store the future (as a [`Future`]) and not evaluate it
/// yet.
pub async
/// Convert a block of Rust async code into a Godot task whose
/// completion can safely be awaited from GDScript.
///
/// This macro returns a `Variant` which can be awaited on the
/// GDScript side. If this macro is the entire function body, your
/// function must return `Variant`.
///
/// It is strongly recommended that functions which use this macro
/// take `this: Gd<Self>` via `#[func(gd_self)]` (as opposed to
/// `&self` or `&mut self`) in order to avoid holding a `Gd` binding
/// across an `await` point.
///
/// # Example Usage
///
/// ```rust
/// # use godot::prelude::*;
/// # use gdext_async::godot_async;
/// // Rust
///
/// #[derive(GodotClass)]
/// #[class(init, base=Node)]
/// struct MyRustNode {}
///
/// #[godot_api]
/// impl MyRustNode {
/// #[func(gd_self)]
/// pub fn wait_three_secs(this: Gd<Self>) -> Variant {
/// godot_async! {
/// godot_print!("Before Timer! (2)");
/// let timer = this.get_tree().create_timer(3.0);
/// timer.signals().timeout().to_future().await;
/// godot_print!("After Timer! (3)");
/// }
/// }
/// }
/// ```
///
/// ```gdscript
/// # GDScript
/// extends Node
///
/// func _ready():
/// var node = MyRustNode.new()
/// add_child(node)
/// print("Before Timer! (1)")
/// await node.wait_three_secs()
/// print("After Timer! (4)")
/// ```
/// Await (in Rust) a Godot value, using semantics similar to
/// GDScript's `await`.
///
/// GDScript function state objects will be awaited, while any other
/// value (**including signals**) will be returned verbatim.
///
/// # Example Usage
///
/// ```rust
/// # use godot::prelude::*;
/// # use gdext_async::godot_await;
/// // Rust
///
/// // Note: Ordinary Rust async function, NOT exposed to GDScript.
/// pub async fn fade_out_enemy(mut enemy_node: Gd<Node2D>) {
/// godot_print!("Freeing enemy node ...");
/// godot_await! { enemy_node.call("fade_out", &[]) };
/// godot_print!("Enemy node freed.");
/// }
///
/// ```
///
/// ```gdscript
/// # GDScript
/// extends Node2D
///
/// func fade_out():
/// var tween = create_tween()
/// tween.tween_property(self, "modulate:a", 0.0, 1.0)
/// await tween.finished
/// queue_free()
/// ```
/// Attribute macro that can be applied to `impl` blocks (similar to
/// [`godot_api`]) to enable optional functionality.
///
/// This macro can only be applied to an inherent impl block, not to a
/// trait impl. This macro generates `#[godot_api(secondary)]` blocks,
/// so the relevant struct must have a primary (i.e. non-`secondary`)
/// `#[godot_api]` block.
///
/// ## Async Functions (`#[async_func]` / `#[async_func(gd_self)]`)
///
/// A function in a `gdext_async`-enabled impl block which is tagged
/// with `#[async_func]` will be exported to Godot, similar to
/// `#[func]` on `#[godot_api]`. The exported Godot-side function will
/// be `await`-able in GDScript.
///
/// The annotated function must be `async` and its arguments and
/// return type must be Godot-compatible. That is, arguments must be
/// [`AsArg`](godot::meta::AsArg) and the result type must be
/// [`ToGodot`]. Note that this is a stronger guarantee than
/// `#[func]`, as it is not currently possible to return, for example,
/// `Result<T, E>` from a `#[async_func]` since the type does not
/// implement `ToGodot`.
///
/// `#[async_func]` can be called as `#[async_func(gd_self)]`, which
/// causes the generated GDScript-function to accept `Gd<Self>` rather
/// than an explicit `&self` or `&mut self`. If you are accepting a
/// `self` argument, you almost always want `gd_self`, as holding a
/// `Gd` binding across an `await` point is generally a very bad idea.
///
/// The function will be available both from Rust and from GDScript
/// and can be awaited using the respective `await` keyword in each
/// language.
///
/// `#[rpc]` functions are NOT currently supported by this macro.
///
/// ### Example
///
/// ```
/// # use godot::prelude::*;
/// # use gdext_async_macros::gdext_async;
///
/// #[derive(GodotClass)]
/// #[class(init, base=Node2D)]
/// pub struct Player {}
///
/// #[gdext_async]
/// #[godot_api]
/// impl Player {
/// #[async_func(gd_self)]
/// pub async fn play_item_get_animation(this: Gd<Self>, item_id: i32) -> i32 {
/// // Function body ...
/// unimplemented!()
/// }
///
/// // Also works with static functions
/// #[async_func]
/// pub async fn calculate_item_damage(item_id: i32) -> f32 {
/// unimplemented!()
/// }
/// }
/// ```
pub use gdext_async;