more shuffling; testing dispatch

This commit is contained in:
i do not exist 2026-10-05 02:26:01 +03:00
parent 56df5c5b78
commit 02dc7bc9f8
12 changed files with 1339 additions and 1359 deletions

View file

@ -2,112 +2,6 @@ use crate::*;
impl_as_mut!(Mode: |self: Mode| self);
/// Has a stack of currently active interaction modes.
pub trait HasModeStack {
/// Stack of active modes.
fn mode_stack (&self) -> &RwLock<Vec<Arc<str>>>;
}
impl HasModeStack for App {
fn mode_stack (&self) -> &RwLock<Vec<Arc<str>>> {
&self.modes
}
}
pub trait HasModes {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>>;
/// Register a mode.
///
/// ```
/// # use ::{std::sync::Arc, tek::*};
/// let config: Config = Default::default();
///
/// config.modes_add(stringify!(Menu
/// (name Menu)
/// (info Mode selector.)
/// (axis Y Prev Next)
/// (bind Confirm)
/// (view (bg (g 30) (bar/s 7 Logo (full/xy Dialog))))
/// )).unwrap();
///
/// let _: Arc<Mode> = config.modes_get("Menu").unwrap();
/// ```
fn modes_add <'a> (&self, expr: impl Language) -> UsuallyRef<'a, ()> {
let name = expr.head()?.ok_or("mode: missing name")?;
let body = expr.tail()?.ok_or("mode: missing body")?;
let mut mode = Mode::default();
body.each(&mut mode, |c, s|c.add(s))?;
self.modes().write().insert(name.into(), Arc::new(mode));
Ok(())
}
/// Get a mode by name.
fn modes_get (&self, name: impl AsRef<str>) -> Option<Arc<Mode>> {
self.modes().read().get(name.as_ref()).cloned()
}
/// Run something for each mode.
fn modes_for_each <T> (&self, mut ator: impl FnMut(&str, &Mode)->T) {
for (k, v) in self.modes().read().iter() {
let _ = ator(k.as_ref(), v.as_ref());
}
}
/// Count modes.
fn modes_count (&self) -> usize {
self.modes().read().len()
}
/// Clear modes.
fn modes_clear (&self) {
*self.modes().write() = Default::default();
}
}
impl HasModes for App {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>> {
&self.config.config.modes.0
}
}
impl HasModes for ConfigWatcher {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>> {
&self.config.modes.0
}
}
impl HasModes for Config {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>> {
&self.modes.0
}
}
impl HasModes for Modes {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>> {
&self.0
}
}
impl HasModes for Mode {
fn modes (&self) -> &RwLock<BTreeMap<Arc<str>, Arc<Mode>>> {
&self.modes.0
}
}
/// Collection of UI modes.
///
/// ```
/// # use tek::*;
/// // Empty mode registry:
/// let mut state = Modes::default();
/// assert_eq!(state.modes_count(), 0);
/// assert!(state.modes_get("Foo").is_none());
///
/// // Add a mode:
/// let _ = state.modes_add(&"Foo (name Foo) (info Bar)").unwrap();
/// assert_eq!(state.modes_count(), 1);
/// assert!(state.modes_get("Foo").is_some());
/// ```
#[derive(Default, Debug, Clone)]
pub struct Modes(pub Arc<RwLock<BTreeMap<Arc<str>, Arc<Mode>>>>);
/// Group of view and keys definitions.
///
/// ```
@ -120,12 +14,11 @@ pub struct Mode {
pub info: Vec<Arc<str>>,
pub view: Vec<Arc<View<Tui, App>>>,
pub keys: Vec<Arc<str>>,
pub axis: BTreeMap<Arc<str>, (Arc<str>, Arc<str>)>,
pub modes: Modes,
pub axis: BTreeMap<Arc<str>, Arc<str>>,
pub modes: Arc<RwLock<BTreeMap<Arc<str>, Arc<Mode>>>>,
}
impl Mode {
/// Add a definition to the mode.
///
/// Supported definitions:
@ -164,8 +57,7 @@ impl Mode {
let body = tail.tail()?.ok_or("submode: missing body")?;
let mut submode = Mode::default();
body.each(&mut submode, |c, s|c.add(s))?;
let modes = self.modes.clone();
modes.0.write().insert(name.into(), Arc::new(submode));
self.modes.write().insert(name.into(), Arc::new(submode));
Ok(self)
}
@ -177,27 +69,22 @@ impl Mode {
}
fn add_axis (&mut self, tail: &str) -> Usually<&mut Self> {
let mut axis: Option<Arc<str>> = None;
let mut dec: Option<Arc<str>> = None;
let mut inc: Option<Arc<str>> = None;
let mut axis: Option<Arc<str>> = None;
let mut param: Option<Arc<str>> = None;
tail.each(0, |index: usize, src: &str|if index == 0 {
axis = Some(src.into());
Ok(1)
} else if index == 1 {
dec = Some(src.into());
param = Some(src.into());
Ok(2)
} else if index == 2 {
inc = Some(src.into());
Ok(3)
} else {
err!("expected (mode (axis [Name] [command] [command])), got: {tail}")
})?;
if let Some(axis) = axis && let Some(dec) = dec && let Some(inc) = inc {
self.keys.push(format!("((dec {axis}) {dec})").into());
self.keys.push(format!("((inc {axis}) {inc})").into());
if let Some(axis) = axis && let Some(param) = param {
self.axis.insert(axis.into(), param.into());
Ok(self)
} else {
err!("expected (mode (axis X Decrement Increment)), got: {tail}")
err!("mode: expected (axis X Param), got: {tail}")
}
}