130 lines
3.9 KiB
Rust
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; |