116 lines
3.8 KiB
Rust
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>,
|
|
}
|