Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

book: Use new API spawn_future_local #1533

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
290 changes: 166 additions & 124 deletions book/listings/Cargo.lock

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions book/listings/main_event_loop/3/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::thread;
use std::time::Duration;

use glib::{clone, MainContext};
use glib::clone;
use gtk::prelude::*;
use gtk::{gio, glib, Application, ApplicationWindow, Button};

Expand Down Expand Up @@ -40,18 +40,17 @@ fn build_ui(app: &Application) {
sender
.send_blocking(false)
.expect("The channel needs to be open.");
let ten_seconds = Duration::from_secs(10);
thread::sleep(ten_seconds);
let five_seconds = Duration::from_secs(5);
thread::sleep(five_seconds);
// Activate the button again
sender
.send_blocking(true)
.expect("The channel needs to be open.");
});
});

let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(clone!(@weak button => async move {
while let Ok(enable_button) = receiver.recv().await {
button.set_sensitive(enable_button);
}
Expand Down
8 changes: 3 additions & 5 deletions book/listings/main_event_loop/4/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glib::{clone, MainContext};
use glib::clone;
use gtk::prelude::*;
use gtk::{glib, Application, ApplicationWindow, Button};

Expand Down Expand Up @@ -30,8 +30,7 @@ fn build_ui(app: &Application) {
let (sender, receiver) = async_channel::bounded(1);
// Connect to "clicked" signal of `button`
button.connect_clicked(move |_| {
let main_context = MainContext::default();
main_context.spawn_local(clone!(@strong sender => async move {
glib::spawn_future_local(clone!(@strong sender => async move {
// Deactivate the button until the operation is done
sender.send(false).await.expect("The channel needs to be open.");
glib::timeout_future_seconds(5).await;
Expand All @@ -40,9 +39,8 @@ fn build_ui(app: &Application) {
}));
});

let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(clone!(@weak button => async move {
while let Ok(enable_button) = receiver.recv().await {
button.set_sensitive(enable_button);
}
Expand Down
5 changes: 2 additions & 3 deletions book/listings/main_event_loop/5/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glib::{clone, MainContext};
use glib::clone;
use gtk::prelude::*;
use gtk::{glib, Application, ApplicationWindow, Button};

Expand Down Expand Up @@ -28,8 +28,7 @@ fn build_ui(app: &Application) {
// ANCHOR: callback
// Connect to "clicked" signal of `button`
button.connect_clicked(move |button| {
let main_context = MainContext::default();
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(clone!(@weak button => async move {
// Deactivate the button until the operation is done
button.set_sensitive(false);
glib::timeout_future_seconds(5).await;
Expand Down
9 changes: 4 additions & 5 deletions book/listings/main_event_loop/6/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glib::{clone, MainContext};
use glib::clone;
use gtk::prelude::*;
use gtk::{gio, glib};
use gtk::{Application, ApplicationWindow, Button};
Expand Down Expand Up @@ -31,14 +31,13 @@ fn build_ui(app: &Application) {
// ANCHOR: callback
// Connect to "clicked" signal of `button`
button.connect_clicked(move |button| {
let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(clone!(@weak button => async move {
// Deactivate the button until the operation is done
button.set_sensitive(false);
let enable_button = gio::spawn_blocking(move || {
let ten_seconds = Duration::from_secs(10);
thread::sleep(ten_seconds);
let five_seconds = Duration::from_secs(5);
thread::sleep(five_seconds);
true
})
.await
Expand Down
5 changes: 2 additions & 3 deletions book/listings/main_event_loop/7/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ashpd::desktop::account::UserInformation;
use ashpd::WindowIdentifier;
use glib::{clone, MainContext};
use glib::clone;
use gtk::prelude::*;
use gtk::{glib, Application, ApplicationWindow, Button};

Expand Down Expand Up @@ -30,9 +30,8 @@ fn build_ui(app: &Application) {
// ANCHOR: callback
// Connect to "clicked" signal of `button`
button.connect_clicked(move |button| {
let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(clone!(@weak button => async move {
// Get native of button for window identifier
let native = button.native().expect("Need to be able to get native.");
// Get window identifier so that the dialog will be modal to the main window
Expand Down
10 changes: 4 additions & 6 deletions book/listings/main_event_loop/8/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glib::{clone, MainContext};
use glib::clone;
use gtk::glib;
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button};
Expand Down Expand Up @@ -30,25 +30,23 @@ fn build_ui(app: &Application) {
let (sender, receiver) = async_channel::bounded(1);
// Connect to "clicked" signal of `button`
button.connect_clicked(move |_| {
let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@strong sender => async move {
glib::spawn_future_local(clone!(@strong sender => async move {
let response = reqwest::get("https://www.gtk-rs.org").await;
sender.send(response).await.expect("The channel needs to be open.");
}));
});

let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(async move {
while let Ok(response) = receiver.recv().await {
if let Ok(response) = response {
println!("Status: {}", response.status());
} else {
println!("Could not make a `GET` request.");
}
}
}));
});
// ANCHOR_END: callback

// Create a window
Expand Down
7 changes: 3 additions & 4 deletions book/listings/main_event_loop/9/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glib::{clone, MainContext};
use glib::clone;
use gtk::glib;
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button};
Expand Down Expand Up @@ -42,17 +42,16 @@ fn build_ui(app: &Application) {
}));
});

let main_context = MainContext::default();
// The main loop executes the asynchronous block
main_context.spawn_local(clone!(@weak button => async move {
glib::spawn_future_local(async move {
while let Ok(response) = receiver.recv().await {
if let Ok(response) = response {
println!("Status: {}", response.status());
} else {
println!("Could not make a `GET` request.");
}
}
}));
});
// ANCHOR_END: callback

// Create a window
Expand Down
4 changes: 2 additions & 2 deletions book/src/main_event_loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ However, we don't want to block the main loop while waiting for a message to rec
That is the whole point of the exercise after all!

We solve that problem by waiting for messages in an [`async`](https://rust-lang.github.io/async-book/) block.
This `async` block is spawned on the `glib` main loop with [`spawn_local`](https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib/struct.MainContext.html#method.spawn_local)
This `async` block is spawned on the `glib` main loop with [`spawn_future_local`](https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib/fn.spawn_future_local.html)

> See also [`spawn`](https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib/struct.MainContext.html#method.spawn) for spawning async blocks on the main loop from outside the main thread.
> See also [`spawn_future`](https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib/fn.spawn_future.html) for spawning async blocks on the main loop from outside the main thread.

Filename: <a class=file-link href="https://github.com/gtk-rs/gtk4-rs/blob/master/book/listings/main_event_loop/3/main.rs">listings/main_event_loop/3/main.rs</a>

Expand Down
Loading