Files
renderbug/src/scenes.rs
2024-12-15 19:27:27 +01:00

130 lines
3.9 KiB
Rust

use crate::task::Task;
use crate::events::*;
use crate::properties::*;
use paste::paste;
#[derive(Debug, PartialEq, Eq, Clone)]
struct Scene {
name: &'static str,
patterns: Vec<&'static str>,
trigger: Trigger
}
#[derive(Debug, PartialEq, Eq, Clone)]
enum Trigger {
Startup,
PropertyEquals(PropertyID, Variant)
}
pub struct Sequencer {
scenes: Vec<Scene>,
cur_scene: String
}
impl Sequencer {
pub fn new() -> Self {
Sequencer {
cur_scene: String::new(),
scenes: vec![
Scene {
name: "Start",
patterns: vec!["Idle"],
trigger: Trigger::Startup
},
Scene {
name: "Online",
patterns: vec!["Idle"],
trigger: Trigger::PropertyEquals(prop_id!(System::NetworkOnline), Variant::Boolean(true))
}
]
}
}
fn get_scene(&self, name: &String) -> Option<&Scene> {
for scene in self.scenes.iter() {
if scene.name == name {
return Some(scene);
}
}
return None;
}
fn apply_scene(&mut self, name: &String, bus: &mut EventBus) {
if let Some(dst_tasks) = self.get_scene(name) {
if let Some(src_tasks) = self.get_scene(&self.cur_scene) {
let stop_queue = src_tasks.patterns.iter().filter(|i| !dst_tasks.patterns.contains(i));
let start_queue = dst_tasks.patterns.iter().filter(|i| !src_tasks.patterns.contains(i));
log::info!("Switching scene from {} to {}", self.cur_scene, name);
for stop in stop_queue {
bus.push(Event::new_stop_thing(stop));
}
for start in start_queue {
bus.push(Event::new_start_thing(start));
}
} else {
log::info!("Starting new scene {}", name);
log::info!("start={:?}", dst_tasks.patterns);
for start in dst_tasks.patterns.iter() {
bus.push(Event::new_start_thing(start));
}
}
self.cur_scene = name.clone();
} else {
panic!("Could not apply scene {:?} scenes={:?}", name, self.scenes);
}
}
}
pub mod props {
use crate::property_namespace;
property_namespace!(
Scenes,
Current => "",
All => Vec::new()
);
}
use crate::scenes::props::Scenes;
impl Task for Sequencer {
fn start(&mut self, bus: &mut EventBus) {
log::info!("Starting sequencer!!!");
let startup_scene = self.scenes.iter().filter(|i| { i.trigger == Trigger::Startup }).next().unwrap();
bus.set_property(Scenes::Current, startup_scene.name);
let mut scene_list = Vec::new();
for scene in self.scenes.iter() {
scene_list.push(Variant::String(scene.name.to_string()));
}
bus.set_property(Scenes::All, scene_list);
}
fn on_property_change(&mut self, key: PropertyID, value: &Variant, bus: &mut EventBus) {
match (key, value) {
(prop_id!(Scenes::Current), Variant::String(ref scene_name)) => {
log::info!("Applying scene");
self.apply_scene(scene_name, bus);
},
(key, value) => {
/*for scene in self.scenes.iter() {
match scene.trigger {
Trigger::PropertyEquals(trigger_key, ref trigger_value) => {
if trigger_key == key && trigger_value == value {
log::info!("Triggering scene {}", scene.name);
bus.push(Scenes::Current.new_property_change(scene.name))
}
},
_ => ()
}
}*/
}
}
}
}
use crate::prop_id;