mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-03-13 12:10:44 +01:00
Content was missing for Bsp, wtf...
This commit is contained in:
parent
06f8ed3ae3
commit
0d8503cc05
2 changed files with 180 additions and 132 deletions
278
src/tengri.rs
278
src/tengri.rs
|
|
@ -103,134 +103,6 @@ pub(crate) use ::std::{
|
||||||
/// Stack eastward.
|
/// Stack eastward.
|
||||||
#[macro_export] macro_rules! row (($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::e(bsp, $expr);)*; bsp }});
|
#[macro_export] macro_rules! row (($($expr:expr),* $(,)?) => {{ let bsp = (); $(let bsp = Bsp::e(bsp, $expr);)*; bsp }});
|
||||||
|
|
||||||
/// Define layout operation.
|
|
||||||
#[cfg(feature = "dsl")] pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
|
||||||
state: &S, output: &mut O, expr: &'a impl Expression
|
|
||||||
) -> Usually<bool> where
|
|
||||||
S: Understand<O, ()>
|
|
||||||
+ for<'b>Namespace<'b, bool>
|
|
||||||
+ for<'b>Namespace<'b, O::Unit>
|
|
||||||
{
|
|
||||||
// First element of expression is used for dispatch.
|
|
||||||
// Dispatch is proto-namespaced using separator character
|
|
||||||
let head = expr.head()?;
|
|
||||||
let mut frags = head.src()?.unwrap_or_default().split("/");
|
|
||||||
// The rest of the tokens in the expr are arguments.
|
|
||||||
// Their meanings depend on the dispatched operation
|
|
||||||
let args = expr.tail();
|
|
||||||
let arg0 = args.head();
|
|
||||||
let tail0 = args.tail();
|
|
||||||
let arg1 = tail0.head();
|
|
||||||
let tail1 = tail0.tail();
|
|
||||||
let arg2 = tail1.head();
|
|
||||||
// And we also have to do the above binding dance
|
|
||||||
// so that the Perhaps<token>s remain in scope.
|
|
||||||
match frags.next() {
|
|
||||||
|
|
||||||
Some("when") => output.place(&When::new(
|
|
||||||
state.namespace(arg0?)?.unwrap(),
|
|
||||||
Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap())
|
|
||||||
)),
|
|
||||||
|
|
||||||
Some("either") => output.place(&Either::new(
|
|
||||||
state.namespace(arg0?)?.unwrap(),
|
|
||||||
Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap()),
|
|
||||||
Thunk::new(move|output: &mut O|state.understand(output, &arg2).unwrap())
|
|
||||||
)),
|
|
||||||
|
|
||||||
Some("bsp") => output.place(&{
|
|
||||||
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
|
||||||
let b = Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap());
|
|
||||||
match frags.next() {
|
|
||||||
Some("n") => Bsp::n(a, b),
|
|
||||||
Some("s") => Bsp::s(a, b),
|
|
||||||
Some("e") => Bsp::e(a, b),
|
|
||||||
Some("w") => Bsp::w(a, b),
|
|
||||||
Some("a") => Bsp::a(a, b),
|
|
||||||
Some("b") => Bsp::b(a, b),
|
|
||||||
frag => unimplemented!("bsp/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("align") => output.place(&{
|
|
||||||
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
|
||||||
match frags.next() {
|
|
||||||
Some("n") => Align::n(a),
|
|
||||||
Some("s") => Align::s(a),
|
|
||||||
Some("e") => Align::e(a),
|
|
||||||
Some("w") => Align::w(a),
|
|
||||||
Some("x") => Align::x(a),
|
|
||||||
Some("y") => Align::y(a),
|
|
||||||
Some("c") => Align::c(a),
|
|
||||||
frag => unimplemented!("align/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("fill") => output.place(&{
|
|
||||||
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
|
||||||
match frags.next() {
|
|
||||||
Some("xy") | None => Fill::XY(a),
|
|
||||||
Some("x") => Fill::X(a),
|
|
||||||
Some("y") => Fill::Y(a),
|
|
||||||
frag => unimplemented!("fill/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("fixed") => output.place(&{
|
|
||||||
let axis = frags.next();
|
|
||||||
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.understand(output, &arg).unwrap());
|
|
||||||
match axis {
|
|
||||||
Some("xy") | None => Fixed::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
|
||||||
Some("x") => Fixed::X(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
Some("y") => Fixed::Y(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
frag => unimplemented!("fixed/{frag:?} ({expr:?}) ({head:?}) ({:?})",
|
|
||||||
head.src()?.unwrap_or_default().split("/").next())
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("min") => output.place(&{
|
|
||||||
let axis = frags.next();
|
|
||||||
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.understand(output, &arg).unwrap());
|
|
||||||
match axis {
|
|
||||||
Some("xy") | None => Min::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
|
||||||
Some("x") => Min::X(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
Some("y") => Min::Y(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
frag => unimplemented!("min/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("max") => output.place(&{
|
|
||||||
let axis = frags.next();
|
|
||||||
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.understand(output, &arg).unwrap());
|
|
||||||
match axis {
|
|
||||||
Some("xy") | None => Max::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
|
||||||
Some("x") => Max::X(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
Some("y") => Max::Y(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
frag => unimplemented!("max/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Some("push") => output.place(&{
|
|
||||||
let axis = frags.next();
|
|
||||||
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.understand(output, &arg).unwrap());
|
|
||||||
match axis {
|
|
||||||
Some("xy") | None => Push::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
|
||||||
Some("x") => Push::X(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
Some("y") => Push::Y(state.namespace(arg0?)?.unwrap(), cb),
|
|
||||||
frag => unimplemented!("push/{frag:?}")
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
_ => return Ok(false)
|
|
||||||
|
|
||||||
};
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implement [Command] for given `State` and `handler`
|
/// Implement [Command] for given `State` and `handler`
|
||||||
#[macro_export] macro_rules! command {
|
#[macro_export] macro_rules! command {
|
||||||
($(<$($l:lifetime),+>)?|$self:ident:$Command:ty,$state:ident:$State:ty|$handler:expr) => {
|
($(<$($l:lifetime),+>)?|$self:ident:$Command:ty,$state:ident:$State:ty|$handler:expr) => {
|
||||||
|
|
@ -453,6 +325,151 @@ pub fn tui_input <T: Handle<TuiIn> + Send + Sync + 'static> (
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Define layout operation.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// struct Target;
|
||||||
|
/// impl tengri::Output for Target { type Unit = u16; }
|
||||||
|
///
|
||||||
|
/// struct State;
|
||||||
|
/// impl<'b> Namespace<'b, bool> for State {}
|
||||||
|
/// impl<'b> Namespace<'b, u16> for State {}
|
||||||
|
/// impl Understand<Target, ()> for State {}
|
||||||
|
///
|
||||||
|
/// let state = State;
|
||||||
|
/// let target = Target::default();
|
||||||
|
/// tengri::evaluate_output_expression(&state, &mut out, "")?;
|
||||||
|
/// tengri::evaluate_output_expression(&state, &mut out, "(when true (text hello))")?;
|
||||||
|
/// tengri::evaluate_output_expression(&state, &mut out, "(either true (text hello) (text world)"))?;
|
||||||
|
/// // TODO test all
|
||||||
|
/// ```
|
||||||
|
#[cfg(feature = "dsl")] pub fn evaluate_output_expression <'a, O: Out + 'a, S> (
|
||||||
|
state: &S, output: &mut O, expr: &'a impl Expression
|
||||||
|
) -> Usually<bool> where
|
||||||
|
S: Understand<O, ()>
|
||||||
|
+ for<'b>Namespace<'b, bool>
|
||||||
|
+ for<'b>Namespace<'b, O::Unit>
|
||||||
|
{
|
||||||
|
// First element of expression is used for dispatch.
|
||||||
|
// Dispatch is proto-namespaced using separator character
|
||||||
|
let head = expr.head()?;
|
||||||
|
let mut frags = head.src()?.unwrap_or_default().split("/");
|
||||||
|
// The rest of the tokens in the expr are arguments.
|
||||||
|
// Their meanings depend on the dispatched operation
|
||||||
|
let args = expr.tail();
|
||||||
|
let arg0 = args.head();
|
||||||
|
let tail0 = args.tail();
|
||||||
|
let arg1 = tail0.head();
|
||||||
|
let tail1 = tail0.tail();
|
||||||
|
let arg2 = tail1.head();
|
||||||
|
// And we also have to do the above binding dance
|
||||||
|
// so that the Perhaps<token>s remain in scope.
|
||||||
|
match frags.next() {
|
||||||
|
|
||||||
|
Some("when") => output.place(&When::new(
|
||||||
|
state.namespace(arg0?)?.unwrap(),
|
||||||
|
Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap())
|
||||||
|
)),
|
||||||
|
|
||||||
|
Some("either") => output.place(&Either::new(
|
||||||
|
state.namespace(arg0?)?.unwrap(),
|
||||||
|
Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap()),
|
||||||
|
Thunk::new(move|output: &mut O|state.understand(output, &arg2).unwrap())
|
||||||
|
)),
|
||||||
|
|
||||||
|
Some("bsp") => output.place(&{
|
||||||
|
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
||||||
|
let b = Thunk::new(move|output: &mut O|state.understand(output, &arg1).unwrap());
|
||||||
|
match frags.next() {
|
||||||
|
Some("n") => Bsp::n(a, b),
|
||||||
|
Some("s") => Bsp::s(a, b),
|
||||||
|
Some("e") => Bsp::e(a, b),
|
||||||
|
Some("w") => Bsp::w(a, b),
|
||||||
|
Some("a") => Bsp::a(a, b),
|
||||||
|
Some("b") => Bsp::b(a, b),
|
||||||
|
frag => unimplemented!("bsp/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("align") => output.place(&{
|
||||||
|
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
||||||
|
match frags.next() {
|
||||||
|
Some("n") => Align::n(a),
|
||||||
|
Some("s") => Align::s(a),
|
||||||
|
Some("e") => Align::e(a),
|
||||||
|
Some("w") => Align::w(a),
|
||||||
|
Some("x") => Align::x(a),
|
||||||
|
Some("y") => Align::y(a),
|
||||||
|
Some("c") => Align::c(a),
|
||||||
|
frag => unimplemented!("align/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("fill") => output.place(&{
|
||||||
|
let a = Thunk::new(move|output: &mut O|state.understand(output, &arg0).unwrap());
|
||||||
|
match frags.next() {
|
||||||
|
Some("xy") | None => Fill::XY(a),
|
||||||
|
Some("x") => Fill::X(a),
|
||||||
|
Some("y") => Fill::Y(a),
|
||||||
|
frag => unimplemented!("fill/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("fixed") => output.place(&{
|
||||||
|
let axis = frags.next();
|
||||||
|
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.understand(output, &arg).unwrap());
|
||||||
|
match axis {
|
||||||
|
Some("xy") | None => Fixed::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
||||||
|
Some("x") => Fixed::X(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
Some("y") => Fixed::Y(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
frag => unimplemented!("fixed/{frag:?} ({expr:?}) ({head:?}) ({:?})",
|
||||||
|
head.src()?.unwrap_or_default().split("/").next())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("min") => output.place(&{
|
||||||
|
let axis = frags.next();
|
||||||
|
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.understand(output, &arg).unwrap());
|
||||||
|
match axis {
|
||||||
|
Some("xy") | None => Min::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
||||||
|
Some("x") => Min::X(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
Some("y") => Min::Y(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
frag => unimplemented!("min/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("max") => output.place(&{
|
||||||
|
let axis = frags.next();
|
||||||
|
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.understand(output, &arg).unwrap());
|
||||||
|
match axis {
|
||||||
|
Some("xy") | None => Max::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
||||||
|
Some("x") => Max::X(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
Some("y") => Max::Y(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
frag => unimplemented!("max/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
Some("push") => output.place(&{
|
||||||
|
let axis = frags.next();
|
||||||
|
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.understand(output, &arg).unwrap());
|
||||||
|
match axis {
|
||||||
|
Some("xy") | None => Push::XY(state.namespace(arg0?)?.unwrap(), state.namespace(arg1?)?.unwrap(), cb),
|
||||||
|
Some("x") => Push::X(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
Some("y") => Push::Y(state.namespace(arg0?)?.unwrap(), cb),
|
||||||
|
frag => unimplemented!("push/{frag:?}")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
_ => return Ok(false)
|
||||||
|
|
||||||
|
};
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
/// Should be impl something or other...
|
/// Should be impl something or other...
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|
@ -485,7 +502,7 @@ pub fn tui_input <T: Handle<TuiIn> + Send + Sync + 'static> (
|
||||||
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") => {
|
Some("text") => {
|
||||||
|
|
@ -500,6 +517,9 @@ pub fn tui_input <T: Handle<TuiIn> + Send + Sync + 'static> (
|
||||||
},
|
},
|
||||||
|
|
||||||
Some("bg") => {
|
Some("bg") => {
|
||||||
|
//panic!("expr: {expr:?}\nhead: {head:?}\nfrags: {frags:?}\nargs: {args:?}\narg0: {arg0:?}\ntail0: {tail0:?}\narg1: {arg1:?}\ntail1: {tail1:?}\narg2: {arg2:?}");
|
||||||
|
//panic!("head: {head:?}\narg0: {arg0:?}\narg1: {arg1:?}\narg2: {arg2:?}");;
|
||||||
|
//panic!("head: {head:?}\narg0: {arg0:?}\narg1: {arg1:?}\narg2: {arg2:?}");
|
||||||
let arg0 = arg0?.expect("bg: expected arg 0 (color)");
|
let arg0 = arg0?.expect("bg: expected arg 0 (color)");
|
||||||
let color = Namespace::namespace(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color"));
|
let color = Namespace::namespace(state, arg0)?.unwrap_or_else(||panic!("bg: {arg0:?}: not a color"));
|
||||||
let thunk = Thunk::new(move|output: &mut TuiOut|state.understand(output, &arg1).unwrap());
|
let thunk = Thunk::new(move|output: &mut TuiOut|state.understand(output, &arg1).unwrap());
|
||||||
|
|
|
||||||
|
|
@ -673,14 +673,42 @@ impl<Head, Tail> Bsp<Head, Tail> {
|
||||||
impl<O: Out, Head: Content<O>, Tail: Content<O>> Draw<O> for Bsp<Head, Tail> {
|
impl<O: Out, Head: Content<O>, Tail: Content<O>> Draw<O> for Bsp<Head, Tail> {
|
||||||
fn draw (&self, to: &mut O) {
|
fn draw (&self, to: &mut O) {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
South => {
|
North => { // FIXME
|
||||||
//panic!("{}", self.1.h(to.area()));
|
|
||||||
let area_1 = self.1.layout(to.area());
|
let area_1 = self.1.layout(to.area());
|
||||||
let area_2 = self.2.layout(XYWH(
|
let area_2 = self.2.layout(XYWH(
|
||||||
to.area().x(), to.area().y().plus(area_1.h()),
|
to.area().x(), to.area().y().plus(area_1.h()),
|
||||||
to.area().w(), to.area().h().minus(area_1.h())
|
to.area().w(), to.area().h().minus(area_1.h())
|
||||||
));
|
));
|
||||||
//panic!("{area_1:?} {area_2:?}");
|
to.place_at(area_1, &self.1);
|
||||||
|
to.place_at(area_2, &self.2);
|
||||||
|
},
|
||||||
|
South => {
|
||||||
|
let area_1 = self.1.layout(to.area());
|
||||||
|
let area_2 = self.2.layout(XYWH(
|
||||||
|
to.area().x(), to.area().y().plus(area_1.h()),
|
||||||
|
to.area().w(), to.area().h().minus(area_1.h())
|
||||||
|
));
|
||||||
|
to.place_at(area_1, &self.1);
|
||||||
|
to.place_at(area_2, &self.2);
|
||||||
|
},
|
||||||
|
East => {
|
||||||
|
let area_1 = self.1.layout(to.area());
|
||||||
|
let area_2 = self.2.layout(XYWH(
|
||||||
|
to.area().x().plus(area_1.w()), to.area().y(),
|
||||||
|
to.area().w().minus(area_1.w()), to.area().h()
|
||||||
|
));
|
||||||
|
to.place_at(area_1, &self.1);
|
||||||
|
to.place_at(area_2, &self.2);
|
||||||
|
},
|
||||||
|
Above => {
|
||||||
|
let area_1 = self.1.layout(to.area());
|
||||||
|
let area_2 = self.2.layout(to.area());
|
||||||
|
to.place_at(area_2, &self.2);
|
||||||
|
to.place_at(area_1, &self.1);
|
||||||
|
},
|
||||||
|
Below => {
|
||||||
|
let area_1 = self.1.layout(to.area());
|
||||||
|
let area_2 = self.2.layout(to.area());
|
||||||
to.place_at(area_1, &self.1);
|
to.place_at(area_1, &self.1);
|
||||||
to.place_at(area_2, &self.2);
|
to.place_at(area_2, &self.2);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue