Function spawn
pub fn spawn(future: impl Future<Output = ()> + 'static) -> TaskHandleExpand description
Create a new async background task.
This function allows creating a new async task in which Godot signals can be awaited, like it is possible in GDScript. If a reference to Self is
not flexible enough regarding lifetimes, your function calling spawn() can capture the state in a Gd<Self> pointer instead. The
TaskHandle that is returned provides synchronous introspection into the current state of the task.
Signals can be converted to futures in the following ways:
| Signal type | Simple future | Fallible future (handles freed object) |
|---|---|---|
| Untyped | Signal::to_future() | Signal::to_fallible_future() |
| Typed | TypedSignal::to_future() | TypedSignal::to_fallible_future() |
§Panics
If called from any other thread than the main thread.
§Examples
An example using timers:
ⓘ
#[derive(GodotClass)]
#[class(init, base=Node)]
struct Game {
base: Base<Node>,
}
#[godot_api]
impl INode for Game {
fn ready(&mut self) {
// Use `connect_other_gd` so that `Self::show_messages` receives a
// `Gd<Self>` pointer instead of `&mut Self` reference.
self.base()
.get_node_as::<Node2D>("Player")
.signals()
.ready()
.builder()
.connect_other_gd(self, Self::show_messages);
}
}
#[godot_api]
impl Game {
// Async function that implements sleep using Godot timers.
async fn sleep(&self, duration: f64) {
# let timer = self.base().get_tree().create_timer(duration);
// Use a future to wait for the timeout signal.
# timer.signals().timeout().to_future().await;
}
// `#[func(gd_self)]`: receive `Gd<Self>` instead of `&mut Self`.
#[func(gd_self)]
fn show_messages(this: Gd<Self>) {
// `spawn()` will capture the `this` variable -- this can't be done with
// `&mut self` due to lifetimes.
godot::task::spawn(async move {
godot_print!("Start!");
this.bind().sleep(1.0).await;
godot_print!("One second later!")
});
}
}With typed signals:
#[derive(GodotClass)]
#[class(init)]
struct Building {
base: Base<RefCounted>,
}
#[godot_api]
impl Building {
#[signal]
fn constructed(seconds: u32);
}
let house = Building::new_gd();
godot::task::spawn(async move {
println!("Wait for construction...");
// Emitted arguments can be fetched in tuple form.
// If the signal has no parameters, you can skip `let` and just await the future.
let (seconds,) = house.signals().constructed().to_future().await;
println!("Construction complete after {seconds}s.");
});With untyped signals:
let node = Node::new_alloc();
let signal = Signal::from_object_signal(&node, "signal");
godot::task::spawn(async move {
println!("Starting task...");
// Explicit generic arguments needed, here `()`:
signal.to_future::<()>().await;
println!("Node has changed: {}", node.get_name());
});