task: rewrite event handling as a step towards event-based subscriptions
This commit is contained in:
111
src/scenes.rs
Normal file
111
src/scenes.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::task::Task;
|
||||
use crate::events::*;
|
||||
|
||||
#[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(&'static str, 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("system.network.online", 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.push(Event::new_property_change("scenes.current", startup_scene.name));
|
||||
}
|
||||
|
||||
fn on_property_change(&mut self, key: &'static str, value: &Variant, bus: &mut EventBus) {
|
||||
match (key, value) {
|
||||
("scenes.current", Variant::String(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(Event::new_property_change("scenes.current", scene.name))
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user