diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index bac3e48..68235b0 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -563,6 +563,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + [[package]] name = "embed_plist" version = "1.2.2" @@ -1266,6 +1272,15 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -2758,6 +2773,7 @@ dependencies = [ "display-info", "env_logger", "hex", + "itertools", "log", "paho-mqtt", "paris", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 29f282c..edd8ba8 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -30,6 +30,7 @@ hex = "0.4.3" toml = "0.7.3" paho-mqtt = "0.12.1" time = {version="0.3.20", features= ["formatting"] } +itertools = "0.10.5" [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/src/ambient_light/config.rs b/src-tauri/src/ambient_light/config.rs index 5d25d88..8012120 100644 --- a/src-tauri/src/ambient_light/config.rs +++ b/src-tauri/src/ambient_light/config.rs @@ -1,4 +1,4 @@ -use std::env::current_dir; +use std::{env::current_dir, fmt::format}; use paris::{error, info}; use serde::{Deserialize, Serialize}; @@ -56,6 +56,8 @@ impl LedStripConfigGroup { let config: LedStripConfigGroup = toml::from_str(&config) .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; + log::info!("config loaded: {:?}", config.strips.iter().map(|c| format!("{}#{}", c.index, c.display_id)).collect::>()); + Ok(config) } else { info!("config file not exist, fallback to default config"); diff --git a/src-tauri/src/ambient_light/config_manager.rs b/src-tauri/src/ambient_light/config_manager.rs index bcde3ec..9a21ced 100644 --- a/src-tauri/src/ambient_light/config_manager.rs +++ b/src-tauri/src/ambient_light/config_manager.rs @@ -5,7 +5,7 @@ use tokio::sync::OnceCell; use crate::ambient_light::{config, LedStripConfigGroup}; -use super::Border; +use super::{Border, SamplePointMapper}; pub struct ConfigManager { config: Arc>, @@ -62,19 +62,21 @@ impl ConfigManager { ) -> anyhow::Result<()> { let mut config = self.config.write().await; - for config in config.strips.iter_mut() { - if config.display_id == display_id && config.border == border { - let target = config.len as i64 + delta_len as i64; + for strip in config.strips.iter_mut() { + if strip.display_id == display_id && strip.border == border { + let target = strip.len as i64 + delta_len as i64; if target < 0 || target > 1000 { return Err(anyhow::anyhow!( "Overflow. range: 0-1000, current: {}", target )); } - config.len = target as usize; + strip.len = target as usize; } } + Self::rebuild_mappers(&mut config); + let cloned_config = config.clone(); drop(config); @@ -88,6 +90,24 @@ impl ConfigManager { Ok(()) } + fn rebuild_mappers(config: &mut LedStripConfigGroup) { + let mut prev_end = 0; + let mappers: Vec = config + .strips + .iter() + .map(|strip| { + let mapper = SamplePointMapper { + start: prev_end, + end: prev_end + strip.len, + }; + prev_end = mapper.end; + mapper + }) + .collect(); + + config.mappers = mappers; + } + pub async fn set_items(&self, items: Vec) -> anyhow::Result<()> { let mut config = self.config.write().await; diff --git a/src-tauri/src/ambient_light/publisher.rs b/src-tauri/src/ambient_light/publisher.rs index 0597208..08c1cd1 100644 --- a/src-tauri/src/ambient_light/publisher.rs +++ b/src-tauri/src/ambient_light/publisher.rs @@ -10,6 +10,8 @@ use crate::{ screenshot_manager::ScreenshotManager, }; +use itertools::Itertools; + pub struct LedColorsPublisher { rx: Arc>>>, tx: Arc>>>, @@ -45,15 +47,30 @@ impl LedColorsPublisher { let configs = config_manager.configs().await; let channels = screenshot_manager.channels.read().await; + let display_ids = configs + .strips + .iter() + .map(|c| c.display_id) + .unique().collect::>(); + let mut colors_configs = Vec::new(); - for (display_id, rx) in channels.iter() { + for display_id in display_ids { let led_strip_configs: Vec<_> = configs .strips .iter() - .filter(|c| c.display_id == *display_id) + .filter(|c| c.display_id == display_id) .collect(); + let rx = channels.get(&display_id); + + if rx.is_none() { + warn!("no channel for display_id: {}", display_id); + continue; + } + + let rx = rx.unwrap(); + if led_strip_configs.len() == 0 { warn!("no led strip config for display_id: {}", display_id); continue; @@ -72,14 +89,16 @@ impl LedColorsPublisher { .collect(); let colors_config = config::SamplePointConfig { - display_id: *display_id, + display_id, points, }; colors_configs.push(colors_config); } } - let colors = screenshot_manager.get_all_colors(&colors_configs, &configs.mappers, &channels).await; + let colors = screenshot_manager + .get_all_colors(&colors_configs, &configs.mappers, &channels) + .await; match tx.send(colors) { Ok(_) => { // log::info!("colors updated"); diff --git a/src-tauri/src/screenshot_manager.rs b/src-tauri/src/screenshot_manager.rs index d21e054..b0139ed 100644 --- a/src-tauri/src/screenshot_manager.rs +++ b/src-tauri/src/screenshot_manager.rs @@ -226,6 +226,7 @@ impl ScreenshotManager { let mut global_colors = vec![0u8; total_leds * 3]; let mut all_colors = vec![]; + for config in configs { let rx = channels.get(&config.display_id); if rx.is_none() { @@ -244,11 +245,12 @@ impl ScreenshotManager { let mut color_index = 0; mappers.iter().for_each(|group| { - if group.end >= all_colors.len() || group.start >= all_colors.len() { + if group.end > all_colors.len() || group.start > all_colors.len() { + warn!("get_all_colors: group out of range. start: {}, end: {}, all_colors.len(): {}", group.start, group.end, all_colors.len()); return; - } + } if group.end > group.start { - for i in group.start..group.end - 1 { + for i in group.start..group.end { let rgb = all_colors[color_index].get_rgb(); color_index += 1; @@ -257,7 +259,7 @@ impl ScreenshotManager { global_colors[i * 3 + 2] = rgb[2]; } } else { - for i in (group.end..group.start - 1).rev() { + for i in (group.end..group.start).rev() { let rgb = all_colors[color_index].get_rgb(); color_index += 1;