mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
refactor engine and layout into input and output
This commit is contained in:
parent
f052891473
commit
4d0f98acd2
40 changed files with 104 additions and 109 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -1432,19 +1432,17 @@ dependencies = [
|
||||||
"clojure-reader",
|
"clojure-reader",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"konst",
|
"konst",
|
||||||
"tek_layout",
|
"tek_input",
|
||||||
|
"tek_output",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tek_engine"
|
name = "tek_input"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tek_layout"
|
name = "tek_output"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
|
||||||
"tek_engine",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tek_tui"
|
name = "tek_tui"
|
||||||
|
|
@ -1456,8 +1454,8 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"tek_edn",
|
"tek_edn",
|
||||||
"tek_engine",
|
"tek_input",
|
||||||
"tek_layout",
|
"tek_output",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,10 @@ wavers = "1.4.3"
|
||||||
#winit = { version = "0.30.4", features = [ "x11" ] }
|
#winit = { version = "0.30.4", features = [ "x11" ] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["edn"]
|
default = ["tek_input", "tek_output", "tek_edn"]
|
||||||
edn = ["tek_tui/edn"]
|
tek_input = [ "tek_tui/tek_input" ]
|
||||||
|
tek_output = [ "tek_tui/tek_output" ]
|
||||||
|
tek_edn = [ "tek_tui/tek_edn" ]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tek_arranger"
|
name = "tek_arranger"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
#[allow(unused_imports)] use tek::{
|
#[allow(unused_imports)] use tek::{
|
||||||
*,
|
*,
|
||||||
jack::*,
|
jack::*,
|
||||||
tek_layout::Measure,
|
tek_input::*,
|
||||||
tek_engine::Usually,
|
tek_output::*,
|
||||||
tek_tui::{Tui, TuiRun, ItemPalette, ItemColor, ratatui::prelude::Color}
|
tek_tui::{Tui, TuiRun, ItemPalette, ItemColor, ratatui::prelude::Color}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@ version = "0.1.0"
|
||||||
clojure-reader = "0.3.0"
|
clojure-reader = "0.3.0"
|
||||||
konst = "0.3.16"
|
konst = "0.3.16"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
tek_layout = { optional = true, path = "../layout" }
|
|
||||||
|
tek_input = { optional = true, path = "../input" }
|
||||||
|
tek_output = { optional = true, path = "../output" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["layout"]
|
default = ["tek_input", "tek_output"]
|
||||||
layout = [ "tek_layout" ]
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tek_tui = { path = "../tui" }
|
tek_tui = { path = "../tui" }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use ::tek_layout::{*, tek_engine::{Usually, Content, Render, RenderBox, Output, Thunk}};
|
use ::tek_output::*;
|
||||||
use EdnItem::*;
|
use EdnItem::*;
|
||||||
|
|
||||||
pub type EdnCallback<'a, Output, State> =
|
pub type EdnCallback<'a, Output, State> =
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
pub(crate) use std::{
|
pub(crate) use std::{
|
||||||
fmt::{Debug, Formatter, Error as FormatError}
|
fmt::{Debug, Formatter, Error as FormatError}
|
||||||
};
|
};
|
||||||
pub use ::tek_layout;
|
pub use ::tek_output;
|
||||||
|
|
||||||
mod edn_error; pub use self::edn_error::*;
|
mod edn_error; pub use self::edn_error::*;
|
||||||
mod edn_item; pub use self::edn_item::*;
|
mod edn_item; pub use self::edn_item::*;
|
||||||
|
|
@ -12,6 +12,9 @@ mod edn_iter; pub use self::edn_iter::*;
|
||||||
mod edn_token; pub use self::edn_token::*;
|
mod edn_token; pub use self::edn_token::*;
|
||||||
mod edn_view; pub use self::edn_view::*;
|
mod edn_view; pub use self::edn_view::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "tek_output")]
|
||||||
|
pub(crate) use ::tek_output::*;
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_edn () -> Result<(), ParseError> {
|
#[cfg(test)] #[test] fn test_edn () -> Result<(), ParseError> {
|
||||||
use EdnItem::*;
|
use EdnItem::*;
|
||||||
assert_eq!(EdnItem::<String>::read_all("")?,
|
assert_eq!(EdnItem::<String>::read_all("")?,
|
||||||
|
|
|
||||||
0
engine/Cargo.lock → input/Cargo.lock
generated
0
engine/Cargo.lock → input/Cargo.lock
generated
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tek_engine"
|
name = "tek_input"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
||||||
15
input/src/engine.rs
Normal file
15
input/src/engine.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
/// Event source
|
||||||
|
pub trait Input: Send + Sync + Sized {
|
||||||
|
/// Type of input event
|
||||||
|
type Event;
|
||||||
|
/// Result of handling input
|
||||||
|
type Handled;
|
||||||
|
/// Currently handled event
|
||||||
|
fn event (&self) -> &Self::Event;
|
||||||
|
/// Whether component should exit
|
||||||
|
fn is_done (&self) -> bool;
|
||||||
|
/// Mark component as done
|
||||||
|
fn done (&self);
|
||||||
|
}
|
||||||
|
|
@ -5,30 +5,15 @@ mod engine; pub use self::engine::*;
|
||||||
mod handle; pub use self::handle::*;
|
mod handle; pub use self::handle::*;
|
||||||
mod command; pub use self::command::*;
|
mod command; pub use self::command::*;
|
||||||
mod event_map; pub use self::event_map::*;
|
mod event_map; pub use self::event_map::*;
|
||||||
mod coordinate; pub use self::coordinate::*;
|
|
||||||
mod size; pub use self::size::*;
|
|
||||||
mod area; pub use self::area::*;
|
|
||||||
mod render; pub use self::render::*;
|
|
||||||
mod content; pub use self::content::*;
|
|
||||||
mod thunk; pub use self::thunk::*;
|
|
||||||
|
|
||||||
pub use std::error::Error;
|
pub(crate) use std::marker::PhantomData;
|
||||||
|
pub(crate) use std::error::Error;
|
||||||
|
|
||||||
/// Standard result type.
|
/// Standard result type.
|
||||||
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
/// Standard optional result type.
|
/// Standard optional result type.
|
||||||
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
|
|
||||||
/// Prototypal case of implementor macro.
|
|
||||||
/// Saves 4loc per data pats.
|
|
||||||
#[macro_export] macro_rules! from {
|
|
||||||
($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => {
|
|
||||||
impl $(<$($lt),+>)? From<$Source> for $Target {
|
|
||||||
fn from ($state:$Source) -> Self { $cb }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_dimensions () {
|
#[cfg(test)] #[test] fn test_dimensions () {
|
||||||
assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]);
|
assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]);
|
||||||
0
layout/Cargo.lock → output/Cargo.lock
generated
0
layout/Cargo.lock → output/Cargo.lock
generated
|
|
@ -1,10 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tek_layout"
|
name = "tek_output"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tek_engine = { path = "../engine" }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tek_tui = { path = "../tui" }
|
tek_tui = { path = "../tui" }
|
||||||
|
tek_engine = { path = "../engine" }
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(impl_trait_in_assoc_type)]
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
|
mod coordinate; pub use self::coordinate::*;
|
||||||
|
mod size; pub use self::size::*;
|
||||||
|
mod area; pub use self::area::*;
|
||||||
|
|
||||||
|
mod output; pub use self::output::*;
|
||||||
|
mod content; pub use self::content::*;
|
||||||
|
mod render; pub use self::render::*;
|
||||||
|
mod thunk; pub use self::thunk::*;
|
||||||
|
|
||||||
mod when; pub use self::when::*;
|
mod when; pub use self::when::*;
|
||||||
mod either; pub use self::either::*;
|
mod either; pub use self::either::*;
|
||||||
mod map; pub use self::map::*;
|
mod map; pub use self::map::*;
|
||||||
|
|
@ -12,9 +21,24 @@ mod measure; pub use self::measure::*;
|
||||||
mod transform_xy; pub use self::transform_xy::*;
|
mod transform_xy; pub use self::transform_xy::*;
|
||||||
mod transform_xy_unit; pub use self::transform_xy_unit::*;
|
mod transform_xy_unit; pub use self::transform_xy_unit::*;
|
||||||
|
|
||||||
pub use ::tek_engine;
|
|
||||||
pub(crate) use ::tek_engine::*;
|
|
||||||
pub(crate) use std::marker::PhantomData;
|
pub(crate) use std::marker::PhantomData;
|
||||||
|
pub(crate) use std::error::Error;
|
||||||
|
|
||||||
|
/// Standard result type.
|
||||||
|
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
|
/// Standard optional result type.
|
||||||
|
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
|
|
||||||
|
/// Prototypal case of implementor macro.
|
||||||
|
/// Saves 4loc per data pats.
|
||||||
|
#[macro_export] macro_rules! from {
|
||||||
|
($(<$($lt:lifetime),+>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => {
|
||||||
|
impl $(<$($lt),+>)? From<$Source> for $Target {
|
||||||
|
fn from ($state:$Source) -> Self { $cb }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
|
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
|
||||||
use ::tek_tui::Tui;
|
use ::tek_tui::Tui;
|
||||||
|
|
@ -1,33 +1,5 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Platform backend.
|
|
||||||
pub trait Engine: Send + Sync + Sized {
|
|
||||||
/// Input event type
|
|
||||||
type Input: Input;
|
|
||||||
/// Render target
|
|
||||||
type Output: Output;
|
|
||||||
/// Prepare before run
|
|
||||||
fn setup (&mut self) -> Usually<()> { Ok(()) }
|
|
||||||
/// True if done
|
|
||||||
fn exited (&self) -> bool;
|
|
||||||
/// Clean up after run
|
|
||||||
fn teardown (&mut self) -> Usually<()> { Ok(()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Event source
|
|
||||||
pub trait Input: Send + Sync + Sized {
|
|
||||||
/// Type of input event
|
|
||||||
type Event;
|
|
||||||
/// Result of handling input
|
|
||||||
type Handled;
|
|
||||||
/// Currently handled event
|
|
||||||
fn event (&self) -> &Self::Event;
|
|
||||||
/// Whether component should exit
|
|
||||||
fn is_done (&self) -> bool;
|
|
||||||
/// Mark component as done
|
|
||||||
fn done (&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render target
|
/// Render target
|
||||||
pub trait Output: Send + Sync + Sized {
|
pub trait Output: Send + Sync + Sized {
|
||||||
/// Unit of length
|
/// Unit of length
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::marker::ConstParamTy;
|
use std::marker::ConstParamTy;
|
||||||
use tek_engine::Render;
|
|
||||||
use EdnItem::*;
|
use EdnItem::*;
|
||||||
|
|
||||||
const EDN: &'static str = include_str!("groovebox.edn");
|
const EDN: &'static str = include_str!("groovebox.edn");
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@
|
||||||
#![feature(impl_trait_in_assoc_type)]
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
pub use ::tek_tui::{self, tek_engine, tek_layout};
|
pub use ::tek_tui::{self, tek_edn, tek_input, tek_output};
|
||||||
pub(crate) use ::tek_tui::{
|
pub(crate) use ::tek_tui::{
|
||||||
*,
|
*,
|
||||||
tek_edn::*,
|
tek_edn::*,
|
||||||
tek_layout::*,
|
tek_input::*,
|
||||||
tek_engine::*,
|
tek_output::*,
|
||||||
crossterm::{
|
crossterm::{
|
||||||
self,
|
self,
|
||||||
event::{
|
event::{
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@ edition = "2021"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tek_engine = { path = "../engine" }
|
|
||||||
tek_layout = { path = "../layout" }
|
|
||||||
tek_edn = { optional = true, path = "../edn" }
|
|
||||||
palette = { version = "0.7.6", features = [ "random" ] }
|
palette = { version = "0.7.6", features = [ "random" ] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
crossterm = "0.28.1"
|
crossterm = "0.28.1"
|
||||||
ratatui = { version = "0.29.0", features = [ "unstable-widget-ref", "underline-color" ] }
|
ratatui = { version = "0.29.0", features = [ "unstable-widget-ref", "underline-color" ] }
|
||||||
better-panic = "0.3.0"
|
better-panic = "0.3.0"
|
||||||
|
|
||||||
|
tek_edn = { optional = true, path = "../edn" }
|
||||||
|
tek_input = { optional = true, path = "../input" }
|
||||||
|
tek_output = { optional = true, path = "../output" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["edn"]
|
default = ["tek_input", "tek_output", "tek_edn"]
|
||||||
edn = ["tek_edn"]
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
pub use ::tek_engine;
|
pub use ::tek_input;
|
||||||
pub use ::tek_layout;
|
pub use ::tek_output;
|
||||||
pub use ::tek_edn;
|
pub use ::tek_edn;
|
||||||
pub(crate) use tek_layout::*;
|
pub(crate) use tek_input::*;
|
||||||
pub(crate) use tek_engine::*;
|
pub(crate) use tek_output::*;
|
||||||
|
|
||||||
mod tui_engine; pub use self::tui_engine::*;
|
mod tui_engine; pub use self::tui_engine::*;
|
||||||
mod tui_content; pub use self::tui_content::*;
|
mod tui_content; pub use self::tui_content::*;
|
||||||
|
|
|
||||||
|
|
@ -7,31 +7,6 @@ pub struct Tui {
|
||||||
pub area: [u16;4], // FIXME auto resize
|
pub area: [u16;4], // FIXME auto resize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine for Tui {
|
|
||||||
type Input = TuiIn;
|
|
||||||
type Output = TuiOut;
|
|
||||||
fn exited (&self) -> bool {
|
|
||||||
self.exited.fetch_and(true, Relaxed)
|
|
||||||
}
|
|
||||||
fn setup (&mut self) -> Usually<()> {
|
|
||||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
|
||||||
std::panic::set_hook(Box::new(move |info: &std::panic::PanicHookInfo|{
|
|
||||||
stdout().execute(LeaveAlternateScreen).unwrap();
|
|
||||||
CrosstermBackend::new(stdout()).show_cursor().unwrap();
|
|
||||||
disable_raw_mode().unwrap();
|
|
||||||
better_panic_handler(info);
|
|
||||||
}));
|
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
|
||||||
self.backend.hide_cursor()?;
|
|
||||||
enable_raw_mode().map_err(Into::into)
|
|
||||||
}
|
|
||||||
fn teardown (&mut self) -> Usually<()> {
|
|
||||||
stdout().execute(LeaveAlternateScreen)?;
|
|
||||||
self.backend.show_cursor()?;
|
|
||||||
disable_raw_mode().map_err(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Tui {
|
impl Tui {
|
||||||
/// Construct a new TUI engine and wrap it for shared ownership.
|
/// Construct a new TUI engine and wrap it for shared ownership.
|
||||||
pub fn new () -> Usually<Arc<RwLock<Self>>> {
|
pub fn new () -> Usually<Arc<RwLock<Self>>> {
|
||||||
|
|
@ -44,6 +19,23 @@ impl Tui {
|
||||||
backend,
|
backend,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
/// True if done
|
||||||
|
pub fn exited (&self) -> bool {
|
||||||
|
self.exited.fetch_and(true, Relaxed)
|
||||||
|
}
|
||||||
|
/// Prepare before run
|
||||||
|
pub fn setup (&mut self) -> Usually<()> {
|
||||||
|
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||||
|
std::panic::set_hook(Box::new(move |info: &std::panic::PanicHookInfo|{
|
||||||
|
stdout().execute(LeaveAlternateScreen).unwrap();
|
||||||
|
CrosstermBackend::new(stdout()).show_cursor().unwrap();
|
||||||
|
disable_raw_mode().unwrap();
|
||||||
|
better_panic_handler(info);
|
||||||
|
}));
|
||||||
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
|
self.backend.hide_cursor()?;
|
||||||
|
enable_raw_mode().map_err(Into::into)
|
||||||
|
}
|
||||||
/// Update the display buffer.
|
/// Update the display buffer.
|
||||||
pub fn flip (&mut self, mut buffer: Buffer, size: ratatui::prelude::Rect) -> Buffer {
|
pub fn flip (&mut self, mut buffer: Buffer, size: ratatui::prelude::Rect) -> Buffer {
|
||||||
if self.buffer.area != size {
|
if self.buffer.area != size {
|
||||||
|
|
@ -58,4 +50,10 @@ impl Tui {
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
/// Clean up after run
|
||||||
|
pub fn teardown (&mut self) -> Usually<()> {
|
||||||
|
stdout().execute(LeaveAlternateScreen)?;
|
||||||
|
self.backend.show_cursor()?;
|
||||||
|
disable_raw_mode().map_err(Into::into)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue