#![feature(anonymous_lifetime_in_impl_trait)] //#![feature(associated_type_defaults)] //#![feature(const_default)] //#![feature(const_option_ops)] #![feature(const_precise_live_drops)] #![feature(const_trait_impl)] //#![feature(impl_trait_in_assoc_type)] #![feature(step_trait)] //#![feature(trait_alias)] //#![feature(type_alias_impl_trait)] //#![feature(type_changing_struct_update)] pub extern crate atomic_float; pub extern crate palette; pub extern crate better_panic; pub extern crate unicode_width; #[cfg(feature = "sing")] pub extern crate jack; #[cfg(feature = "term")] pub extern crate ratatui; #[cfg(feature = "term")] pub extern crate crossterm; #[cfg(feature = "lang")] pub extern crate dizzle as lang; #[cfg(test)] #[macro_use] pub extern crate proptest; pub(crate) use ::{ atomic_float::AtomicF64, std::fmt::{Debug, Display}, std::ops::{Add, Sub, Mul, Div}, std::sync::{Arc, RwLock}, std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::*}, }; #[cfg(feature = "lang")] pub use ::dizzle::{Usually, Perhaps, impl_default}; /// DSL builtins. #[cfg(feature = "lang")] pub mod eval; /// Temporal dimension. #[cfg(feature = "time")] pub mod time; /// Circuit breaker for main loop. #[cfg(feature = "play")] pub mod exit; /// Thread management. #[cfg(feature = "play")] pub mod task; /// Integration with JACK audio backend. #[cfg(feature = "sing")] pub mod sing; /// Generic drawing utilities. #[cfg(feature = "draw")] pub mod draw; /// Spatial dimension. #[cfg(feature = "draw")] pub mod space; /// Color handling. #[cfg(feature = "draw")] pub mod color; /// Text handling. #[cfg(feature = "text")] pub mod text; /// Terminal output. #[cfg(feature = "term")] pub mod term; /// Terminal keyboard input. #[cfg(feature = "term")] pub mod keys; /// Define a trait an implement it for various mutation-enabled wrapper types. */ #[macro_export] macro_rules! flex_trait_mut ( ($Trait:ident $(<$($A:ident:$T:ident),+>)? { $(fn $fn:ident (&mut $self:ident $(, $arg:ident:$ty:ty)*) -> $ret:ty $body:block)* })=>{ pub trait $Trait $(<$($A: $T),+>)? { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret $body)* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for &mut _T_ { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { (*$self).$fn($($arg),*) })* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for Option<_T_> { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { if let Some(this) = $self { this.$fn($($arg),*) } else { Ok(None) } })* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Mutex<_T_> { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.get_mut().unwrap().$fn($($arg),*) })* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<::std::sync::Mutex<_T_>> { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.lock().unwrap().$fn($($arg),*) })* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::RwLock<_T_> { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.write().unwrap().$fn($($arg),*) })* } impl<$($($A: $T,)+)? _T_: $Trait $(<$($A),+>)?> $Trait $(<$($A),+>)? for ::std::sync::Arc<::std::sync::RwLock<_T_>> { $(fn $fn (&mut $self $(,$arg:$ty)*) -> $ret { $self.write().unwrap().$fn($($arg),*) })* } }; ); /// Define an enum containing commands, and implement [Command] trait for over given `State`. #[macro_export] macro_rules! def_command ( ($Command:ident: |$state:ident: $State:ty| { // FIXME: support attrs (docstrings) $($Variant:ident$({$($arg:ident:$Arg:ty),+ $(,)?})?=>$body:expr),* $(,)? })=>{ #[derive(Debug)] pub enum $Command { // FIXME: support attrs (docstrings) $($Variant $({ $($arg: $Arg),* })?),* } impl ::tengri::dizzle::Act<$State> for $Command { fn act (&self, $state: &mut $State) -> Perhaps { match self { $(Self::$Variant $({ $($arg),* })? => $body,)* _ => unimplemented!("Act<{}>: {self:?}", stringify!($State)), } } } }); /// Implement [Handle] for given `State` and `handler`. #[macro_export] macro_rules! impl_handle { //(|$self:ident:$State:ty,$input:ident|$handler:expr) => { //impl ::tengri::Handle for $State { //fn handle (&mut $self, $input: &E) -> Perhaps { //$handler //} //} //}; ($E:ty: |$self:ident:$State:ty,$input:ident|$handler:expr) => { //impl ::tengri::Handle<$E> for $State { //fn handle (&mut $self, $input: &$E) -> //Perhaps<<$E as ::tengri::Input>::Handled> //{ //$handler //} //} } }