mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
94 lines
2.7 KiB
Rust
94 lines
2.7 KiB
Rust
#![feature(associated_type_defaults)]
|
|
#![feature(if_let_guard)]
|
|
|
|
pub(crate) use tengri_core::*;
|
|
|
|
#[cfg(test)] mod input_test;
|
|
|
|
/// Event source
|
|
pub trait Input: Sized {
|
|
/// Type of input event
|
|
type Event;
|
|
/// Result of handling input
|
|
type Handled; // TODO: make this an Option<Box dyn Command<Self>> containing the undo
|
|
/// Currently handled event
|
|
fn event (&self) -> &Self::Event;
|
|
/// Whether component should exit
|
|
fn is_done (&self) -> bool;
|
|
/// Mark component as done
|
|
fn done (&self);
|
|
}
|
|
|
|
flex_trait_mut!(Handle <E: Input> {
|
|
fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> {
|
|
Ok(None)
|
|
}
|
|
});
|
|
|
|
pub trait Command<S>: Send + Sync + Sized {
|
|
fn execute (&self, state: &mut S) -> Perhaps<Self>;
|
|
fn delegate <T> (&self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T>
|
|
where Self: Sized
|
|
{
|
|
Ok(self.execute(state)?.map(wrap))
|
|
}
|
|
}
|
|
|
|
impl<S, T: Command<S>> Command<S> for Option<T> {
|
|
fn execute (&self, _: &mut S) -> Perhaps<Self> {
|
|
Ok(None)
|
|
}
|
|
fn delegate <U> (&self, _: &mut S, _: impl Fn(Self)->U) -> Perhaps<U>
|
|
where Self: Sized
|
|
{
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
/// Implement [Command] for given `State` and `handler`
|
|
#[macro_export] macro_rules! command {
|
|
($(<$($l:lifetime),+>)?|$self:ident:$Command:ty,$state:ident:$State:ty|$handler:expr) => {
|
|
impl$(<$($l),+>)? ::tengri::input::Command<$State> for $Command {
|
|
fn execute (&$self, $state: &mut $State) -> Perhaps<Self> {
|
|
Ok($handler)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export] macro_rules! def_command (($Command:ident: |$state:ident: $State:ty| {
|
|
$($Variant:ident$({$($arg:ident:$Arg:ty),+ $(,)?})?=>$body:expr),* $(,)?
|
|
})=>{
|
|
#[derive(Debug)]
|
|
pub enum $Command {
|
|
$($Variant $({ $($arg: $Arg),* })?),*
|
|
}
|
|
impl Command<$State> for $Command {
|
|
fn execute (&self, $state: &mut $State) -> Perhaps<Self> {
|
|
match self {
|
|
$(Self::$Variant $({ $($arg),* })? => $body,)*
|
|
_ => unimplemented!("Command<{}>: {self:?}", stringify!($State)),
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
/// Implement [Handle] for given `State` and `handler`.
|
|
#[macro_export] macro_rules! handle {
|
|
(|$self:ident:$State:ty,$input:ident|$handler:expr) => {
|
|
impl<E: Engine> ::tengri::input::Handle<E> for $State {
|
|
fn handle (&mut $self, $input: &E) -> Perhaps<E::Handled> {
|
|
$handler
|
|
}
|
|
}
|
|
};
|
|
($E:ty: |$self:ident:$State:ty,$input:ident|$handler:expr) => {
|
|
impl ::tengri::input::Handle<$E> for $State {
|
|
fn handle (&mut $self, $input: &$E) ->
|
|
Perhaps<<$E as ::tengri::input::Input>::Handled>
|
|
{
|
|
$handler
|
|
}
|
|
}
|
|
}
|
|
}
|