Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tui Lazy Attributes and Layout #329

Merged
merged 37 commits into from May 3, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
499971e
wip lazy layout
ealmloff Mar 18, 2022
26d92b6
rebase master
ealmloff Mar 23, 2022
6adfa88
moved stretch layout to native-core
ealmloff Mar 23, 2022
7f4e257
bugfixes, testing and refactoring
ealmloff Mar 27, 2022
05d0416
Delete launch.json
ealmloff Mar 27, 2022
5b25500
finishing touches and benchmarks
ealmloff Mar 31, 2022
32b2e3a
bugfixes, docs, and pass clippy
ealmloff Apr 2, 2022
a001b7c
re-enable rendering
ealmloff Apr 3, 2022
56af1f7
remove extra prints
ealmloff Apr 3, 2022
479c127
Merge branch 'DioxusLabs:master' into lazy_tui
ealmloff Apr 4, 2022
06e8785
add PopRoot
ealmloff Apr 4, 2022
351722d
update dependancy to stretch2 master and remove refrences to tree
ealmloff Apr 4, 2022
3dd18b2
added headless mode for CI
ealmloff Apr 5, 2022
92f4816
WIP new api
ealmloff Apr 9, 2022
9e9fc09
WIP macro progress
ealmloff Apr 9, 2022
13a99bc
WIP: intigrate exsisting code
ealmloff Apr 10, 2022
92010b0
WIP update tests
ealmloff Apr 12, 2022
9eaf721
tests passing, and tui updated
ealmloff Apr 12, 2022
2b383bc
fixed test
ealmloff Apr 12, 2022
71707fe
pass cargo check
ealmloff Apr 12, 2022
628638b
new dioxus_core api
ealmloff Apr 13, 2022
3b06059
fix rendering
ealmloff Apr 13, 2022
0fb9aed
add children on initial build and add sorted slice macro
ealmloff Apr 13, 2022
436c6a0
add node dependancy
ealmloff Apr 16, 2022
b9c2664
add builder methods to NodeMask
ealmloff Apr 16, 2022
4718668
add docoumentation for custom_renderer
ealmloff Apr 17, 2022
d9276bd
clean up code and docs
ealmloff Apr 17, 2022
e9da4c0
add todo
ealmloff Apr 17, 2022
b79a58c
pass clippy
ealmloff Apr 17, 2022
f4689a4
Merge branch 'DioxusLabs:master' into lazy_tui
ealmloff Apr 17, 2022
7c30d93
nested state
ealmloff Apr 20, 2022
cebf170
fixed infinite loop in union_ordered_iter
ealmloff Apr 20, 2022
7b35566
allow nodes to depend on the listeners of a node
ealmloff Apr 21, 2022
84db875
Merge branch 'master' of https://github.com/DioxusLabs/dioxus into la…
ealmloff Apr 24, 2022
e1120bb
ensure all nodes have a intialized layout
ealmloff May 2, 2022
3adcba5
remove empty attributes
ealmloff May 3, 2022
0b1e17c
add native-core-macro to workspace
ealmloff May 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.toml
Expand Up @@ -28,6 +28,8 @@ dioxus-tui = { path = "./packages/tui", version = "^0.2.0", optional = true }

dioxus-liveview = { path = "./packages/liveview", optional = true }

dioxus-native-core = { path = "./packages/native-core", optional = true }

# dioxus-mobile = { path = "./packages/mobile", version = "^0.2.0", optional = true }
# dioxus-rsx = { path = "./packages/rsx", optional = true }
# macro = ["dioxus-core-macro", "dioxus-rsx"]
Expand All @@ -45,6 +47,7 @@ ayatana = ["dioxus-desktop/ayatana"]
router = ["dioxus-router"]
tui = ["dioxus-tui"]
liveview = ["dioxus-liveview"]
native-core = ["dioxus-native-core"]


[workspace]
Expand All @@ -61,6 +64,7 @@ members = [
"packages/fermi",
"packages/tui",
"packages/liveview",
"packages/native-core",
]
ealmloff marked this conversation as resolved.
Show resolved Hide resolved

[dev-dependencies]
Expand Down Expand Up @@ -88,3 +92,7 @@ harness = false
[[bench]]
name = "jsframework"
harness = false

[[bench]]
name = "tui_update"
harness = false
230 changes: 230 additions & 0 deletions benches/tui_update.rs
@@ -0,0 +1,230 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use dioxus::prelude::*;
use dioxus_tui::{Config, TuiContext};

criterion_group!(mbenches, tui_update);
criterion_main!(mbenches);

/// This benchmarks the cache performance of the TUI for small edits by changing one box at a time.
fn tui_update(c: &mut Criterion) {
let mut group = c.benchmark_group("Update boxes");

// We can also use loops to define multiple benchmarks, even over multiple dimensions.
for size in 1..=6 {
let parameter_string = format!("{}", 5 * size);
group.bench_with_input(
BenchmarkId::new("size", parameter_string),
&size,
|b, size| {
b.iter(|| match size {
1 => dioxus::tui::launch_cfg(
app5,
Config {
headless: true,
..Default::default()
},
),
2 => dioxus::tui::launch_cfg(
app10,
Config {
headless: true,
..Default::default()
},
),
3 => dioxus::tui::launch_cfg(
app15,
Config {
headless: true,
..Default::default()
},
),
4 => dioxus::tui::launch_cfg(
app20,
Config {
headless: true,
..Default::default()
},
),
5 => dioxus::tui::launch_cfg(
app25,
Config {
headless: true,
..Default::default()
},
),
6 => dioxus::tui::launch_cfg(
app30,
Config {
headless: true,
..Default::default()
},
),
_ => (),
})
},
);
}
}

#[derive(Props, PartialEq)]
struct BoxProps {
x: usize,
y: usize,
hue: f32,
alpha: f32,
}
#[allow(non_snake_case)]
fn Box(cx: Scope<BoxProps>) -> Element {
let count = use_state(&cx, || 0);

let x = cx.props.x * 2;
let y = cx.props.y * 2;
let hue = cx.props.hue;
let display_hue = cx.props.hue as u32 / 10;
let count = count.get();
let alpha = cx.props.alpha + (count % 100) as f32;

cx.render(rsx! {
div {
left: "{x}%",
top: "{y}%",
width: "100%",
height: "100%",
background_color: "hsl({hue}, 100%, 50%, {alpha}%)",
align_items: "center",
p{"{display_hue:03}"}
}
})
}

#[derive(Props, PartialEq)]
struct GridProps {
size: usize,
}
#[allow(non_snake_case)]
fn Grid(cx: Scope<GridProps>) -> Element {
let size = cx.props.size;
let count = use_state(&cx, || 0);
let counts = use_ref(&cx, || vec![0; size * size]);

let ctx: TuiContext = cx.consume_context().unwrap();
if *count.get() + 1 >= (size * size) {
ctx.quit();
} else {
counts.with_mut(|c| {
let i = *count.current();
c[i] += 1;
c[i] = c[i] % 360;
});
count.with_mut(|i| {
*i += 1;
*i = *i % (size * size);
});
}

cx.render(rsx! {
div{
width: "100%",
height: "100%",
flex_direction: "column",
(0..size).map(|x|
{
cx.render(rsx! {
div{
width: "100%",
height: "100%",
flex_direction: "row",
(0..size).map(|y|
{
let alpha = y as f32*100.0/size as f32 + counts.read()[x*size + y] as f32;
let key = format!("{}-{}", x, y);
cx.render(rsx! {
Box{
x: x,
y: y,
alpha: 100.0,
hue: alpha,
key: "{key}",
}
})
}
)
}
})
}
)
}
})
}

fn app5(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 5,
}
}
})
}

fn app10(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 10,
}
}
})
}

fn app15(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 15,
}
}
})
}

fn app20(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 20,
}
}
})
}

fn app25(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 25,
}
}
})
}

fn app30(cx: Scope) -> Element {
cx.render(rsx! {
div{
width: "100%",
height: "100%",
Grid{
size: 30,
}
}
})
}
49 changes: 41 additions & 8 deletions docs/reference/src/platforms/tui.md
Expand Up @@ -9,13 +9,12 @@ TUI support is currently quite experimental. Even the project name will change.
## Getting Set up


To tinker with TUI support, start by making a new package and adding our TUI package from git.
To tinker with TUI support, start by making a new package and adding our TUI feature.

```shell
$ cargo new --bin demo
$ cd demo
$ cargo add dioxus
$ cargo add rink --git https://github.com/DioxusLabs/rink.git
$ cargo add dioxus --features tui
```


Expand All @@ -27,10 +26,7 @@ Then, edit your `main.rs` with the basic template.
use dioxus::prelude::*;

fn main() {
let mut dom = VirtualDom::new(app);
dom.rebuild();

rink::render_vdom(&mut dom).unwrap();
dioxus::tui::launch(app);
}

fn app(cx: Scope) -> Element {
Expand All @@ -54,7 +50,44 @@ To run our app:
$ cargo run
```

Press "q" to close the app (yes, this is hardcoded, we are working on handlers to expose this in your code.)
Press "ctrl-c" to close the app. To switch from "ctrl-c" to just "q" to quit you can launch the app with a Configeration to disable the default quit and use the root TuiContext to quit on your own.

```rust
// main
use dioxus::events::{KeyCode, KeyboardEvent};
use dioxus::prelude::*;
use dioxus::tui::TuiContext;

fn main() {
dioxus::tui::launch_cfg(
app,
dioxus::tui::Config {
ctrl_c_quit: false,
// Some older terminals only support 16 colors or ANSI colors if your terminal is one of these change this to BaseColors or ANSI
rendering_mode: dioxus::tui::RenderingMode::Rgb,
},
);
}

fn app(cx: Scope) -> Element {
let tui_ctx: TuiContext = cx.consume_context().unwrap();

cx.render(rsx! {
div {
width: "100%",
height: "10px",
background_color: "red",
justify_content: "center",
align_items: "center",
onkeydown: move |k: KeyboardEvent| if let KeyCode::Q = k.data.key_code {
tui_ctx.quit();
},

"Hello world!"
}
})
}
```

## Notes

Expand Down
1 change: 1 addition & 0 deletions examples/tui_color_test.rs
Expand Up @@ -5,6 +5,7 @@ fn main() {
app,
dioxus::tui::Config {
rendering_mode: dioxus::tui::RenderingMode::Ansi,
..Default::default()
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/events.rs
Expand Up @@ -49,7 +49,7 @@ impl BubbleState {
/// }
/// )).unwrap();
/// ```
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct UserEvent {
/// The originator of the event trigger if available
pub scope_id: Option<ScopeId>,
Expand Down
19 changes: 19 additions & 0 deletions packages/native-core/Cargo.toml
@@ -0,0 +1,19 @@
[package]
name = "dioxus-native-core"
version = "0.2.0"
edition = "2021"
license = "MIT/Apache-2.0"
repository = "https://github.com/DioxusLabs/dioxus/"
homepage = "https://dioxuslabs.com"

[dependencies]
dioxus-core = { path = "../core", version = "^0.2.0" }
dioxus-html = { path = "../html", version = "^0.2.0" }
dioxus-core-macro = { path = "../core-macro", version = "^0.2.0" }

stretch2 = { git = "https://github.com/DioxusLabs/stretch" }
smallvec = "1.6"
fxhash = "0.2"

[dev-dependencies]
rand = "0.8.5"