Skip to content

Commit

Permalink
book: Use new API spawn_future_local
Browse files Browse the repository at this point in the history
  • Loading branch information
Hofer-Julian committed Nov 3, 2023
1 parent aaab21c commit b2a8aab
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 157 deletions.
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

0 comments on commit b2a8aab

Please sign in to comment.