From ece565de1c9025da09605dda58a260cada0abb44 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Fri, 9 Apr 2021 23:15:56 +1200 Subject: [PATCH] anime: tweak gif animation time types --- asusctl/examples/animatrix-gif.rs | 2 +- asusctl/examples/animatrix-png-gif.rs | 22 +++--- daemon-user/src/main.rs | 28 +++++--- daemon-user/src/user_config.rs | 22 +++--- data/user-example.json | 99 ++++++++++++++++----------- rog-anime/src/gif.rs | 22 ++++-- rog-anime/src/sequencer.rs | 6 +- 7 files changed, 124 insertions(+), 77 deletions(-) diff --git a/asusctl/examples/animatrix-gif.rs b/asusctl/examples/animatrix-gif.rs index 3bd1f63e..6bc94aad 100644 --- a/asusctl/examples/animatrix-gif.rs +++ b/asusctl/examples/animatrix-gif.rs @@ -15,7 +15,7 @@ fn main() { let path = Path::new(&args[1]); let brightness = args[2].parse::().unwrap(); let mut seq = Sequences::new(); - seq.add_asus_gif(path, None, brightness).unwrap(); + seq.add_asus_gif(path, rog_anime::AnimTime::Infinite, brightness).unwrap(); loop { for action in seq.iter() { diff --git a/asusctl/examples/animatrix-png-gif.rs b/asusctl/examples/animatrix-png-gif.rs index b2af2eaa..ecfa6c19 100644 --- a/asusctl/examples/animatrix-png-gif.rs +++ b/asusctl/examples/animatrix-png-gif.rs @@ -6,7 +6,7 @@ use std::{ }; use glam::Vec2; -use rog_anime::{Action, Sequences}; +use rog_anime::{Action, AnimTime, Sequences}; use rog_dbus::AuraDbusClient; fn main() { @@ -32,12 +32,12 @@ fn main() { ), if let Ok(time) = args[7].parse::() { if time != 0 { - Some(Duration::from_secs(time)) + AnimTime::Time(Duration::from_secs(time)) } else { - None + AnimTime::Infinite } } else { - None + AnimTime::Infinite }, args[6].parse::().unwrap(), ) @@ -54,12 +54,12 @@ fn main() { ), if let Ok(time) = args[7].parse::() { if time != 0 { - Some(Duration::from_secs(time)) + AnimTime::Time(Duration::from_secs(time)) } else { - None + AnimTime::Infinite } } else { - None + AnimTime::Infinite }, args[6].parse::().unwrap(), ) @@ -69,6 +69,7 @@ fn main() { loop { for action in seq.iter() { if let Action::Animation(frames) = action { + let mut count = 0; let start = Instant::now(); 'outer: loop { for frame in frames.frames() { @@ -77,13 +78,18 @@ fn main() { .anime() .write(frame.frame().clone()) .unwrap(); - if let Some(time) = frames.duration() { + if let AnimTime::Time(time) = frames.duration() { if Instant::now().duration_since(start) > time { break 'outer; } + } else if let AnimTime::Cycles(times) = frames.duration() { + if count == times { + break 'outer; + } } sleep(frame.delay()); } + count +=1; } } } diff --git a/daemon-user/src/main.rs b/daemon-user/src/main.rs index db224b72..cf0eae41 100644 --- a/daemon-user/src/main.rs +++ b/daemon-user/src/main.rs @@ -1,4 +1,4 @@ -use rog_anime::Action; +use rog_anime::{Action, AnimTime}; use rog_dbus::AuraDbusClient; use rog_user::user_config::*; @@ -27,20 +27,26 @@ fn main() -> Result<(), Box> { let start = Instant::now(); match action { - Action::Animation(frames) => 'animation: loop { - for frame in frames.frames() { - client.proxies().anime().write(frame.frame().clone())?; - if let Some(time) = frames.duration() { - if Instant::now().duration_since(start) > time { + Action::Animation(frames) => { + let mut count = 0; + 'animation: loop { + for frame in frames.frames() { + client.proxies().anime().write(frame.frame().clone())?; + if let AnimTime::Time(time) = frames.duration() { + if Instant::now().duration_since(start) > time { + break 'animation; + } + } + sleep(frame.delay()); + } + if let AnimTime::Cycles(times) = frames.duration() { + count += 1; + if count >= times { break 'animation; } } - sleep(frame.delay()); } - if frames.duration().is_none() { - break 'animation; - } - }, + } Action::Image(image) => { client.proxies().anime().write(image.as_ref().clone())?; } diff --git a/daemon-user/src/user_config.rs b/daemon-user/src/user_config.rs index f346b055..dd886f93 100644 --- a/daemon-user/src/user_config.rs +++ b/daemon-user/src/user_config.rs @@ -5,7 +5,7 @@ use std::{ time::Duration, }; -use rog_anime::{Sequences, Vec2}; +use rog_anime::{AnimTime, Sequences, Vec2}; use serde_derive::{Deserialize, Serialize}; use crate::error::Error; @@ -20,7 +20,7 @@ pub enum AnimeAction { /// Full gif sequence. Immutable. AsusAnimation { file: PathBuf, - duration: Option, + time: AnimTime, brightness: f32, }, /// Basic image, can have properties changed @@ -29,7 +29,7 @@ pub enum AnimeAction { scale: f32, angle: f32, translation: Vec2, - duration: Option, + time: AnimTime, brightness: f32, }, Image { @@ -45,12 +45,12 @@ pub enum AnimeAction { impl UserConfig { pub fn new() -> Self { - Self { + let x = Self { anime: vec![ AnimeAction::AsusAnimation { file: "/usr/share/asusd/anime/asus/rog/Sunset.gif".into(), brightness: 0.5, - duration: None, + time: AnimTime::Cycles(1), }, AnimeAction::ImageAnimation { file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(), @@ -58,7 +58,7 @@ impl UserConfig { angle: 0.65, translation: Vec2::default(), brightness: 0.5, - duration: Some(Duration::from_secs(5)), + time: AnimTime::Time(Duration::from_secs(5)), }, AnimeAction::Image { file: "/usr/share/asusd/anime/custom/rust.png".into(), @@ -74,10 +74,12 @@ impl UserConfig { angle: 0.0, translation: Vec2::new(3.0, 2.0), brightness: 0.5, - duration: None, + time: AnimTime::Cycles(2), }, ], - } + }; + println!("{}", serde_json::to_string_pretty(&x).unwrap()); + x } pub fn load_config(&mut self) -> Result<(), Error> { @@ -122,7 +124,7 @@ impl UserConfig { match anime { AnimeAction::AsusAnimation { file, - duration, + time: duration, brightness, } => seq.add_asus_gif(&file, *duration, *brightness)?, AnimeAction::ImageAnimation { @@ -130,7 +132,7 @@ impl UserConfig { scale, angle, translation, - duration, + time: duration, brightness, } => { seq.add_image_gif(&file, *scale, *angle, *translation, *duration, *brightness)? diff --git a/data/user-example.json b/data/user-example.json index b80d8e3e..9f3600e9 100644 --- a/data/user-example.json +++ b/data/user-example.json @@ -1,45 +1,64 @@ { - "anime": [ - { - "AsusAnimation": { - "file": "/usr/share/asusd/anime/asus/Controller.gif", - "duration": { + "anime": [ + { + "AsusAnimation": { + "file": "/usr/share/asusd/anime/asus/rog/Sunset.gif", + "time": { + "Cycles": 1 + }, + "brightness": 0.5 + } + }, + { + "ImageAnimation": { + "file": "/usr/share/asusd/anime/custom/sonic-run.gif", + "scale": 0.9, + "angle": 0.65, + "translation": [ + 0.0, + 0.0 + ], + "time": { + "Time": { "secs": 5, "nanos": 0 } - } - }, - { - "ImageAnimation": { - "file": "/usr/share/asusd/anime/sonic.gif", - "scale": 0.9, - "angle": 0.65, - "translation": [ - 0.0, - 0.0 - ], - "duration": { - "secs": 5, - "nanos": 0 - }, - "brightness": 0.5 - } - }, - { - "Image": { - "file_path": "/usr/share/asusd/anime/doom.png", - "scale": 0.7, - "angle": 0.0, - "translation": [ - 0.0, - 0.0 - ], - "duration": { - "secs": 5, - "nanos": 0 - }, - "brightness": 0.6 - } + }, + "brightness": 0.5 } - ] - } \ No newline at end of file + }, + { + "Image": { + "file": "/usr/share/asusd/anime/custom/rust.png", + "scale": 1.0, + "angle": 0.0, + "translation": [ + 0.0, + 0.0 + ], + "brightness": 0.6 + } + }, + { + "Pause": { + "secs": 6, + "nanos": 0 + } + }, + { + "ImageAnimation": { + "file": "/usr/share/asusd/anime/custom/sonic-wait.gif", + "scale": 0.9, + "angle": 0.0, + "translation": [ + 3.0, + 2.0 + ], + "time": { + "Cycles": 2 + }, + "brightness": 0.5 + } + } + ] +} diff --git a/rog-anime/src/gif.rs b/rog-anime/src/gif.rs index 59b837a7..28d879bc 100644 --- a/rog-anime/src/gif.rs +++ b/rog-anime/src/gif.rs @@ -22,16 +22,30 @@ impl AniMeFrame { } } +#[derive(Debug, Copy, Clone, Deserialize, Serialize)] +pub enum AnimTime { + Time(Duration), + Cycles(u32), + Infinite, +} + +impl Default for AnimTime { + fn default() -> Self { + Self::Infinite + } +} + + /// A gif animation. This is a collection of frames from the gif, and a duration /// that the animation should be shown for. #[derive(Debug, Clone, Deserialize, Serialize)] -pub struct AniMeGif(Vec, Option); +pub struct AniMeGif(Vec, AnimTime); impl AniMeGif { /// Create an animation using the 74x36 ASUS gif format pub fn create_diagonal_gif( file_name: &Path, - duration: Option, + duration: AnimTime, brightness: f32, ) -> Result { let mut matrix = AniMeDiagonal::new(None); @@ -75,7 +89,7 @@ impl AniMeGif { scale: f32, angle: f32, translation: Vec2, - duration: Option, + duration: AnimTime, brightness: f32, ) -> Result { let mut frames = Vec::new(); @@ -142,7 +156,7 @@ impl AniMeGif { &self.0 } - pub fn duration(&self) -> Option { + pub fn duration(&self) -> AnimTime { self.1 } } diff --git a/rog-anime/src/sequencer.rs b/rog-anime/src/sequencer.rs index 0db9fcde..9948567a 100644 --- a/rog-anime/src/sequencer.rs +++ b/rog-anime/src/sequencer.rs @@ -3,7 +3,7 @@ use std::{path::Path, time::Duration}; use glam::Vec2; use serde_derive::{Deserialize, Serialize}; -use crate::{error::AnimeError, AniMeDataBuffer, AniMeGif, AniMeImage}; +use crate::{AniMeDataBuffer, AniMeGif, AniMeImage, AnimTime, error::AnimeError}; /// #[derive(Debug, Deserialize, Serialize)] @@ -36,7 +36,7 @@ impl Sequences { pub fn add_asus_gif( &mut self, file: &Path, - duration: Option, + duration: AnimTime, brightness: f32, ) -> Result<(), AnimeError> { let frames = AniMeGif::create_diagonal_gif(file, duration, brightness)?; @@ -64,7 +64,7 @@ impl Sequences { scale: f32, angle: f32, translation: Vec2, - duration: Option, + duration: AnimTime, brightness: f32, ) -> Result<(), AnimeError> { let frames =