use std::{collections::HashMap, time::Duration}; use common::{BulbPrefs, Param}; use lighter_lib::{BulbColor, BulbId}; use lighter_manager::manager::{BulbCommand, BulbManager, BulbSelector}; use rand::random; use tokio::{spawn, time::sleep}; use crate::util::DeadMansHandle; use super::LightScript; pub struct Party { manager: BulbManager, party_tasks: HashMap, } impl Party { pub fn create(manager: BulbManager) -> Self { Party { manager, party_tasks: Default::default(), } } } impl LightScript for Party { fn get_params(&mut self, bulb: &BulbId) -> BulbPrefs { let enabled = self.party_tasks.get(bulb).is_some(); BulbPrefs { kvs: [("Party".to_string(), Param::Toggle(enabled))] .into_iter() .collect(), } } fn set_param(&mut self, bulb: &BulbId, name: &str, param: Param) { if name != "Party" { error!("invalid param name"); return; } let Param::Toggle(enabled) = param else { error!("invalid param kind"); return; }; if !enabled { self.party_tasks.remove(bulb); } else { let task = spawn(party_task(self.manager.clone(), bulb.clone())); self.party_tasks .insert(bulb.clone(), DeadMansHandle(task.abort_handle())); } } } async fn party_task(manager: BulbManager, id: BulbId) { manager .until_interrupted(id.clone(), async { let mut h: f32 = random(); loop { sleep(Duration::from_millis(50)).await; h += 0.01; if h > 1.0 { h = 0.0; } let color = BulbColor::HSB { h, s: 1.0, b: 1.0 }; manager .send_command(BulbCommand::SetColor(BulbSelector::Id(id.clone()), color)) .await; } }) .await; }