diff --git a/Cargo.lock b/Cargo.lock index f2aedc8..81680ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,114 @@ dependencies = [ "libloading", ] +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-net" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +dependencies = [ + "async-io", + "autocfg", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +dependencies = [ + "async-io", + "async-lock", + "autocfg", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "signal-hook", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "autocfg" version = "1.1.0" @@ -137,6 +245,21 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -291,6 +414,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const_panic" version = "0.2.8" @@ -550,6 +682,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-code" version = "2.3.1" @@ -569,6 +722,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "expat-sys" version = "2.1.6" @@ -579,6 +738,15 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fdeflate" version = "0.3.0" @@ -726,6 +894,21 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.28" @@ -954,6 +1137,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hexf-parse" version = "0.2.1" @@ -1005,6 +1194,7 @@ checksum = "215d51fa4f70dbb63775d7141243c4d98d4d525d8949695601f8fbac7dcbc04e" dependencies = [ "futures", "log", + "smol", "wasm-bindgen-futures", "wasm-timer", ] @@ -1117,6 +1307,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "itoa" version = "1.0.6" @@ -1177,6 +1378,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "lock_api" version = "0.4.9" @@ -1427,7 +1634,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1548,6 +1755,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.11.2" @@ -1675,6 +1888,22 @@ dependencies = [ "miniz_oxide 0.7.1", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1835,6 +2064,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "ryu" version = "1.0.13" @@ -1926,6 +2169,25 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[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 = "simd-adler32" version = "0.3.5" @@ -1991,6 +2253,33 @@ dependencies = [ "wayland-client", ] +[[package]] +name = "smol" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +dependencies = [ + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "spirv" version = "0.2.0+1.5.4" @@ -2180,6 +2469,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 6ac4a15..a941256 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -iced = "0.9.0" +iced = { version = "0.9.0", features = [ + "smol" +] } iced_aw = { version = "0.5.2", default-features = false, features = [ "tab_bar", "tabs" ] } diff --git a/src/ui/main_win.rs b/src/ui/main_win.rs index ec114a0..971cad2 100644 --- a/src/ui/main_win.rs +++ b/src/ui/main_win.rs @@ -1,19 +1,26 @@ +use std::{borrow::BorrowMut, time::{Duration, Instant}}; + use crate::{ config::{get_config, save_config, Config}, constants::APP_NAME, profile::{load_profile, Profile}, + runner::{Runner, RunnerStatus}, }; use iced::{ executor, widget::{button, checkbox, column, pick_list, row, scrollable, text, text_input}, - Alignment, Application, Command, Element, Length, Padding, Theme, + Alignment, Application, Command, Element, Length, Padding, Theme, Subscription, time, }; +use super::widgets::widgets::hspacer; + pub struct MainWin { profiles: Vec, - monado_active: bool, config: Config, debug_search_term: String, + monado_runner: Option, + monado_active: bool, + monado_log: String, } #[derive(Debug, Clone)] @@ -26,6 +33,7 @@ pub enum Message { DebugViewChanged(bool), LogLevelChanged(String), DebugSearchChanged(String), + LogUpdate(Instant), } impl MainWin { @@ -41,6 +49,35 @@ impl MainWin { fn get_selected_profile(&self) -> Option<&Profile> { self.get_profile_by_name(&self.config.selected_profile_name) } + + fn start_monado(&mut self) { + match self.monado_runner.borrow_mut() { + None => {} + Some(existing_runner) => { + existing_runner.terminate(); + } + }; + + let profile = self.get_selected_profile().unwrap(); + + self.monado_runner = Some(Runner::new( + profile.environment.clone(), + profile.monado_path.clone(), + vec![], + )); + + self.monado_runner.as_mut().unwrap().start() + } + + fn get_monado_log(&mut self) { + self.monado_log = match self.monado_runner.as_mut() { + Some(runner) => match runner.status() { + RunnerStatus::Running => runner.get_stdout(), + RunnerStatus::Stopped => "Monado service inactive".into(), + }, + None => "Monado service inactive".into(), + } + } } impl Application for MainWin { @@ -54,9 +91,11 @@ impl Application for MainWin { Self { // TODO: load profiles from disk somehow profiles: vec![load_profile(&"./test/files/profile.json".to_string()).unwrap()], - monado_active: false, config: get_config(), debug_search_term: "".into(), + monado_runner: None, + monado_active: false, + monado_log: "".into() }, Command::none(), ) @@ -68,8 +107,12 @@ impl Application for MainWin { fn update(&mut self, msg: Message) -> Command { match msg { - Message::Start => self.monado_active = true, - Message::Stop => self.monado_active = false, + Message::Start => { + self.start_monado(); + } + Message::Stop => { + self.monado_runner.as_mut().unwrap().terminate(); + } Message::ProfileChanged(profile) => { if self.config.selected_profile_name != profile.name { self.config.selected_profile_name = profile.name; @@ -84,68 +127,90 @@ impl Application for MainWin { save_config(&self.config); } Message::DebugSearchChanged(term) => self.debug_search_term = term, + Message::LogUpdate(_) => { + self.monado_active = match self.monado_runner.as_mut() { + None => false, + Some(runner) => match runner.status() { + RunnerStatus::Running => true, + RunnerStatus::Stopped => false, + } + }; + self.get_monado_log(); + }, _ => println!("unhandled"), }; Command::none() } + fn subscription(&self) -> Subscription { + time::every(Duration::from_millis(500)).map(Message::LogUpdate) + } + fn view(&self) -> Element { - row![ - column![ - column![match self.monado_active { - true => button("Stop").on_press(Message::Stop), - false => button("Start").on_press(Message::Start), - } - .padding(Padding::from([6, 24])),] - .height(Length::Fill), - row![ + let debug_view = match self.config.debug_view_enabled { + false => column![], + true => { + let debug_toolbar = row![ pick_list( - self.profiles.to_vec(), - self.get_selected_profile().cloned(), - Message::ProfileChanged - ), - button("Edit").on_press(Message::EditProfile), - row![].width(Length::Fill), - checkbox( - "Debug View", - self.config.debug_view_enabled, - Message::DebugViewChanged + vec![ + "Debug".to_string(), + "Info".into(), + "Warning".into(), + "Error".into(), + ], + Some("Debug".into()), + Message::LogLevelChanged ), + hspacer!(), + text_input("Search...", self.debug_search_term.as_str()) + .on_input(Message::DebugSearchChanged), ] - .width(Length::Fill), - ] + .padding(12); + + column![ + // TODO: tab bar + scrollable(text(self.monado_log.clone())) + .width(Length::Fill) + .height(Length::Fill), + debug_toolbar, + ] + .width(Length::Fill) + } + }; + + let toolbar = row![ + pick_list( + self.profiles.to_vec(), + self.get_selected_profile().cloned(), + Message::ProfileChanged + ), + button("Edit").on_press(Message::EditProfile), + hspacer!(), + checkbox( + "Debug View", + self.config.debug_view_enabled, + Message::DebugViewChanged + ), + ] + .width(Length::Fill); + + let monado_view = column![ + match self.monado_active { + true => button("Stop").on_press(Message::Stop), + false => button("Start").on_press(Message::Start), + } + .padding(Padding::from([6, 24])), + scrollable(column![]) + ] + .height(Length::Fill) + .align_items(Alignment::Center); + + let main_view = column![monado_view, toolbar,] .width(Length::Fill) .height(Length::Fill) - .padding(12) - .align_items(Alignment::Center), - match self.config.debug_view_enabled { - true => column![ - // TODO: tab bar - scrollable(text("Foo bar baz")) - .width(Length::Fill) - .height(Length::Fill), - row![ - pick_list( - vec![ - "Debug".to_string(), - "Info".into(), - "Warning".into(), - "Error".into(), - ], - Some("Debug".into()), - Message::LogLevelChanged - ), - row![].width(Length::Fill), - text_input("Search...", self.debug_search_term.as_str()) - .on_input(Message::DebugSearchChanged), - ] - .padding(12) - ] - .width(Length::Fill), - false => column![], - } - ] - .into() + .padding(12); + + row![main_view, debug_view,].into() } fn theme(&self) -> Self::Theme { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 5916fea..28b0a0c 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,3 +1,3 @@ pub mod main_win; - +pub mod widgets;