Anime: Enabled setting builtin animations

This commit is contained in:
Luke D. Jones
2023-06-21 13:34:08 +12:00
parent a0529e0efd
commit cd5daa17d0
15 changed files with 420 additions and 247 deletions

View File

@@ -2,78 +2,12 @@ use std::time::Duration;
use config_traits::{StdConfig, StdConfigLoad2};
use rog_anime::error::AnimeError;
use rog_anime::{ActionData, ActionLoader, AnimTime, AnimeType, Fade, Vec2};
use rog_anime::usb::Brightness;
use rog_anime::{ActionData, ActionLoader, AnimTime, Animations, AnimeType, Fade, Vec2};
use serde_derive::{Deserialize, Serialize};
const CONFIG_FILE: &str = "anime.ron";
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV341 {
pub system: Option<ActionLoader>,
pub boot: Option<ActionLoader>,
pub suspend: Option<ActionLoader>,
pub shutdown: Option<ActionLoader>,
}
impl From<AnimeConfigV341> for AnimeConfig {
fn from(c: AnimeConfigV341) -> AnimeConfig {
AnimeConfig {
system: if let Some(ani) = c.system {
vec![ani]
} else {
vec![]
},
boot: if let Some(ani) = c.boot {
vec![ani]
} else {
vec![]
},
wake: if let Some(ani) = c.suspend {
vec![ani]
} else {
vec![]
},
shutdown: if let Some(ani) = c.shutdown.clone() {
vec![ani]
} else {
vec![]
},
sleep: if let Some(ani) = c.shutdown.clone() {
vec![ani]
} else {
vec![]
},
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV352 {
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
}
impl From<AnimeConfigV352> for AnimeConfig {
fn from(c: AnimeConfigV352) -> AnimeConfig {
AnimeConfig {
system: c.system,
boot: c.boot,
wake: c.wake,
sleep: c.shutdown.clone(),
shutdown: c.shutdown,
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct AnimeConfigV460 {
pub system: Vec<ActionLoader>,
@@ -92,9 +26,32 @@ impl From<AnimeConfigV460> for AnimeConfig {
wake: c.wake,
sleep: c.sleep,
shutdown: c.shutdown,
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
..Default::default()
}
}
}
#[derive(Deserialize, Serialize, Debug)]
pub struct AnimeConfigV5 {
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
pub awake_enabled: bool,
pub boot_anim_enabled: bool,
}
impl From<AnimeConfigV5> for AnimeConfig {
fn from(c: AnimeConfigV5) -> AnimeConfig {
AnimeConfig {
system: c.system,
boot: c.boot,
wake: c.wake,
sleep: c.sleep,
shutdown: c.shutdown,
..Default::default()
}
}
}
@@ -156,8 +113,10 @@ pub struct AnimeConfig {
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
pub awake_enabled: bool,
pub boot_anim_enabled: bool,
pub display_enabled: bool,
pub display_brightness: Brightness,
pub builtin_anims_enabled: bool,
pub builtin_anims: Animations,
}
impl Default for AnimeConfig {
@@ -169,8 +128,10 @@ impl Default for AnimeConfig {
sleep: Vec::new(),
shutdown: Vec::new(),
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
display_enabled: true,
display_brightness: Brightness::Med,
builtin_anims_enabled: true,
builtin_anims: Animations::default(),
}
}
}
@@ -189,7 +150,7 @@ impl StdConfig for AnimeConfig {
}
}
impl StdConfigLoad2<AnimeConfigV341, AnimeConfigV352> for AnimeConfig {}
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV5> for AnimeConfig {}
impl AnimeConfig {
// fn clamp_config_brightness(mut config: &mut AnimeConfig) {
@@ -247,8 +208,7 @@ impl AnimeConfig {
time: AnimTime::Infinite,
}],
brightness: 1.0,
awake_enabled: true,
boot_anim_enabled: true,
..Default::default()
}
}
}

View File

