From e1d3a7840dc5823a6038f55d8702fd950be56ffe Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Tue, 21 Mar 2023 09:17:52 -0400 Subject: [PATCH] Take direct control of the tokio runtime Since the GTK thread wants to be the main one, it's easier to manually spawn the runtime handlers and to spawn new tasks to handle communication with the core. I added a basic struct to own the runtime, the core, and communication between the core and GTK --- kifu/kifu-core/Cargo.lock | 226 ++++++++++++++++++++++++++++++++++++++ kifu/kifu-core/Cargo.toml | 2 +- kifu/kifu-core/src/api.rs | 34 ++---- kifu/kifu-gtk/src/main.rs | 86 +++++++++------ 4 files changed, 288 insertions(+), 60 deletions(-) diff --git a/kifu/kifu-core/Cargo.lock b/kifu/kifu-core/Cargo.lock index ebcdde1..59b31e4 100644 --- a/kifu/kifu-core/Cargo.lock +++ b/kifu/kifu-core/Cargo.lock @@ -8,6 +8,33 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "kifu-core" version = "0.1.0" @@ -15,12 +42,157 @@ dependencies = [ "tokio", ] +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + [[package]] name = "pin-project-lite" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "proc-macro2" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tokio" version = "1.26.0" @@ -28,10 +200,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" dependencies = [ "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot", "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", "windows-sys", ] +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.45.0" diff --git a/kifu/kifu-core/Cargo.toml b/kifu/kifu-core/Cargo.toml index 1433197..ad2dec2 100644 --- a/kifu/kifu-core/Cargo.toml +++ b/kifu/kifu-core/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.26", features = [ "sync" ] } +tokio = { version = "1.26", features = [ "full" ] } diff --git a/kifu/kifu-core/src/api.rs b/kifu/kifu-core/src/api.rs index 31b3640..6f389ed 100644 --- a/kifu/kifu-core/src/api.rs +++ b/kifu/kifu-core/src/api.rs @@ -16,41 +16,23 @@ pub enum Response { PlayingFieldView(PlayingFieldView), } -fn dispatch(state: Arc>, request: Request) -> Response { - match request { - Request::PlayingField => Response::PlayingFieldView(playing_field()), - } -} - +#[derive(Clone)] pub struct CoreApp { - request_rx: Receiver, - response_tx: Sender, state: Arc>, } impl CoreApp { - pub fn new() -> (Self, Sender, Receiver) { - let (request_tx, request_rx) = channel(5); - let (response_tx, response_rx) = channel(5); - + pub fn new() -> Self { let state = Arc::new(RwLock::new(AppState::new())); - ( - Self { - request_rx, - response_tx, - state, - }, - request_tx, - response_rx, - ) + Self { state } } - pub async fn run(&mut self) { - loop { - let msg = self.request_rx.recv().await.unwrap(); - let resp = dispatch(self.state.clone(), msg); - self.response_tx.send(resp).await.unwrap(); + pub async fn dispatch(&self, request: Request) -> Response { + match request { + Request::PlayingField => Response::PlayingFieldView(playing_field()), } } + + pub async fn run(&self) {} } diff --git a/kifu/kifu-gtk/src/main.rs b/kifu/kifu-gtk/src/main.rs index 1970ce3..617ab45 100644 --- a/kifu/kifu-gtk/src/main.rs +++ b/kifu/kifu-gtk/src/main.rs @@ -4,55 +4,75 @@ use std::{ sync::{Arc, Mutex}, time::Duration, }; -use tokio::sync::mpsc::{Receiver, Sender}; +use tokio::{ + runtime::Runtime, + sync::mpsc::{Receiver, Sender}, +}; -#[tokio::main] -async fn main() { - let (mut core, request_tx, response_rx) = CoreApp::new(); - let core_handle = tokio::spawn(async move { - core.run().await; +#[derive(Clone)] +pub struct CoreApi { + gtk_tx: gtk::glib::Sender, + rt: Arc, + core: CoreApp, +} + +impl CoreApi { + pub fn dispatch(&self, request: Request) { + self.rt.spawn({ + let gtk_tx = self.gtk_tx.clone(); + let core = self.core.clone(); + async move { gtk_tx.send(core.dispatch(request).await) } + }); + } +} + +fn main() { + let runtime = Arc::new( + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(), + ); + + let core = CoreApp::new(); + + let core_handle = runtime.spawn({ + let core = core.clone(); + async move { + core.run().await; + } }); - let gtk_handle = tokio::task::spawn_blocking(move || { - let app = gtk::Application::builder() - .application_id("com.luminescent-dreams.kifu-gtk") - .build(); + let app = gtk::Application::builder() + .application_id("com.luminescent-dreams.kifu-gtk") + .build(); - let _ = tokio::spawn({ - let request_tx = request_tx.clone(); - async move { - let _ = request_tx.send(Request::PlayingField).await; - } - }); - - app.connect_activate(move |app| { + app.connect_activate({ + let runtime = runtime.clone(); + move |app| { let (gtk_tx, gtk_rx) = gtk::glib::MainContext::channel::(gtk::glib::PRIORITY_DEFAULT); - let _ = tokio::task::spawn(connector(gtk_tx, response_rx)); + let api = CoreApi { + gtk_tx, + rt: runtime.clone(), + core: core.clone(), + }; let window = gtk::ApplicationWindow::new(app); window.present(); + gtk_rx.attach(None, |message| { println!("message: {:?}", message); Continue(true) }); - }); - println!("running the gtk loop"); - app.run(); + api.dispatch(Request::PlayingField); + } }); - core_handle.await; - gtk_handle.await; -} + println!("running the gtk loop"); + app.run(); -async fn connector(gtk_tx: gtk::glib::Sender, mut response_rx: Receiver) { - loop { - let msg = response_rx.recv().await; - match msg { - Some(msg) => gtk_tx.send(msg).unwrap(), - None => (), - } - } + let _ = runtime.block_on(async { core_handle.await }); }