deckster/src/runner/state.rs
2024-01-31 01:23:56 +01:00

116 lines
3.8 KiB
Rust

use std::collections::{HashMap, HashSet};
use enum_map::EnumMap;
use log::error;
use deckster_shared::path::{KeyPath, KeyPosition, KnobPath, KnobPosition};
use deckster_shared::state::{Key, Knob};
use crate::model;
use crate::runner::state;
#[derive(Debug)]
pub struct State {
pub active_key_page_id: String,
pub active_knob_page_id: String,
pub active_touch_ids: HashSet<u8>,
pub key_pages_by_id: HashMap<String, KeyPage>,
pub knob_pages_by_id: HashMap<String, KnobPage>,
}
impl State {
pub fn create(config: &model::config::Config) -> Self {
let key_pages_by_id: HashMap<_, _> = config
.key_pages_by_id
.iter()
.map(|(id, p)| state::KeyPage {
id: id.clone(),
keys_by_position: p
.keys
.iter()
.map(|(position, k)| Key {
path: KeyPath {
page_id: p.id.clone(),
position: *position,
},
base_style: k.base_style.clone(),
style: None,
})
.map(|k| (k.path.position, k))
.collect(),
})
.map(|p| (p.id.clone(), p))
.collect();
let knob_pages_by_id: HashMap<_, _> = config
.knob_pages_by_id
.iter()
.map(|(id, p)| KnobPage {
id: id.clone(),
knobs_by_position: EnumMap::from_fn(|position| {
let knob_config = &p.knobs[position];
Knob {
path: KnobPath {
page_id: p.id.clone(),
position,
},
base_style: knob_config.base_style.clone(),
style: None,
value: None,
}
}),
})
.map(|p| (p.id.clone(), p))
.collect();
State {
active_key_page_id: config.initial.key_page.clone(),
active_knob_page_id: config.initial.knob_page.clone(),
active_touch_ids: HashSet::new(),
key_pages_by_id,
knob_pages_by_id,
}
}
pub fn mutate_key_for_command<R>(&mut self, command_name: &'static str, path: &KeyPath, mutator: impl FnOnce(&mut Key) -> R) -> Option<R> {
match self.key_pages_by_id.get_mut(&path.page_id) {
None => error!("Received {} command with invalid path.page_id: {}", command_name, &path.page_id),
Some(key_page) => match key_page.keys_by_position.get_mut(&path.position) {
None => error!("Received {} command with invalid path.position: {}", command_name, &path.position),
Some(key) => return Some(mutator(key)),
},
}
None
}
pub fn mutate_knob_for_command<R>(&mut self, command_name: &'static str, path: &KnobPath, mutator: impl FnOnce(&mut Knob) -> R) -> Option<R> {
match self.knob_pages_by_id.get_mut(&path.page_id) {
None => error!("Received {} command with invalid path.page_id: {}", command_name, &path.page_id),
Some(knob_page) => return Some(mutator(&mut knob_page.knobs_by_position[path.position])),
}
None
}
pub fn active_key_page(&self) -> &KeyPage {
&self.key_pages_by_id[&self.active_key_page_id]
}
pub fn active_knob_page(&self) -> &KnobPage {
&self.knob_pages_by_id[&self.active_knob_page_id]
}
}
#[derive(Debug)]
pub struct KeyPage {
pub id: String,
pub keys_by_position: HashMap<KeyPosition, Key>,
}
#[derive(Debug)]
pub struct KnobPage {
pub id: String,
pub knobs_by_position: EnumMap<KnobPosition, Knob>,
}