From 13e736dbed9a6e5959c41816c8841b02e85c176b Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 26 Apr 2020 15:14:00 +1200 Subject: [PATCH] First pass for tokio --- Cargo.lock | 303 ++++++++++++++++++++++++++++++++++- Cargo.toml | 9 +- examples/per-key-effect-2.rs | 30 ++-- src/core.rs | 62 ++++--- src/daemon.rs | 79 +++++---- src/laptops/gl753.rs | 18 ++- src/laptops/gx502.rs | 26 +-- src/laptops/mod.rs | 4 +- src/main.rs | 5 +- 9 files changed, 419 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d29f43f5..b3902977 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,18 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi", + "winapi 0.3.8", +] + +[[package]] +name = "async-trait" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -32,7 +43,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.8", ] [[package]] @@ -80,6 +91,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bytes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" + [[package]] name = "cc" version = "1.0.52" @@ -138,14 +155,26 @@ dependencies = [ [[package]] name = "dbus" -version = "0.7.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add8dd36d6d34a084220eb9fe216d3e230d52b37c31702e1ffda4fb2d4ef950e" +checksum = "38f8875bb7afbc20dec12db09e18af3dcbd672b08592d2932950326a6437c616" dependencies = [ + "futures", "libc", "libdbus-sys", ] +[[package]] +name = "dbus-tokio" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "641f98f32585b8a8cc5d88c6c55a8f6cdf60740baab17c57d59b9b662c73f522" +dependencies = [ + "dbus", + "mio", + "tokio", +] + [[package]] name = "enumflags2" version = "0.6.4" @@ -188,7 +217,114 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi", + "winapi 0.3.8", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" + +[[package]] +name = "futures-executor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" + +[[package]] +name = "futures-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" + +[[package]] +name = "futures-task" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" + +[[package]] +name = "futures-util" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", ] [[package]] @@ -235,6 +371,25 @@ dependencies = [ "quick-error", ] +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -281,7 +436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ "cc", - "winapi", + "winapi 0.3.8", ] [[package]] @@ -313,6 +468,48 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "mio" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + [[package]] name = "nom" version = "5.1.1" @@ -323,6 +520,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "numtoa" version = "0.2.3" @@ -335,12 +542,36 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pin-project-lite" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +[[package]] +name = "proc-macro-hack" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" + +[[package]] +name = "proc-macro-nested" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" + [[package]] name = "proc-macro2" version = "1.0.10" @@ -400,7 +631,9 @@ name = "rog-daemon" version = "0.6.1" dependencies = [ "aho-corasick", + "async-trait", "dbus", + "dbus-tokio", "env_logger", "gumdrop", "log", @@ -409,6 +642,7 @@ dependencies = [ "serde_derive", "sysfs-class", "thiserror", + "tokio", "toml", "uhid-virt", ] @@ -453,6 +687,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + [[package]] name = "strsim" version = "0.8.0" @@ -544,6 +784,33 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tokio" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9c43f1bb96970e153bcbae39a65e249ccb942bd9d36dbdf086024920417c9c" +dependencies = [ + "bytes", + "futures-core", + "lazy_static", + "mio", + "num_cpus", + "pin-project-lite", + "slab", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.5.6" @@ -612,6 +879,12 @@ dependencies = [ "libc", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.8" @@ -622,6 +895,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -634,7 +913,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.8", ] [[package]] @@ -643,6 +922,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "xattr" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index d988d094..0d6e4fb0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,10 @@ path = "src/main.rs" [dependencies] rusb = "^0.5.5" gumdrop = "^0.8.0" -dbus = "^0.7.1" +dbus = { version = "^0.8.2", features = ["futures"] } +dbus-tokio = "^0.5.1" +tokio = { version = "0.2.19", features = ["rt-threaded", "macros"] } + serde = "1.0" serde_derive = "1.0" toml = "0.5" @@ -25,4 +28,6 @@ thiserror = "^1.0.15" log = "^0.4.8" uhid-virt = "^0.0.4" #keycode = "0.3" -env_logger = "^0.7.1" \ No newline at end of file +env_logger = "^0.7.1" + +async-trait = "0.1.30" \ No newline at end of file diff --git a/examples/per-key-effect-2.rs b/examples/per-key-effect-2.rs index 1c48b656..f427fe31 100644 --- a/examples/per-key-effect-2.rs +++ b/examples/per-key-effect-2.rs @@ -24,29 +24,29 @@ fn main() -> Result<(), Box> { let mut key_colours = KeyColourArray::new(); per_key_led.push(key_colours.clone()); - for _ in 0..29 { - *key_colours.key(Key::ROG).0 += 8; - *key_colours.key(Key::L).0 += 8; - *key_colours.key(Key::I).0 += 8; - *key_colours.key(Key::N).0 += 8; - *key_colours.key(Key::U).0 += 8; - *key_colours.key(Key::X).0 += 8; + for _ in 0..49 { + *key_colours.key(Key::ROG).0 += 3; + *key_colours.key(Key::L).0 += 3; + *key_colours.key(Key::I).0 += 3; + *key_colours.key(Key::N).0 += 3; + *key_colours.key(Key::U).0 += 3; + *key_colours.key(Key::X).0 += 3; per_key_led.push(key_colours.clone()); } - for _ in 0..29 { - *key_colours.key(Key::ROG).0 -= 8; - *key_colours.key(Key::L).0 -= 8; - *key_colours.key(Key::I).0 -= 8; - *key_colours.key(Key::N).0 -= 8; - *key_colours.key(Key::U).0 -= 8; - *key_colours.key(Key::X).0 -= 8; + for _ in 0..49 { + *key_colours.key(Key::ROG).0 -= 3; + *key_colours.key(Key::L).0 -= 3; + *key_colours.key(Key::I).0 -= 3; + *key_colours.key(Key::N).0 -= 3; + *key_colours.key(Key::U).0 -= 3; + *key_colours.key(Key::X).0 -= 3; per_key_led.push(key_colours.clone()); } // It takes each interrupt at least 1ms. 10ms to write complete block. Plus any extra // penalty time such as read waits - let time = time::Duration::from_millis(16); // aim for 60 per second + let time = time::Duration::from_millis(1); // aim for 60 per second let row = KeyColourArray::get_init_msg(); let msg = diff --git a/src/core.rs b/src/core.rs index da883c61..51339cb3 100644 --- a/src/core.rs +++ b/src/core.rs @@ -90,7 +90,7 @@ impl RogCore { }) } - pub(crate) fn reload(&mut self) -> Result<(), Box> { + pub(crate) async fn reload(&mut self) -> Result<(), Box> { let mode_curr = self.config.current_mode[3]; let mode = self .config @@ -98,7 +98,7 @@ impl RogCore { .get_field_from(BuiltInModeByte::from(mode_curr).into()) .unwrap() .to_owned(); - self.aura_write_messages(&[&mode])?; + self.aura_write_messages(&[&mode]).await?; let path = if Path::new(FAN_TYPE_1_PATH).exists() { FAN_TYPE_1_PATH @@ -131,7 +131,7 @@ impl RogCore { Err(AuraError::UsbError(rusb::Error::NoDevice)) } - pub fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> { + pub async fn aura_write(&mut self, message: &[u8]) -> Result<(), AuraError> { match self .handle .write_interrupt(self.led_endpoint, message, Duration::from_millis(1)) @@ -145,31 +145,31 @@ impl RogCore { Ok(()) } - fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> { + async fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), AuraError> { if !self.initialised { - self.aura_write(&LED_INIT1)?; - self.aura_write(LED_INIT2.as_bytes())?; - self.aura_write(&LED_INIT3)?; - self.aura_write(LED_INIT4.as_bytes())?; - self.aura_write(&LED_INIT5)?; + self.aura_write(&LED_INIT1).await?; + self.aura_write(LED_INIT2.as_bytes()).await?; + self.aura_write(&LED_INIT3).await?; + self.aura_write(LED_INIT4.as_bytes()).await?; + self.aura_write(&LED_INIT5).await?; self.initialised = true; } for message in messages { - self.aura_write(*message)?; - self.aura_write(&LED_SET)?; + self.aura_write(*message).await?; + self.aura_write(&LED_SET).await?; } // Changes won't persist unless apply is set - self.aura_write(&LED_APPLY)?; + self.aura_write(&LED_APPLY).await?; Ok(()) } /// Initialise and clear the keyboard for custom effects - pub fn aura_effect_init(&mut self) -> Result<(), AuraError> { + pub async fn aura_effect_init(&mut self) -> Result<(), AuraError> { let mut init = [0u8; 64]; init[0] = 0x5d; // Report ID init[1] = 0xbc; // Mode = custom??, 0xb3 is builtin - self.aura_write(&init)?; + self.aura_write(&init).await?; self.initialised = true; Ok(()) @@ -178,27 +178,25 @@ impl RogCore { /// Write an effect block /// /// `aura_effect_init` must be called any effect routine, and called only once. - pub fn aura_write_effect(&mut self, effect: &[KeyColourArray]) -> Result<(), AuraError> { - for key_colours in effect { - for row in key_colours.get() { - self.aura_write(row)?; - } + pub async fn aura_write_effect(&mut self, effect: Vec>) -> Result<(), AuraError> { + for row in effect.iter() { + self.aura_write(row).await?; } Ok(()) } - pub(crate) fn aura_set_and_save( + pub(crate) async fn aura_set_and_save( &mut self, supported_modes: &[BuiltInModeByte], bytes: &[u8], ) -> Result<(), AuraError> { let mode = BuiltInModeByte::from(bytes[3]); if bytes[1] == 0xbc { - self.aura_write(bytes)?; + self.aura_write(bytes).await?; return Ok(()); } else if supported_modes.contains(&mode) || bytes[1] == 0xba { let messages = [bytes]; - self.aura_write_messages(&messages)?; + self.aura_write_messages(&messages).await?; self.config.set_field_from(bytes); self.config.write(); return Ok(()); @@ -207,7 +205,7 @@ impl RogCore { Err(AuraError::NotSupported) } - pub(crate) fn aura_bright_inc( + pub(crate) async fn aura_bright_inc( &mut self, supported_modes: &[BuiltInModeByte], max_bright: u8, @@ -218,11 +216,11 @@ impl RogCore { self.config.brightness = bright; } let bytes = aura_brightness_bytes(bright); - self.aura_set_and_save(supported_modes, &bytes)?; + self.aura_set_and_save(supported_modes, &bytes).await?; Ok(()) } - pub(crate) fn aura_bright_dec( + pub(crate) async fn aura_bright_dec( &mut self, supported_modes: &[BuiltInModeByte], min_bright: u8, @@ -233,14 +231,14 @@ impl RogCore { self.config.brightness = bright; } let bytes = aura_brightness_bytes(bright); - self.aura_set_and_save(supported_modes, &bytes)?; + self.aura_set_and_save(supported_modes, &bytes).await?; Ok(()) } /// Select next Aura effect /// /// If the current effect is the last one then the effect selected wraps around to the first. - pub(crate) fn aura_mode_next( + pub(crate) async fn aura_mode_next( &mut self, supported_modes: &[BuiltInModeByte], ) -> Result<(), AuraError> { @@ -258,7 +256,7 @@ impl RogCore { .get_field_from(supported_modes[idx_next].into()) .unwrap() .to_owned(); - self.aura_set_and_save(supported_modes, &mode_next)?; + self.aura_set_and_save(supported_modes, &mode_next).await?; info!("Switched LED mode to {:#?}", supported_modes[idx_next]); Ok(()) } @@ -266,7 +264,7 @@ impl RogCore { /// Select previous Aura effect /// /// If the current effect is the first one then the effect selected wraps around to the last. - pub(crate) fn aura_mode_prev( + pub(crate) async fn aura_mode_prev( &mut self, supported_modes: &[BuiltInModeByte], ) -> Result<(), AuraError> { @@ -284,7 +282,7 @@ impl RogCore { .get_field_from(supported_modes[idx_next].into()) .unwrap() .to_owned(); - self.aura_set_and_save(supported_modes, &mode_next)?; + self.aura_set_and_save(supported_modes, &mode_next).await?; info!("Switched LED mode to {:#?}", supported_modes[idx_next]); Ok(()) } @@ -324,11 +322,11 @@ impl RogCore { /// /// `report_filter_bytes` is used to filter the data read from the interupt so /// only the relevant byte array is returned. - pub(crate) fn poll_keyboard(&mut self, report_filter_bytes: &[u8]) -> Option<[u8; 32]> { + pub(crate) async fn poll_keyboard(&mut self, report_filter_bytes: &[u8]) -> Option<[u8; 32]> { let mut buf = [0u8; 32]; match self .handle - .read_interrupt(self.keys_endpoint, &mut buf, Duration::from_millis(1)) + .read_interrupt(self.keys_endpoint, &mut buf, Duration::from_millis(50)) { Ok(_) => { if report_filter_bytes.contains(&buf[0]) { diff --git a/src/daemon.rs b/src/daemon.rs index ffce0225..ba8e5149 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -4,16 +4,17 @@ pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon"; use crate::{core::RogCore, laptops::match_laptop}; use dbus::{ - blocking::Connection, + nonblock::Process, tree::{Factory, MethodErr}, }; +use dbus_tokio::connection; + use log::{error, info}; -use std::cell::RefCell; use std::error::Error; -use std::rc::Rc; +use std::sync::{Arc, Mutex}; use std::time::Duration; -pub fn start_daemon() -> Result<(), Box> { +pub async fn start_daemon() -> Result<(), Box> { let laptop = match_laptop(); let mut rogcore = RogCore::new(&*laptop).map_or_else( |err| { @@ -26,23 +27,25 @@ pub fn start_daemon() -> Result<(), Box> { }, ); // Reload settings - rogcore.reload()?; + rogcore.reload().await?; + println!("RELOADED"); - let mut connection = Connection::new_system().map_or_else( - |err| { - error!("{:?}", err); - panic!("{:?}", err); - }, - |dbus| { - info!("DBus connected"); - dbus - }, - ); - connection.request_name(DBUS_IFACE, false, true, false)?; - let factory = Factory::new_fn::<()>(); + let (resource, connection) = connection::new_system_sync()?; + tokio::spawn(async { + let err = resource.await; + panic!("Lost connection to D-Bus: {}", err); + }); - let input: Rc>>> = Rc::new(RefCell::new(None)); - let effect: Rc>>>> = Rc::new(RefCell::new(None)); + println!("CONN REQUEST"); + connection + .request_name(DBUS_IFACE, false, true, false) + .await?; + println!("CONN REQUEST DONE"); + + let factory = Factory::new_sync::<()>(); + + let input: Arc>>> = Arc::new(Mutex::new(None)); + let effect: Arc>>>> = Arc::new(Mutex::new(None)); let tree = factory.tree(()).add( factory.object_path(DBUS_PATH, ()).add( @@ -56,7 +59,7 @@ pub fn start_daemon() -> Result<(), Box> { move |m| { let bytes: Vec = m.msg.read1()?; - if let Ok(mut lock) = input.try_borrow_mut() { + if let Ok(mut lock) = input.try_lock() { *lock = Some(bytes.to_vec()); let mret = m .msg @@ -79,7 +82,7 @@ pub fn start_daemon() -> Result<(), Box> { .method("ledeffect", (), { let effect = effect.clone(); move |m| { - if let Ok(mut lock) = effect.try_borrow_mut() { + if let Ok(mut lock) = effect.try_lock() { let mut iter = m.msg.iter_init(); let byte_array: Vec> = vec![ iter.read()?, @@ -121,14 +124,10 @@ pub fn start_daemon() -> Result<(), Box> { ); // We add the tree to the connection so that incoming method calls will be handled. - tree.start_receive(&connection); + tree.start_receive_send(&*connection); let supported = Vec::from(laptop.supported_modes()); loop { - // A no-comp loop takes 2 milliseconds - // With effect, up to 16ms - // With single write, 3ms - // // Timing is such that: // - interrupt write is minimum 1ms (sometimes lower) // - read interrupt must timeout, minimum of 1ms @@ -136,38 +135,34 @@ pub fn start_daemon() -> Result<(), Box> { // - to maintain constant times of 1ms, per-key colours should use // the effect endpoint so that the complete colour block is written // as fast as 1ms per row of the matrix inside it. (10ms total time) - connection - .process(Duration::from_millis(100)) - .unwrap_or_else(|err| { - error!("{:?}", err); - false - }); + + // DBUS processing takes 6ms.... + connection.process_all(); // 700u per write - if let Ok(mut lock) = input.try_borrow_mut() { + if let Ok(mut lock) = input.try_lock() { if let Some(bytes) = &*lock { // It takes up to 20 milliseconds to write a complete colour block here - rogcore.aura_set_and_save(&supported, &bytes)?; + rogcore.aura_set_and_save(&supported, &bytes).await?; *lock = None; } } - if let Ok(mut lock) = effect.try_borrow_mut() { - if let Some(bytes) = &*lock { - // It takes up to 10 milliseconds to write a complete colour block and here - for row in bytes { - rogcore.aura_write(&row)?; - } - *lock = None; + if let Ok(mut lock) = effect.try_lock() { + if lock.is_some() { + let effect = lock.take(); + rogcore.aura_write_effect(effect.unwrap()).await?; } } - match laptop.run(&mut rogcore) { + match laptop.run(&mut rogcore).await { Ok(_) => {} Err(err) => { error!("{:?}", err); panic!("Force crash for systemd to restart service") } } + // When using an effect gen, 17-20ms is the min/max time to account for. + // If DBUS didn't take so long we could get this down to 11-12ms. } } diff --git a/src/laptops/gl753.rs b/src/laptops/gl753.rs index 149d6db6..783947ab 100644 --- a/src/laptops/gl753.rs +++ b/src/laptops/gl753.rs @@ -47,14 +47,18 @@ impl LaptopGL753 { } impl LaptopGL753 { - fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { - if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes) { + async fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { + if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes).await { match GL753Keys::from(key_buf[1]) { GL753Keys::LedBrightUp => { - rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?; + rogcore + .aura_bright_inc(&self.supported_modes, self.max_led_bright) + .await?; } GL753Keys::LedBrightDown => { - rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?; + rogcore + .aura_bright_dec(&self.supported_modes, self.min_led_bright) + .await?; } GL753Keys::ScreenBrightUp => self.backlight.step_up(), GL753Keys::ScreenBrightDown => self.backlight.step_down(), @@ -88,9 +92,11 @@ impl LaptopGL753 { } } +use async_trait::async_trait; +#[async_trait] impl Laptop for LaptopGL753 { - fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { - self.do_keypress_actions(rogcore) + async fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { + self.do_keypress_actions(rogcore).await } fn led_endpoint(&self) -> u8 { self.led_endpoint diff --git a/src/laptops/gx502.rs b/src/laptops/gx502.rs index 1de8577f..9c7796a5 100644 --- a/src/laptops/gx502.rs +++ b/src/laptops/gx502.rs @@ -89,17 +89,21 @@ impl LaptopGX502 { } impl LaptopGX502 { - fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { - if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes) { + async fn do_keypress_actions(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { + if let Some(key_buf) = rogcore.poll_keyboard(&self.report_filter_bytes).await { match GX502Keys::from(key_buf[1]) { GX502Keys::LedBrightUp => { - rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?; + rogcore + .aura_bright_inc(&self.supported_modes, self.max_led_bright) + .await?; } GX502Keys::LedBrightDown => { - rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?; + rogcore + .aura_bright_dec(&self.supported_modes, self.min_led_bright) + .await?; } - GX502Keys::AuraNext => rogcore.aura_mode_next(&self.supported_modes)?, - GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&self.supported_modes)?, + GX502Keys::AuraNext => rogcore.aura_mode_next(&self.supported_modes).await?, + GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&self.supported_modes).await?, GX502Keys::ScreenBrightUp => self.backlight.step_up(), GX502Keys::ScreenBrightDown => self.backlight.step_down(), GX502Keys::Sleep => rogcore.suspend_with_systemd(), @@ -120,8 +124,8 @@ impl LaptopGX502 { rogcore.virt_keys().press(key); } GX502Keys::Rog => { - rogcore.aura_effect_init()?; - rogcore.aura_write_effect(&self.per_key_led)?; + //rogcore.aura_effect_init()?; + //rogcore.aura_write_effect(&self.per_key_led)?; // let mut key = [0u8; 32]; // key[0] = 0x01; // key[3] = 0x68; // XF86Tools? F13 @@ -139,9 +143,11 @@ impl LaptopGX502 { } } +use async_trait::async_trait; +#[async_trait] impl Laptop for LaptopGX502 { - fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { - self.do_keypress_actions(rogcore) + async fn run(&self, rogcore: &mut RogCore) -> Result<(), AuraError> { + self.do_keypress_actions(rogcore).await } fn led_endpoint(&self) -> u8 { self.led_endpoint diff --git a/src/laptops/mod.rs b/src/laptops/mod.rs index 7e653697..7b24971e 100644 --- a/src/laptops/mod.rs +++ b/src/laptops/mod.rs @@ -1,6 +1,7 @@ use crate::aura::BuiltInModeByte; use crate::core::RogCore; use crate::error::AuraError; +use async_trait::async_trait; //use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState}; use log::info; @@ -62,10 +63,11 @@ pub(crate) fn match_laptop() -> Box { /// /// If using the `keycode` crate to build keyboard input, the report must be prefixed /// with the report ID (usually `0x01` for the virtual keyboard). +#[async_trait] pub(crate) trait Laptop { fn board_name(&self) -> &str; fn prod_family(&self) -> &str; - fn run(&self, core: &mut RogCore) -> Result<(), AuraError>; + async fn run(&self, core: &mut RogCore) -> Result<(), AuraError>; fn led_endpoint(&self) -> u8; fn key_endpoint(&self) -> u8; fn usb_vendor(&self) -> u16; diff --git a/src/main.rs b/src/main.rs index 44bf9e0e..5b059766 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,8 @@ struct LedModeCommand { command: Option, } -fn main() -> Result<(), Box> { +#[tokio::main] +pub async fn main() -> Result<(), Box> { let mut builder = Builder::from_env("ROGCORE_LOG"); builder.target(Target::Stdout); builder.format_timestamp(None); @@ -48,7 +49,7 @@ fn main() -> Result<(), Box> { let parsed = CLIStart::parse_args_default_or_exit(); if parsed.daemon { - start_daemon()?; + start_daemon().await?; } if parsed.version { println!("Version: {}", VERSION);