mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Use tokio in asusctl
This commit is contained in:
@@ -4,16 +4,18 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased - 4.4.1]
|
||||
## [Unreleased - 4.5.0]
|
||||
### Added
|
||||
- intofy watches on:
|
||||
- `charge_control_end_threshold`
|
||||
- `panel_od`
|
||||
- `gpu_mux_mode`
|
||||
- `platform_profile`
|
||||
- keyboard brightness
|
||||
- These allow for updating any associated config and sending dbus notifications.
|
||||
### Changed
|
||||
- Use loops to ensure that mutex is gained for LED changes.
|
||||
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
||||
### Breaking
|
||||
- DBUS: all charge control methods renamed:
|
||||
- `ChargeControlEndThreshold`
|
||||
|
||||
26
Cargo.lock
generated
26
Cargo.lock
generated
@@ -588,8 +588,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"smol",
|
||||
"sysfs-class",
|
||||
"tokio",
|
||||
"toml",
|
||||
"zbus",
|
||||
"zvariant",
|
||||
@@ -1705,6 +1705,16 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.7"
|
||||
@@ -2537,11 +2547,25 @@ dependencies = [
|
||||
"autocfg",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
|
||||
@@ -25,7 +25,7 @@ rog_profiles = { path = "../rog-profiles" }
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
|
||||
async-trait = "^0.1"
|
||||
smol = "^1.2"
|
||||
tokio = { version = "^1.21.1", features = ["macros", "rt-multi-thread", "time"]}
|
||||
|
||||
# cli and logging
|
||||
log = "^0.4"
|
||||
|
||||
@@ -13,7 +13,6 @@ use rog_anime::{
|
||||
ActionData, AnimeDataBuffer, AnimePacketType, AnimeType,
|
||||
};
|
||||
use rog_platform::{hid_raw::HidRaw, supported::AnimeSupportedFunctions, usb_raw::USBRaw};
|
||||
use smol::Executor;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
@@ -230,11 +229,7 @@ impl CtrlAnimeTask {
|
||||
|
||||
#[async_trait]
|
||||
impl crate::CtrlTask for CtrlAnimeTask {
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
_: SignalContext<'a>,
|
||||
) -> Result<(), RogError> {
|
||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||
let run_action =
|
||||
|start: bool, lock: MutexGuard<CtrlAnime>, inner: Arc<Mutex<CtrlAnime>>| {
|
||||
if start {
|
||||
@@ -251,7 +246,6 @@ impl crate::CtrlTask for CtrlAnimeTask {
|
||||
let inner3 = self.inner.clone();
|
||||
let inner4 = self.inner.clone();
|
||||
self.create_sys_event_tasks(
|
||||
executor,
|
||||
// Loop is required to try an attempt to get the mutex *without* blocking
|
||||
// other threads - it is possible to end up with deadlocks otherwise.
|
||||
move || loop {
|
||||
|
||||
@@ -114,7 +114,7 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(default)]
|
||||
// #[serde(default)]
|
||||
pub struct AuraConfig {
|
||||
pub brightness: LedBrightness,
|
||||
pub current_mode: AuraModeNum,
|
||||
@@ -271,7 +271,7 @@ impl AuraConfig {
|
||||
if l == 0 {
|
||||
warn!("File is empty {}", AURA_CONFIG_PATH);
|
||||
} else {
|
||||
let x: AuraConfig = serde_json::from_str(&buf)
|
||||
let x = serde_json::from_str(&buf)
|
||||
.unwrap_or_else(|_| panic!("Could not deserialise {}", AURA_CONFIG_PATH));
|
||||
*self = x;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,11 @@ use rog_aura::{
|
||||
};
|
||||
use rog_aura::{AuraZone, Direction, Speed, GRADIENT};
|
||||
use rog_platform::{hid_raw::HidRaw, keyboard_led::KeyboardLed, supported::LedSupportedFunctions};
|
||||
use smol::Executor;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::MutexGuard;
|
||||
use zbus::SignalContext;
|
||||
use zbus::{export::futures_util::StreamExt, SignalContext};
|
||||
|
||||
use crate::GetSupported;
|
||||
|
||||
@@ -95,11 +94,7 @@ impl CtrlKbdLedTask {
|
||||
|
||||
#[async_trait]
|
||||
impl CtrlTask for CtrlKbdLedTask {
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
_: SignalContext<'a>,
|
||||
) -> Result<(), RogError> {
|
||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||
let load_save = |start: bool, mut lock: MutexGuard<CtrlKbdLed>| {
|
||||
// If waking up
|
||||
if !start {
|
||||
@@ -123,7 +118,6 @@ impl CtrlTask for CtrlKbdLedTask {
|
||||
let inner3 = self.inner.clone();
|
||||
let inner4 = self.inner.clone();
|
||||
self.create_sys_event_tasks(
|
||||
executor,
|
||||
// Loop so that we do aquire the lock but also don't block other
|
||||
// threads (prevents potential deadlocks)
|
||||
move || loop {
|
||||
@@ -156,20 +150,18 @@ impl CtrlTask for CtrlKbdLedTask {
|
||||
let ctrl2 = self.inner.clone();
|
||||
if let Ok(ctrl) = self.inner.lock() {
|
||||
let mut watch = ctrl.kd_brightness.monitor_brightness()?;
|
||||
executor
|
||||
.spawn(async move {
|
||||
let mut buffer = [0; 1024];
|
||||
loop {
|
||||
if let Ok(events) = watch.read_events_blocking(&mut buffer) {
|
||||
for _ in events {
|
||||
if let Ok(lock) = ctrl2.try_lock() {
|
||||
load_save(true, lock);
|
||||
}
|
||||
}
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch
|
||||
.event_stream(&mut buffer)
|
||||
.unwrap()
|
||||
.for_each(|_| async {
|
||||
if let Ok(lock) = ctrl2.try_lock() {
|
||||
load_save(true, lock);
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
})
|
||||
.await;
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -4,7 +4,6 @@ use async_trait::async_trait;
|
||||
use log::{info, warn};
|
||||
use rog_platform::platform::{AsusPlatform, GpuMode};
|
||||
use rog_platform::supported::RogBiosSupportedFunctions;
|
||||
use smol::Executor;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
@@ -129,7 +128,7 @@ impl CtrlRogBios {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_panel_od(&self, enable: bool) -> Result<(), RogError> {
|
||||
fn set_panel_overdrive(&self, enable: bool) -> Result<(), RogError> {
|
||||
self.platform.set_panel_od(enable).map_err(|err| {
|
||||
warn!("CtrlRogBios: set_panel_overdrive {}", err);
|
||||
err
|
||||
@@ -197,7 +196,7 @@ impl CtrlRogBios {
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_post_boot_sound(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {}
|
||||
|
||||
async fn set_panel_overdrive(
|
||||
async fn set_panel_od(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
overdrive: bool,
|
||||
@@ -256,7 +255,7 @@ impl crate::Reloadable for CtrlRogBios {
|
||||
} else {
|
||||
false
|
||||
};
|
||||
self.set_panel_od(p)?;
|
||||
self.set_panel_overdrive(p)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -269,22 +268,17 @@ impl CtrlRogBios {
|
||||
|
||||
#[async_trait]
|
||||
impl CtrlTask for CtrlRogBios {
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
signal_ctxt: SignalContext<'a>,
|
||||
) -> Result<(), RogError> {
|
||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||
let platform1 = self.clone();
|
||||
let platform2 = self.clone();
|
||||
self.create_sys_event_tasks(
|
||||
executor,
|
||||
move || {},
|
||||
move || {
|
||||
info!("CtrlRogBios reloading panel_od");
|
||||
if let Ok(lock) = platform1.config.try_lock() {
|
||||
if platform1.platform.has_panel_od() {
|
||||
platform1
|
||||
.set_panel_od(lock.panel_od)
|
||||
.set_panel_overdrive(lock.panel_od)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlCharge: set_limit {}", err);
|
||||
err
|
||||
@@ -299,7 +293,7 @@ impl CtrlTask for CtrlRogBios {
|
||||
if let Ok(lock) = platform2.config.try_lock() {
|
||||
if platform2.platform.has_panel_od() {
|
||||
platform2
|
||||
.set_panel_od(lock.panel_od)
|
||||
.set_panel_overdrive(lock.panel_od)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlCharge: set_limit {}", err);
|
||||
err
|
||||
@@ -311,9 +305,8 @@ impl CtrlTask for CtrlRogBios {
|
||||
)
|
||||
.await;
|
||||
|
||||
self.watch_panel_od(executor, signal_ctxt.clone()).await?;
|
||||
self.watch_gpu_mux_mode(executor, signal_ctxt.clone())
|
||||
.await?;
|
||||
self.watch_panel_od(signal_ctxt.clone()).await?;
|
||||
self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ use async_trait::async_trait;
|
||||
use log::{info, warn};
|
||||
use rog_platform::power::AsusPower;
|
||||
use rog_platform::supported::ChargeSupportedFunctions;
|
||||
use smol::Executor;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use zbus::dbus_interface;
|
||||
@@ -62,12 +61,11 @@ impl CtrlPower {
|
||||
err
|
||||
})
|
||||
.unwrap_or(100);
|
||||
self.set(limit)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlCharge: set_limit {}", err);
|
||||
err
|
||||
})
|
||||
.ok();
|
||||
if let Ok(mut config) = self.config.try_lock() {
|
||||
config.read();
|
||||
config.bat_charge_limit = limit;
|
||||
config.write();
|
||||
}
|
||||
|
||||
return config.bat_charge_limit;
|
||||
}
|
||||
@@ -129,15 +127,10 @@ impl CtrlPower {
|
||||
|
||||
#[async_trait]
|
||||
impl CtrlTask for CtrlPower {
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
signal_ctxt: SignalContext<'a>,
|
||||
) -> Result<(), RogError> {
|
||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||
let power1 = self.clone();
|
||||
let power2 = self.clone();
|
||||
self.create_sys_event_tasks(
|
||||
executor,
|
||||
move || {},
|
||||
move || {
|
||||
info!("CtrlCharge reloading charge limit");
|
||||
@@ -167,8 +160,7 @@ impl CtrlTask for CtrlPower {
|
||||
)
|
||||
.await;
|
||||
|
||||
self.watch_charge_control_end_threshold(executor, signal_ctxt)
|
||||
.await?;
|
||||
self.watch_charge_control_end_threshold(signal_ctxt).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::fan_curve_set::FanCurveSet;
|
||||
use rog_profiles::Profile;
|
||||
use rog_profiles::PLATFORM_PROFILE;
|
||||
use smol::Executor;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
use zbus::Connection;
|
||||
use zbus::SignalContext;
|
||||
|
||||
@@ -219,43 +219,39 @@ impl crate::ZbusAdd for ProfileZbus {
|
||||
|
||||
#[async_trait]
|
||||
impl CtrlTask for ProfileZbus {
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
signal_ctxt: SignalContext<'a>,
|
||||
) -> Result<(), RogError> {
|
||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||
let ctrl = self.inner.clone();
|
||||
let mut inotify = Inotify::init()?;
|
||||
inotify.add_watch(PLATFORM_PROFILE, WatchMask::MODIFY)?;
|
||||
let mut watch = Inotify::init()?;
|
||||
watch.add_watch(PLATFORM_PROFILE, WatchMask::CLOSE_WRITE)?;
|
||||
|
||||
executor
|
||||
.spawn(async move {
|
||||
let mut buffer = [0; 1024];
|
||||
loop {
|
||||
if let Ok(events) = inotify.read_events_blocking(&mut buffer) {
|
||||
for _ in events {
|
||||
let mut active_profile = None;
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
loop {
|
||||
watch
|
||||
.event_stream(&mut buffer)
|
||||
.unwrap()
|
||||
.for_each(|_| async {
|
||||
let mut active_profile = None;
|
||||
|
||||
if let Ok(ref mut lock) = ctrl.try_lock() {
|
||||
let new_profile = Profile::get_active_profile().unwrap();
|
||||
if new_profile != lock.config.active_profile {
|
||||
lock.config.active_profile = new_profile;
|
||||
lock.write_profile_curve_to_platform().unwrap();
|
||||
lock.save_config();
|
||||
active_profile = Some(lock.config.active_profile);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(active_profile) = active_profile {
|
||||
Self::notify_profile(&signal_ctxt, active_profile)
|
||||
.await
|
||||
.ok();
|
||||
if let Ok(ref mut lock) = ctrl.try_lock() {
|
||||
let new_profile = Profile::get_active_profile().unwrap();
|
||||
if new_profile != lock.config.active_profile {
|
||||
lock.config.active_profile = new_profile;
|
||||
lock.write_profile_curve_to_platform().unwrap();
|
||||
lock.save_config();
|
||||
active_profile = Some(lock.config.active_profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
if let Some(active_profile) = active_profile {
|
||||
Self::notify_profile(&signal_ctxt.clone(), active_profile)
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ use std::env;
|
||||
use std::error::Error;
|
||||
use std::io::Write;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use ::zbus::{Connection, SignalContext};
|
||||
use log::LevelFilter;
|
||||
use log::{error, info, warn};
|
||||
use smol::Executor;
|
||||
use tokio::time::sleep;
|
||||
|
||||
use daemon::ctrl_anime::config::AnimeConfig;
|
||||
use daemon::ctrl_anime::zbus::CtrlAnimeZbus;
|
||||
@@ -31,7 +32,8 @@ use rog_profiles::Profile;
|
||||
|
||||
static PROFILE_CONFIG_PATH: &str = "/etc/asusd/profile.conf";
|
||||
|
||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
.target(env_logger::Target::Stdout)
|
||||
@@ -60,14 +62,12 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
||||
info!("rog-platform v{}", rog_platform::VERSION);
|
||||
|
||||
let mut executor = Executor::new();
|
||||
|
||||
smol::block_on(start_daemon(&mut executor))?;
|
||||
start_daemon().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The actual main loop for the daemon
|
||||
async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>> {
|
||||
async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
let supported = SupportedFunctions::get_supported();
|
||||
print_board_info();
|
||||
println!("{}", serde_json::to_string_pretty(&supported)?);
|
||||
@@ -90,7 +90,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
|
||||
let task = CtrlRogBios::new(config.clone())?;
|
||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Platform")?;
|
||||
task.create_tasks(executor, sig).await.ok();
|
||||
task.create_tasks(sig).await.ok();
|
||||
}
|
||||
Err(err) => {
|
||||
error!("rog_bios_control: {}", err);
|
||||
@@ -107,7 +107,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
|
||||
let task = CtrlPower::new(config)?;
|
||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Charge")?;
|
||||
task.create_tasks(executor, sig).await.ok();
|
||||
task.create_tasks(sig).await.ok();
|
||||
}
|
||||
Err(err) => {
|
||||
error!("charge_control: {}", err);
|
||||
@@ -127,7 +127,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Profile")?;
|
||||
|
||||
let task = ProfileZbus::new(tmp.clone());
|
||||
task.create_tasks(executor, sig).await.ok();
|
||||
task.create_tasks(sig).await.ok();
|
||||
task.add_to_server(&mut connection).await;
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -152,7 +152,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
|
||||
let task = CtrlAnimeTask::new(inner).await;
|
||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Anime")?;
|
||||
task.create_tasks(executor, sig).await.ok();
|
||||
task.create_tasks(sig).await.ok();
|
||||
}
|
||||
Err(err) => {
|
||||
error!("AniMe control: {}", err);
|
||||
@@ -176,7 +176,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
|
||||
let task = CtrlKbdLedTask::new(inner);
|
||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Aura")?;
|
||||
task.create_tasks(executor, sig).await.ok();
|
||||
task.create_tasks(sig).await.ok();
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Keyboard control: {}", err);
|
||||
@@ -185,7 +185,9 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
|
||||
|
||||
// Request dbus name after finishing initalizing all functions
|
||||
connection.request_name(DBUS_NAME).await?;
|
||||
|
||||
loop {
|
||||
smol::block_on(executor.tick());
|
||||
// This is just a blocker to idle and ensure the reator reacts
|
||||
sleep(Duration::from_millis(1000)).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,10 @@ use std::time::Duration;
|
||||
|
||||
use crate::error::RogError;
|
||||
use async_trait::async_trait;
|
||||
use config::Config;
|
||||
use inotify::{Inotify, WatchMask};
|
||||
use log::warn;
|
||||
use logind_zbus::manager::ManagerProxy;
|
||||
use smol::{stream::StreamExt, Executor, Timer};
|
||||
use zbus::{Connection, SignalContext};
|
||||
use tokio::time;
|
||||
use zbus::{export::futures_util::StreamExt, Connection, SignalContext};
|
||||
use zvariant::ObjectPath;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@@ -65,6 +63,8 @@ pub trait ZbusAdd {
|
||||
/// - `notify_<name>(SignalContext, SomeValue)`
|
||||
///
|
||||
/// In most cases if `SomeValue` is stored in a config then `<name>()` getter is expected to update it.
|
||||
/// The getter should *never* write back to the path or attribute that is being watched or an
|
||||
/// infinite loop will occur.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -78,28 +78,24 @@ pub trait ZbusAdd {
|
||||
macro_rules! task_watch_item {
|
||||
($name:ident $self_inner:ident) => {
|
||||
concat_idents::concat_idents!(fn_name = watch_, $name {
|
||||
async fn fn_name<'a>(
|
||||
async fn fn_name(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
signal_ctxt: SignalContext<'a>,
|
||||
signal_ctxt: SignalContext<'static>,
|
||||
) -> Result<(), RogError> {
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
|
||||
let ctrl = self.clone();
|
||||
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||
let mut watch = self.$self_inner.watch_fn()?;
|
||||
executor
|
||||
.spawn(async move {
|
||||
let mut buffer = [0; 1024];
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch.event_stream(&mut buffer).unwrap().for_each(|_| async {
|
||||
let value = ctrl.$name();
|
||||
dbg!(value);
|
||||
concat_idents::concat_idents!(notif_fn = notify_, $name {
|
||||
Self::notif_fn(&signal_ctxt, value).await.unwrap();
|
||||
});
|
||||
}).await;
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
@@ -112,59 +108,23 @@ macro_rules! task_watch_item {
|
||||
pub trait CtrlTask {
|
||||
/// Implement to set up various tasks that may be required, using the `Executor`.
|
||||
/// No blocking loops are allowed, or they must be run on a separate thread.
|
||||
async fn create_tasks<'a>(
|
||||
&self,
|
||||
executor: &mut Executor<'a>,
|
||||
signal: SignalContext<'a>,
|
||||
) -> Result<(), RogError>;
|
||||
|
||||
/// Free method to run a task when the path is modified
|
||||
///
|
||||
/// Not very useful if you need to also do a zbus notification.
|
||||
fn create_tasks_inotify(
|
||||
&self,
|
||||
executor: &mut Executor,
|
||||
path: &str,
|
||||
mut task: impl FnMut() + Send + 'static,
|
||||
) -> Result<(), RogError> {
|
||||
let mut inotify = Inotify::init()?;
|
||||
inotify.add_watch(path, WatchMask::MODIFY)?;
|
||||
let mut buffer = [0; 1024];
|
||||
|
||||
executor
|
||||
.spawn(async move {
|
||||
loop {
|
||||
if let Ok(events) = inotify.read_events_blocking(&mut buffer) {
|
||||
for _ in events {
|
||||
task()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn create_tasks(&self, signal: SignalContext<'static>) -> Result<(), RogError>;
|
||||
|
||||
/// Create a timed repeating task
|
||||
async fn repeating_task(
|
||||
&self,
|
||||
millis: u64,
|
||||
executor: &mut Executor,
|
||||
mut task: impl FnMut() + Send + 'static,
|
||||
) {
|
||||
let timer = Timer::interval(Duration::from_millis(millis));
|
||||
executor
|
||||
.spawn(async move {
|
||||
timer.for_each(|_| task()).await;
|
||||
})
|
||||
.detach();
|
||||
async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send + 'static) {
|
||||
let mut timer = time::interval(Duration::from_millis(millis));
|
||||
tokio::spawn(async move {
|
||||
timer.tick().await;
|
||||
task();
|
||||
});
|
||||
}
|
||||
|
||||
/// Free helper method to create tasks to run on: sleep, wake, shutdown, boot
|
||||
///
|
||||
/// The closures can potentially block, so execution time should be the minimal possible
|
||||
/// such as save a variable.
|
||||
async fn create_sys_event_tasks(
|
||||
&self,
|
||||
executor: &mut Executor,
|
||||
mut on_sleep: impl FnMut() + Send + 'static,
|
||||
mut on_wake: impl FnMut() + Send + 'static,
|
||||
mut on_shutdown: impl FnMut() + Send + 'static,
|
||||
@@ -178,54 +138,40 @@ pub trait CtrlTask {
|
||||
.await
|
||||
.expect("Controller could not create ManagerProxy");
|
||||
|
||||
executor
|
||||
.spawn(async move {
|
||||
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
|
||||
notif
|
||||
.for_each(|event| {
|
||||
if let Ok(args) = event.args() {
|
||||
if args.start {
|
||||
on_sleep();
|
||||
} else if !args.start() {
|
||||
on_wake();
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
if let Ok(mut notif) = manager.receive_prepare_for_sleep().await {
|
||||
while let Some(event) = notif.next().await {
|
||||
if let Ok(args) = event.args() {
|
||||
if args.start {
|
||||
on_sleep();
|
||||
} else if !args.start() {
|
||||
on_wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
});
|
||||
|
||||
let manager = ManagerProxy::new(&connection)
|
||||
.await
|
||||
.expect("Controller could not create ManagerProxy");
|
||||
|
||||
executor
|
||||
.spawn(async move {
|
||||
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
|
||||
notif
|
||||
.for_each(|event| {
|
||||
if let Ok(args) = event.args() {
|
||||
if args.start {
|
||||
on_shutdown();
|
||||
} else if !args.start() {
|
||||
on_boot();
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
if let Ok(mut notif) = manager.receive_prepare_for_shutdown().await {
|
||||
while let Some(event) = notif.next().await {
|
||||
if let Ok(args) = event.args() {
|
||||
if args.start {
|
||||
on_shutdown();
|
||||
} else if !args.start() {
|
||||
on_boot();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CtrlTaskComplex {
|
||||
type A;
|
||||
|
||||
fn do_task(&mut self, config: &mut Config, event: Self::A);
|
||||
}
|
||||
|
||||
pub trait GetSupported {
|
||||
type A;
|
||||
|
||||
|
||||
@@ -156,7 +156,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
start_closed = false;
|
||||
continue;
|
||||
}
|
||||
dbg!("asda");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ impl eframe::App for AppErrorShow {
|
||||
.add(Button::new(RichText::new("Okay").size(20.0)))
|
||||
.clicked()
|
||||
{
|
||||
frame.quit();
|
||||
frame.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ impl<'a> RogApp<'a> {
|
||||
Button::new(RichText::new("❌").size(height - 4.0)).frame(false),
|
||||
);
|
||||
if close_response.clicked() {
|
||||
frame.quit();
|
||||
frame.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,6 @@ macro_rules! watch_attr {
|
||||
pub fn fn_name(&self) -> Result<inotify::Inotify> {
|
||||
let mut path = self.$item.clone();
|
||||
path.push($attr_name);
|
||||
dbg!(&path);
|
||||
let mut inotify = inotify::Inotify::init().unwrap();
|
||||
inotify.add_watch(path.to_str().unwrap(), inotify::WatchMask::MODIFY).unwrap();
|
||||
Ok(inotify)
|
||||
|
||||
Reference in New Issue
Block a user