@@ -11,7 +11,7 @@ use std::thread::sleep;
use ::zbus::export::futures_util::lock::Mutex;
use log::{error, info, warn};
use rog_anime::error::AnimeError;
use rog_anime::usb::{get_anime_type, pkt_for_flush, pkts_for_init};
use rog_anime::usb::{get_anime_type, pkt_flush, pkt_set_enable_powersave_anim, pkts_for_init};
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType};
use rog_platform::hid_raw::HidRaw;
use rog_platform::supported::AnimeSupportedFunctions;
@@ -72,12 +72,21 @@ impl CtrlAnime {
///
/// Because this also writes to the usb device, other write tries (display
/// only) *must* get the mutex lock and set the `thread_exit` atomic.
fn run_thread(inner: Arc<Mutex<CtrlAnime>>, actions: Vec<ActionData>, mut once: bool) {
async fn run_thread(inner: Arc<Mutex<CtrlAnime>>, actions: Vec<ActionData>, mut once: bool) {
if actions.is_empty() {
warn!("AniMe system actions was empty");
return;
}
if let Some(lock) = inner.try_lock() {
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
}
// Loop rules:
// - Lock the mutex **only when required**. That is, the lock must be held for
// the shortest duration possible.
@@ -211,7 +220,7 @@ impl CtrlAnime {
for row in &data {
self.node.write_bytes(row)?;
}
self.node.write_bytes(&pkt_for_flush())?;
self.node.write_bytes(&pkt_flush())?;
Ok(())
}

View File

@@ -5,10 +5,10 @@ use async_trait::async_trait;
use config_traits::StdConfig;
use log::warn;
use rog_anime::usb::{
pkt_for_enable_animation, pkt_for_set_awake_enabled, pkt_for_set_boot, pkt_for_set_brightness,
Brightness,
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
pkt_set_enable_powersave_anim, AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness,
};
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
use rog_anime::{AnimeDataBuffer, DeviceState};
use zbus::export::futures_util::lock::Mutex;
use zbus::{dbus_interface, Connection, SignalContext};
@@ -65,83 +65,125 @@ impl CtrlAnimeZbus {
#[zbus(signal_context)] ctxt: SignalContext<'_>,
brightness: Brightness,
) {
let lock = self.0.lock().await;
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_for_set_brightness(brightness))
.write_bytes(&pkt_set_brightness(brightness))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
// lock.config.write();
lock.config.display_brightness = brightness;
lock.config.write();
Self::notify_power_states(
Self::notify_device_state(
&ctxt,
AnimePowerStates {
brightness: lock.config.brightness.floor() as u8,
enabled: lock.config.awake_enabled,
boot_anim_enabled: lock.config.boot_anim_enabled,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Set whether the AniMe is displaying images/data
async fn set_awake_enabled(
/// Enable the builtin animations or not
async fn set_builtins_enabled(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
status: bool,
enabled: bool,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_for_set_awake_enabled(status))
.write_bytes(&pkt_set_enable_powersave_anim(enabled))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.awake_enabled = status;
lock.config.builtin_anims_enabled = enabled;
lock.config.write();
if enabled {
lock.thread_exit.store(true, Ordering::Release);
}
Self::notify_power_states(
Self::notify_device_state(
&ctxt,
AnimePowerStates {
brightness: lock.config.brightness.floor() as u8,
enabled: lock.config.awake_enabled,
boot_anim_enabled: lock.config.boot_anim_enabled,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Set whether the AniMe will show boot, suspend, or off animations
async fn set_animation_enabled(
/// Set which builtin animation is used for each stage
async fn set_builtin_animations(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
on: bool,
boot: AnimBooting,
awake: AnimAwake,
sleep: AnimSleeping,
shutdown: AnimShutdown,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_for_set_boot(on))
.write_bytes(&pkt_set_enable_powersave_anim(true))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.node
.write_bytes(&pkt_for_enable_animation())
.write_bytes(&pkt_set_builtin_animations(boot, awake, sleep, shutdown))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.boot_anim_enabled = on;
lock.config.builtin_anims.boot = boot;
lock.config.builtin_anims.sleep = sleep;
lock.config.builtin_anims.awake = awake;
lock.config.builtin_anims.shutdown = shutdown;
lock.config.write();
Self::notify_power_states(
Self::notify_device_state(
&ctxt,
AnimePowerStates {
brightness: lock.config.brightness.floor() as u8,
enabled: lock.config.awake_enabled,
boot_anim_enabled: lock.config.boot_anim_enabled,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
.ok();
}
/// Set whether the AniMe is enabled at all
async fn set_enable_display(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: bool,
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_display(enabled))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
lock.config.display_enabled = enabled;
lock.config.write();
Self::notify_device_state(
&ctxt,
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
},
)
.await
@@ -154,31 +196,26 @@ impl CtrlAnimeZbus {
if start {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false);
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false).await;
}
}
/// Get status of if the AniMe LEDs are on/displaying while system is awake
#[dbus_interface(property)]
async fn awake_enabled(&self) -> bool {
/// Get the device state as stored by asusd
// #[dbus_interface(property)]
async fn device_state(&self) -> DeviceState {
let lock = self.0.lock().await;
lock.config.awake_enabled
}
/// Get the status of if factory system-status animations are enabled
#[dbus_interface(property)]
async fn animation_enabled(&self) -> bool {
let lock = self.0.lock().await;
lock.config.boot_anim_enabled
DeviceState {
display_enabled: lock.config.display_enabled,
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
}
}
/// Notify listeners of the status of AniMe LED power and factory
/// system-status animations
#[dbus_interface(signal)]
async fn notify_power_states(
ctxt: &SignalContext<'_>,
data: AnimePowerStates,
) -> zbus::Result<()>;
async fn notify_device_state(ctxt: &SignalContext<'_>, data: DeviceState) -> zbus::Result<()>;
}
#[async_trait]
@@ -198,7 +235,7 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true);
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true).await;
}
},
move || {
@@ -206,7 +243,7 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true);
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true).await;
}
},
move || {
@@ -214,7 +251,7 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true);
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true).await;
}
},
move || {
@@ -222,7 +259,7 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true);
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true).await;
}
},
)
@@ -236,14 +273,26 @@ impl crate::CtrlTask for CtrlAnimeZbus {
impl crate::Reloadable for CtrlAnimeZbus {
async fn reload(&mut self) -> Result<(), RogError> {
if let Some(lock) = self.0.try_lock() {
// TODO: restore new settings
// lock.node
// .write_bytes(&pkt_for_set_brightness(lock.config.awake_enabled))?;
let anim = &lock.config.builtin_anims;
lock.node
.write_bytes(&pkt_for_set_boot(lock.config.boot_anim_enabled))?;
.write_bytes(&pkt_set_enable_display(lock.config.display_enabled))?;
lock.node.write_bytes(&pkt_set_enable_powersave_anim(
lock.config.builtin_anims_enabled,
))?;
lock.node.write_bytes(&pkt_set_builtin_animations(
anim.boot,
anim.awake,
anim.sleep,
anim.shutdown,
))?;
if lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false))
.ok();
}
let action = lock.cache.boot.clone();
CtrlAnime::run_thread(self.0.clone(), action, true);
CtrlAnime::run_thread(self.0.clone(), action, true).await;
}
Ok(())
}