diff --git a/examples/Cargo.toml b/examples/Cargo.toml index d112668e1f7..5364ec77f57 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -5,6 +5,7 @@ authors = ["The gtk-rs Project Developers"] edition = "2021" [dependencies] +async-channel = "2.0.0" chrono = "0.4" futures = "0.3" futures-util = "0.3" diff --git a/examples/cairo_threads/main.rs b/examples/cairo_threads/main.rs index 6dc269e17fa..95fe8dfe5c6 100644 --- a/examples/cairo_threads/main.rs +++ b/examples/cairo_threads/main.rs @@ -39,7 +39,7 @@ fn build_ui(application: >k::Application) { // This is the channel for sending results from the worker thread to the main thread // For every received image, queue the corresponding part of the DrawingArea for redrawing - let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::default()); + let (ready_tx, ready_rx) = async_channel::bounded(10); let mut images = Vec::new(); let mut origins = Vec::new(); @@ -92,7 +92,7 @@ fn build_ui(application: >k::Application) { }); // Send the finished image back to the GUI thread - let _ = ready_tx.send((thread_num, image)); + let _ = ready_tx.send_blocking((thread_num, image)); } })); } @@ -117,18 +117,18 @@ fn build_ui(application: >k::Application) { }), ); - ready_rx.attach(None, move |(thread_num, image)| { - let (ref images, ref origins, ref workers) = *workspace; + glib::MainContext::default().spawn_local(async move { + while let Ok((thread_num, image)) = ready_rx.recv().await { + let (ref images, ref origins, ref workers) = *workspace; - // Swap the newly received image with the old stored one and send the old one back to - // the worker thread - let tx = &workers[thread_num]; - let image = images[thread_num].replace(image); - let _ = tx.send(image); + // Swap the newly received image with the old stored one and send the old one back to + // the worker thread + let tx = &workers[thread_num]; + let image = images[thread_num].replace(image); + let _ = tx.send(image); - area.queue_draw_area(origins[thread_num].0, origins[thread_num].1, WIDTH, HEIGHT); - - glib::ControlFlow::Continue + area.queue_draw_area(origins[thread_num].0, origins[thread_num].1, WIDTH, HEIGHT); + } }); window.show_all(); diff --git a/examples/multi_threading_context/main.rs b/examples/multi_threading_context/main.rs index 49b8b6b61a3..4049abe79f4 100644 --- a/examples/multi_threading_context/main.rs +++ b/examples/multi_threading_context/main.rs @@ -28,27 +28,28 @@ fn build_ui(application: >k::Application) { scroll.set_policy(gtk::PolicyType::Automatic, gtk::PolicyType::Automatic); scroll.add(&text_view); - let (tx, rx) = glib::MainContext::channel(glib::Priority::default()); + let (tx, rx) = async_channel::bounded(10); thread::spawn(move || { for i in 1..100 { // do long work thread::sleep(Duration::from_millis(50)); // send result to channel - tx.send(format!("#{i} Text from another thread.")) + tx.send_blocking(format!("#{i} Text from another thread.")) .expect("Couldn't send data to channel"); // receiver will be run on the main thread } }); - // Attach receiver to the main context and set the text buffer text from here let text_buffer = text_view .buffer() .expect("Couldn't get buffer from text_view"); - rx.attach(None, move |text| { - text_buffer.set_text(&text); - glib::ControlFlow::Continue + // Spawn a future on main context and set the text buffer text from here + glib::MainContext::default().spawn_local(async move { + while let Ok(text) = rx.recv().await { + text_buffer.set_text(&text); + } }); window.add(&scroll); diff --git a/examples/progress_tracker/main.rs b/examples/progress_tracker/main.rs index ff1545c1e91..87dc72dddeb 100644 --- a/examples/progress_tracker/main.rs +++ b/examples/progress_tracker/main.rs @@ -57,17 +57,19 @@ impl Application { active.set(true); - let (tx, rx) = glib::MainContext::channel(glib::Priority::default()); + let (tx, rx) = async_channel::bounded(10); + thread::spawn(move || { for v in 1..=10 { - let _ = tx.send(Some(v)); + let _ = tx.send_blocking(Some(v)); thread::sleep(Duration::from_millis(500)); } - let _ = tx.send(None); + let _ = tx.send_blocking(None); }); - rx.attach(None, glib::clone!(@weak active, @weak widgets => @default-return glib::ControlFlow::Break, move |value| match value { - Some(value) => { + let active = active.clone(); + glib::MainContext::default().spawn_local(async move { + while let Ok(Some(value)) = rx.recv().await { widgets .main_view .progress @@ -86,14 +88,10 @@ impl Application { glib::ControlFlow::Break })); } - - glib::ControlFlow::Continue - } - None => { - active.set(false); - glib::ControlFlow::Break } - })); + + active.set(false); + }); }), ); }