diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index 4c482294..75e9eeb3 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -89,7 +89,7 @@ pub async fn start_daemon() -> Result<(), Box> { let (aura_command_send, aura_command_recv) = mpsc::sync_channel::(1); - let (tree, input, effect, animatrix_img, fan_mode, effect_cancel_signal) = dbus_create_tree(); + let (tree, input, effect, mut animatrix_recv, fan_mode, effect_cancel_signal) = dbus_create_tree(); // We add the tree to the connection so that incoming method calls will be handled. tree.start_receive_send(&*connection); @@ -192,17 +192,6 @@ pub async fn start_daemon() -> Result<(), Box> { } } - // If animatrix is supported, try doing a write - if let Some(writer) = animatrix_writer.as_mut() { - let mut image_lock = animatrix_img.lock().await; - if let Some(image) = image_lock.take() { - writer - .do_command(AnimatrixCommand::WriteImage(image)) - .await - .unwrap_or_else(|err| warn!("{:?}", err)); - } - } - let now = Instant::now(); // Cool-down steps // This block is to prevent the loop spooling as fast as possible and saturating the CPU @@ -216,6 +205,20 @@ pub async fn start_daemon() -> Result<(), Box> { } }); + // If animatrix is supported, try doing a write + let animatrix_write_handle = tokio::spawn(async move { + if let Some(writer) = animatrix_writer.as_mut() { + while let Some(image) = animatrix_recv.recv().await { + writer + .do_command(AnimatrixCommand::WriteImage(image)) + .await + .unwrap_or_else(|err| warn!("{:?}", err)); + + } + } + }); + + animatrix_write_handle.await?; led_write_handle.await?; key_read_handle.await?; Ok(()) diff --git a/rog-core/src/rog_dbus.rs b/rog-core/src/rog_dbus.rs index f8294f5e..ad4cd1e3 100644 --- a/rog-core/src/rog_dbus.rs +++ b/rog-core/src/rog_dbus.rs @@ -99,16 +99,17 @@ pub(super) fn dbus_create_ledeffect_method(effect: NestedVecType) -> Method Method { +pub(super) fn dbus_create_animatrix_method(sender: Arc>>>>) -> Method { let factory = Factory::new_sync::<()>(); factory // method for ledmessage .method("AnimatrixWrite", (), { move |m| { - if let Ok(mut lock) = effect.try_lock() { - let mut iter = m.msg.iter_init(); - let byte_array: Vec> = vec![iter.read()?, iter.read()?]; - *lock = Some(byte_array); + let mut iter = m.msg.iter_init(); + let byte_array: Vec> = vec![iter.read()?, iter.read()?]; + if let Ok(mut lock) = sender.try_lock() { + // Ignore errors if the channel is already full + lock.try_send(byte_array).unwrap_or_else(|_err| {}); Ok(vec![]) } else { Err(MethodErr::failed("Could not lock daemon for access")) @@ -148,13 +149,13 @@ pub(super) fn dbus_create_tree() -> ( Tree, LedMsgType, NestedVecType, - NestedVecType, + tokio::sync::mpsc::Receiver>>, FanModeType, Arc>, ) { let input_bytes: LedMsgType = Arc::new(Mutex::new(None)); let input_effect: NestedVecType = Arc::new(Mutex::new(None)); - let animatrix_img: NestedVecType = Arc::new(Mutex::new(None)); + let (animatrix_send, animatrix_recv) = tokio::sync::mpsc::channel::>>(1); let fan_mode: FanModeType = Arc::new(Mutex::new(None)); let factory = Factory::new_sync::<()>(); @@ -168,7 +169,7 @@ pub(super) fn dbus_create_tree() -> ( .add_m(dbus_create_ledmsg_method(input_bytes.clone())) .add_m(dbus_create_ledmultizone_method(input_effect.clone())) .add_m(dbus_create_ledeffect_method(input_effect.clone())) - .add_m(dbus_create_animatrix_method(animatrix_img.clone())) + .add_m(dbus_create_animatrix_method(Arc::new(Mutex::new(animatrix_send)))) .add_m(dbus_create_fan_mode_method(fan_mode.clone())) .add_s(effect_cancel_sig.clone()), ), @@ -178,7 +179,7 @@ pub(super) fn dbus_create_tree() -> ( tree, input_bytes, input_effect, - animatrix_img, + animatrix_recv, fan_mode, effect_cancel_sig, )