mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-01-31 10:56:41 +01:00
Compare commits
2 commits
a933cbe285
...
8a5bc7b6ea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a5bc7b6ea | ||
|
|
d06e1c41f8 |
5 changed files with 91 additions and 59 deletions
|
|
@ -19,6 +19,37 @@ pub trait Input: Sized {
|
||||||
fn done (&self);
|
fn done (&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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),*) })*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
flex_trait_mut!(Handle <E: Input> {
|
flex_trait_mut!(Handle <E: Input> {
|
||||||
fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> {
|
fn handle (&mut self, _input: &E) -> Perhaps<E::Handled> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use ::dizzle::{Dsl, DslExpr, DslWord, DslNs};
|
use ::dizzle::{Language, Expression, Symbol, Namespace};
|
||||||
|
|
||||||
pub trait View<O, U> {
|
pub trait View<O, U> {
|
||||||
fn view_expr <'a> (&'a self, output: &mut O, expr: &'a impl DslExpr) -> Usually<U> {
|
fn view_expr <'a> (&'a self, _output: &mut O, expr: &'a impl Expression) -> Usually<U> {
|
||||||
Err(format!("View::view_expr: no exprs defined: {expr:?}").into())
|
Err(format!("View::view_expr: no exprs defined: {expr:?}").into())
|
||||||
}
|
}
|
||||||
fn view_word <'a> (&'a self, output: &mut O, word: &'a impl DslWord) -> Usually<U> {
|
fn view_word <'a> (&'a self, _output: &mut O, word: &'a impl Symbol) -> Usually<U> {
|
||||||
Err(format!("View::view_word: no words defined: {word:?}").into())
|
Err(format!("View::view_word: no words defined: {word:?}").into())
|
||||||
}
|
}
|
||||||
fn view <'a> (&'a self, output: &mut O, dsl: &'a impl Dsl) -> Usually<U> {
|
fn view <'a> (&'a self, output: &mut O, dsl: &'a impl Language) -> Usually<U> {
|
||||||
if let Ok(Some(expr)) = dsl.expr() {
|
if let Ok(Some(expr)) = dsl.expr() {
|
||||||
self.view_expr(output, &expr)
|
self.view_expr(output, &expr)
|
||||||
} else if let Ok(Some(word)) = dsl.word() {
|
} else if let Ok(Some(word)) = dsl.word() {
|
||||||
self.view_word(output, &word)
|
self.view_word(output, &word)
|
||||||
} else {
|
} else {
|
||||||
panic!("{dsl:?}: invalid")
|
Err(format!("{dsl:?}: invalid").into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
state: &S, output: &mut O, expr: &'a impl DslExpr
|
state: &S, output: &mut O, expr: &'a impl Expression
|
||||||
) -> Usually<bool> where
|
) -> Usually<bool> where
|
||||||
S: View<O, ()>
|
S: View<O, ()>
|
||||||
+ for<'b>DslNs<'b, bool>
|
+ for<'b>Namespace<'b, bool>
|
||||||
+ for<'b>DslNs<'b, O::Unit>
|
+ for<'b>Namespace<'b, O::Unit>
|
||||||
{
|
{
|
||||||
// First element of expression is used for dispatch.
|
// First element of expression is used for dispatch.
|
||||||
// Dispatch is proto-namespaced using separator character
|
// Dispatch is proto-namespaced using separator character
|
||||||
|
|
@ -43,12 +43,12 @@ pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
match frags.next() {
|
match frags.next() {
|
||||||
|
|
||||||
Some("when") => output.place(&When::new(
|
Some("when") => output.place(&When::new(
|
||||||
state.from(arg0?)?.unwrap(),
|
state.resolve(arg0?)?.unwrap(),
|
||||||
Thunk::new(move|output: &mut O|state.view(output, &arg1).unwrap())
|
Thunk::new(move|output: &mut O|state.view(output, &arg1).unwrap())
|
||||||
)),
|
)),
|
||||||
|
|
||||||
Some("either") => output.place(&Either::new(
|
Some("either") => output.place(&Either::new(
|
||||||
state.from(arg0?)?.unwrap(),
|
state.resolve(arg0?)?.unwrap(),
|
||||||
Thunk::new(move|output: &mut O|state.view(output, &arg1).unwrap()),
|
Thunk::new(move|output: &mut O|state.view(output, &arg1).unwrap()),
|
||||||
Thunk::new(move|output: &mut O|state.view(output, &arg2).unwrap())
|
Thunk::new(move|output: &mut O|state.view(output, &arg2).unwrap())
|
||||||
)),
|
)),
|
||||||
|
|
@ -96,9 +96,9 @@ pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
||||||
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
||||||
match axis {
|
match axis {
|
||||||
Some("xy") | None => Fixed::XY(state.from(arg0?)?.unwrap(), state.from(arg1?)?.unwrap(), cb),
|
Some("xy") | None => Fixed::XY(state.resolve(arg0?)?.unwrap(), state.resolve(arg1?)?.unwrap(), cb),
|
||||||
Some("x") => Fixed::X(state.from(arg0?)?.unwrap(), cb),
|
Some("x") => Fixed::X(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
Some("y") => Fixed::Y(state.from(arg0?)?.unwrap(), cb),
|
Some("y") => Fixed::Y(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
frag => unimplemented!("fixed/{frag:?} ({expr:?}) ({head:?}) ({:?})",
|
frag => unimplemented!("fixed/{frag:?} ({expr:?}) ({head:?}) ({:?})",
|
||||||
head.src()?.unwrap_or_default().split("/").next())
|
head.src()?.unwrap_or_default().split("/").next())
|
||||||
}
|
}
|
||||||
|
|
@ -109,9 +109,9 @@ pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
||||||
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
||||||
match axis {
|
match axis {
|
||||||
Some("xy") | None => Min::XY(state.from(arg0?)?.unwrap(), state.from(arg1?)?.unwrap(), cb),
|
Some("xy") | None => Min::XY(state.resolve(arg0?)?.unwrap(), state.resolve(arg1?)?.unwrap(), cb),
|
||||||
Some("x") => Min::X(state.from(arg0?)?.unwrap(), cb),
|
Some("x") => Min::X(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
Some("y") => Min::Y(state.from(arg0?)?.unwrap(), cb),
|
Some("y") => Min::Y(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
frag => unimplemented!("min/{frag:?}")
|
frag => unimplemented!("min/{frag:?}")
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -121,9 +121,9 @@ pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
||||||
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
||||||
match axis {
|
match axis {
|
||||||
Some("xy") | None => Max::XY(state.from(arg0?)?.unwrap(), state.from(arg1?)?.unwrap(), cb),
|
Some("xy") | None => Max::XY(state.resolve(arg0?)?.unwrap(), state.resolve(arg1?)?.unwrap(), cb),
|
||||||
Some("x") => Max::X(state.from(arg0?)?.unwrap(), cb),
|
Some("x") => Max::X(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
Some("y") => Max::Y(state.from(arg0?)?.unwrap(), cb),
|
Some("y") => Max::Y(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
frag => unimplemented!("max/{frag:?}")
|
frag => unimplemented!("max/{frag:?}")
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -133,9 +133,9 @@ pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
let arg = match axis { Some("x") | Some("y") => arg1, Some("xy") | None => arg2, _ => panic!("fixed: unsupported axis {axis:?}") };
|
||||||
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
let cb = Thunk::new(move|output: &mut O|state.view(output, &arg).unwrap());
|
||||||
match axis {
|
match axis {
|
||||||
Some("xy") | None => Push::XY(state.from(arg0?)?.unwrap(), state.from(arg1?)?.unwrap(), cb),
|
Some("xy") | None => Push::XY(state.resolve(arg0?)?.unwrap(), state.resolve(arg1?)?.unwrap(), cb),
|
||||||
Some("x") => Push::X(state.from(arg0?)?.unwrap(), cb),
|
Some("x") => Push::X(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
Some("y") => Push::Y(state.from(arg0?)?.unwrap(), cb),
|
Some("y") => Push::Y(state.resolve(arg0?)?.unwrap(), cb),
|
||||||
frag => unimplemented!("push/{frag:?}")
|
frag => unimplemented!("push/{frag:?}")
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ impl<T: TuiWidget + Send + Sync + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
||||||
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
fn run (&self, state: &Arc<RwLock<T>>) -> Usually<()> {
|
||||||
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
let _input_thread = TuiIn::run_input(self, state, Duration::from_millis(100));
|
||||||
self.write().unwrap().setup()?;
|
self.write().unwrap().setup()?;
|
||||||
let render_thread = TuiOut::run_output(self, state, Duration::from_millis(10));
|
let render_thread = TuiOut::run_output(self, state, Duration::from_millis(10))?;
|
||||||
match render_thread.join() {
|
match render_thread.join() {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
self.write().unwrap().teardown()?;
|
self.write().unwrap().teardown()?;
|
||||||
|
|
@ -96,7 +96,7 @@ impl<T: TuiWidget + Send + Sync + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
||||||
},
|
},
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
self.write().unwrap().teardown()?;
|
self.write().unwrap().teardown()?;
|
||||||
panic!("\n\rDraw thread failed: {error:?}.\n\r")
|
panic!("\n\rDraw thread failed: error={error:?}.\n\r")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -105,22 +105,22 @@ impl<T: TuiWidget + Send + Sync + 'static> TuiRun<T> for Arc<RwLock<Tui>> {
|
||||||
|
|
||||||
#[cfg(feature = "dsl")]
|
#[cfg(feature = "dsl")]
|
||||||
pub fn evaluate_output_expression_tui <'a, S> (
|
pub fn evaluate_output_expression_tui <'a, S> (
|
||||||
state: &S, mut output: &mut TuiOut, expr: impl DslExpr + 'a
|
state: &S, output: &mut TuiOut, expr: impl Expression + 'a
|
||||||
) -> Usually<bool> where
|
) -> Usually<bool> where
|
||||||
S: View<TuiOut, ()>
|
S: View<TuiOut, ()>
|
||||||
+ for<'b>DslNs<'b, bool>
|
+ for<'b>Namespace<'b, bool>
|
||||||
+ for<'b>DslNs<'b, u16>
|
+ for<'b>Namespace<'b, u16>
|
||||||
+ for<'b>DslNs<'b, Color>
|
+ for<'b>Namespace<'b, Color>
|
||||||
{
|
{
|
||||||
// See `tengri_output::evaluate_output_expression`
|
// See `tengri_output::evaluate_output_expression`
|
||||||
let head = expr.head()?;
|
let head = expr.head()?;
|
||||||
let mut frags = head.src()?.unwrap_or_default().split("/");
|
let mut frags = head.src()?.unwrap_or_default().split("/");
|
||||||
let args = expr.tail();
|
let args = expr.tail();
|
||||||
let arg0 = args.head();
|
let arg0 = args.head();
|
||||||
let tail0 = args.tail();
|
let tail0 = args.tail();
|
||||||
let arg1 = tail0.head();
|
let arg1 = tail0.head();
|
||||||
let tail1 = tail0.tail();
|
let tail1 = tail0.tail();
|
||||||
let arg2 = tail1.head();
|
let _arg2 = tail1.head();
|
||||||
match frags.next() {
|
match frags.next() {
|
||||||
|
|
||||||
Some("text") => if let Some(src) = args?.src()? { output.place(&src) },
|
Some("text") => if let Some(src) = args?.src()? { output.place(&src) },
|
||||||
|
|
@ -128,7 +128,7 @@ pub fn evaluate_output_expression_tui <'a, S> (
|
||||||
Some("fg") => {
|
Some("fg") => {
|
||||||
let arg0 = arg0?.expect("fg: expected arg 0 (color)");
|
let arg0 = arg0?.expect("fg: expected arg 0 (color)");
|
||||||
output.place(&Tui::fg(
|
output.place(&Tui::fg(
|
||||||
DslNs::<Color>::from(state, arg0)?.unwrap_or_else(||panic!("fg: {arg0:?}: not a color")),
|
Namespace::<Color>::resolve(state, arg0)?.unwrap_or_else(||panic!("fg: {arg0:?}: not a color")),
|
||||||
Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()),
|
Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
|
@ -136,7 +136,7 @@ pub fn evaluate_output_expression_tui <'a, S> (
|
||||||
Some("bg") => {
|
Some("bg") => {
|
||||||
let arg0 = arg0?.expect("bg: expected arg 0 (color)");
|
let arg0 = arg0?.expect("bg: expected arg 0 (color)");
|
||||||
output.place(&Tui::bg(
|
output.place(&Tui::bg(
|
||||||
DslNs::<Color>::from(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color")),
|
Namespace::<Color>::resolve(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color")),
|
||||||
Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()),
|
Thunk::new(move|output: &mut TuiOut|state.view(output, &arg1).unwrap()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ impl TuiEvent {
|
||||||
Self(event)
|
Self(event)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "dsl")]
|
#[cfg(feature = "dsl")]
|
||||||
pub fn from_dsl (dsl: impl Dsl) -> Perhaps<Self> {
|
pub fn from_dsl (dsl: impl Language) -> Perhaps<Self> {
|
||||||
Ok(TuiKey::from_dsl(dsl)?.to_crossterm().map(Self))
|
Ok(TuiKey::from_dsl(dsl)?.to_crossterm().map(Self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ pub struct TuiKey(Option<KeyCode>, KeyModifiers);
|
||||||
impl TuiKey {
|
impl TuiKey {
|
||||||
const SPLIT: char = '/';
|
const SPLIT: char = '/';
|
||||||
#[cfg(feature = "dsl")]
|
#[cfg(feature = "dsl")]
|
||||||
pub fn from_dsl (dsl: impl Dsl) -> Usually<Self> {
|
pub fn from_dsl (dsl: impl Language) -> Usually<Self> {
|
||||||
if let Some(word) = dsl.word()? {
|
if let Some(word) = dsl.word()? {
|
||||||
let word = word.trim();
|
let word = word.trim();
|
||||||
Ok(if word == ":char" {
|
Ok(if word == ":char" {
|
||||||
|
|
|
||||||
|
|
@ -33,35 +33,36 @@ impl TuiOut {
|
||||||
engine: &Arc<RwLock<Tui>>,
|
engine: &Arc<RwLock<Tui>>,
|
||||||
state: &Arc<RwLock<T>>,
|
state: &Arc<RwLock<T>>,
|
||||||
timer: Duration
|
timer: Duration
|
||||||
) -> JoinHandle<()> {
|
) -> Result<JoinHandle<()>, std::io::Error> {
|
||||||
let exited = engine.read().unwrap().exited.clone();
|
let exited = engine.read().unwrap().exited.clone();
|
||||||
let engine = engine.clone();
|
let engine = engine.clone();
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
let Size { width, height } = engine.read().unwrap().backend.size().expect("get size failed");
|
let Size { width, height } = engine.read().unwrap().backend.size().expect("get size failed");
|
||||||
let mut buffer = Buffer::empty(Rect { x: 0, y: 0, width, height });
|
let mut buffer = Buffer::empty(Rect { x: 0, y: 0, width, height });
|
||||||
spawn(move || loop {
|
std::thread::Builder::new()
|
||||||
if exited.fetch_and(true, Relaxed) {
|
.name("tui output thread".into())
|
||||||
break
|
.spawn(move || loop {
|
||||||
}
|
if exited.fetch_and(true, Relaxed) {
|
||||||
//let t0 = engine.read().unwrap().perf.get_t0();
|
break
|
||||||
let Size { width, height } = engine.read().unwrap().backend.size()
|
|
||||||
.expect("get size failed");
|
|
||||||
if let Ok(state) = state.try_read() {
|
|
||||||
let size = Rect { x: 0, y: 0, width, height };
|
|
||||||
if buffer.area != size {
|
|
||||||
engine.write().unwrap().backend.clear_region(ClearType::All)
|
|
||||||
.expect("clear failed");
|
|
||||||
buffer.resize(size);
|
|
||||||
buffer.reset();
|
|
||||||
}
|
}
|
||||||
let mut output = TuiOut { buffer, area: [0, 0, width, height] };
|
let t0 = engine.read().unwrap().perf.get_t0();
|
||||||
state.draw(&mut output);
|
let Size { width, height } = engine.read().unwrap().backend.size()
|
||||||
buffer = engine.write().unwrap().flip(output.buffer, size);
|
.expect("get size failed");
|
||||||
}
|
if let Ok(state) = state.try_read() {
|
||||||
//let t1 = engine.read().unwrap().perf.get_t1(t0).unwrap();
|
let size = Rect { x: 0, y: 0, width, height };
|
||||||
//buffer.set_string(0, 0, &format!("{:>3}.{:>3}ms", t1.as_millis(), t1.as_micros() % 1000), Style::default());
|
if buffer.area != size {
|
||||||
std::thread::sleep(timer);
|
engine.write().unwrap().backend.clear_region(ClearType::All).expect("clear failed");
|
||||||
})
|
buffer.resize(size);
|
||||||
|
buffer.reset();
|
||||||
|
}
|
||||||
|
let mut output = TuiOut { buffer, area: [0, 0, width, height] };
|
||||||
|
state.draw(&mut output);
|
||||||
|
buffer = engine.write().unwrap().flip(output.buffer, size);
|
||||||
|
}
|
||||||
|
let t1 = engine.read().unwrap().perf.get_t1(t0).unwrap();
|
||||||
|
buffer.set_string(0, 0, &format!("{:>3}.{:>3}ms", t1.as_millis(), t1.as_micros() % 1000), Style::default());
|
||||||
|
std::thread::sleep(timer);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_rect (&mut self, area: [u16;4]) -> &mut Self {
|
pub fn with_rect (&mut self, area: [u16;4]) -> &mut Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue