generalize some of the command logic

This commit is contained in:
🪞👃🪞 2025-01-05 10:34:31 +01:00
parent 905486edbd
commit 1a9077427c
5 changed files with 48 additions and 48 deletions

View file

@ -1 +0,0 @@
use crate::*;

View file

@ -1,6 +1,8 @@
use crate::*; use crate::*;
mod handle; pub use self::handle::*; mod handle; pub use self::handle::*;
mod command; pub use self::command::*;
mod event_map; pub use self::event_map::*;
/// Current input state /// Current input state
pub trait Input<E: Engine> { pub trait Input<E: Engine> {

View file

@ -1,46 +1,4 @@
use crate::*; use crate::*;
#[macro_export] macro_rules! keymap {
(
$(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty
{ $($key:expr => $handler:expr),* $(,)? } $(,)?
) => {
pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap {
fallback: None,
bindings: &[ $(($key, &|$state|Some($handler)),)* ]
};
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
};
(
$(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty
{ $($key:expr => $handler:expr),* $(,)? }, $default:expr
) => {
pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap {
fallback: Some(&|$state, $input|Some($default)),
bindings: &[ $(($key, &|$state|Some($handler)),)* ]
};
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
};
}
pub struct EventMap<'a, S, I: PartialEq, C> {
pub bindings: &'a [(I, &'a dyn Fn(&S) -> Option<C>)],
pub fallback: Option<&'a dyn Fn(&S, &I) -> Option<C>>
}
impl<'a, S, I: PartialEq, C> EventMap<'a, S, I, C> {
pub fn handle (&self, state: &S, input: &I) -> Option<C> {
for (binding, handler) in self.bindings.iter() {
if input == binding {
return handler(state)
}
}
if let Some(fallback) = self.fallback {
fallback(state, input)
} else {
None
}
}
}
pub trait Command<S>: Send + Sync + Sized { pub trait Command<S>: Send + Sync + Sized {
fn execute (self, state: &mut S) -> Perhaps<Self>; fn execute (self, state: &mut S) -> Perhaps<Self>;
fn delegate <T> (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T> { fn delegate <T> (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T> {

View file

@ -0,0 +1,43 @@
use crate::*;
pub struct EventMap<'a, S, I: PartialEq, C> {
pub bindings: &'a [(I, &'a dyn Fn(&S) -> Option<C>)],
pub fallback: Option<&'a dyn Fn(&S, &I) -> Option<C>>
}
impl<'a, S, I: PartialEq, C> EventMap<'a, S, I, C> {
pub fn handle (&self, state: &S, input: &I) -> Option<C> {
for (binding, handler) in self.bindings.iter() {
if input == binding {
return handler(state)
}
}
if let Some(fallback) = self.fallback {
fallback(state, input)
} else {
None
}
}
}
#[macro_export] macro_rules! keymap {
(
$(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty
{ $($key:expr => $handler:expr),* $(,)? } $(,)?
) => {
pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap {
fallback: None,
bindings: &[ $(($key, &|$state|Some($handler)),)* ]
};
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
};
(
$(<$lt:lifetime>)? $KEYS:ident = |$state:ident: $State:ty, $input:ident: $Input:ty| $Command:ty
{ $($key:expr => $handler:expr),* $(,)? }, $default:expr
) => {
pub const $KEYS: EventMap<'static, $State, $Input, $Command> = EventMap {
fallback: Some(&|$state, $input|Some($default)),
bindings: &[ $(($key, &|$state|Some($handler)),)* ]
};
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
};
}

View file

@ -12,10 +12,9 @@ pub(crate) use ::tek_layout::{
*, *,
tek_engine::{ tek_engine::{
Usually, Perhaps, Usually, Perhaps,
Engine, Size, Area, Output, Content, Render, Thunk, render, Engine, Size, Area,
Output, Content, Render, Thunk, render, Input, handle, Handle, command, Command, input_to_command, InputToCommand,
Input, Handle, handle, keymap, kexp, kpat, EventMap,
kexp, kpat,
tui::{ tui::{
Tui, Tui,
TuiIn, key, ctrl, shift, alt, TuiIn, key, ctrl, shift, alt,
@ -57,7 +56,6 @@ pub mod arranger; pub use self::arranger::*;
pub mod border; pub use self::border::*; pub mod border; pub use self::border::*;
pub mod clock; pub use self::clock::*; pub mod clock; pub use self::clock::*;
pub mod color; pub use self::color::*; pub mod color; pub use self::color::*;
pub mod command; pub use self::command::*;
pub mod field; pub use self::field::*; pub mod field; pub use self::field::*;
pub mod file; pub use self::file::*; pub mod file; pub use self::file::*;
pub mod focus; pub use self::focus::*; pub mod focus; pub use self::focus::*;