Ported examples 00 and 01 to proc macro interface.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use ruin_app::prelude::*;
|
||||
use ruin_ui::Border;
|
||||
|
||||
#[ruin_runtime::async_main]
|
||||
async fn main() -> ruin_app::Result<()> {
|
||||
|
||||
162
lib/ruin_app/example/01_async_data_and_effects.rs
Normal file
162
lib/ruin_app/example/01_async_data_and_effects.rs
Normal file
@@ -0,0 +1,162 @@
|
||||
use ruin_app::prelude::*;
|
||||
|
||||
#[ruin_runtime::async_main]
|
||||
async fn main() -> ruin_app::Result<()> {
|
||||
App::new()
|
||||
.window(
|
||||
Window::new()
|
||||
.title("RUIN Async Data and Effects")
|
||||
.app_id("dev.ruin.async-data")
|
||||
.size(1080.0, 760.0),
|
||||
)
|
||||
.mount(view! {
|
||||
AsyncDataAndEffectsDemo() {}
|
||||
})
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn AsyncDataAndEffectsDemo() -> impl IntoView {
|
||||
let selected_path = use_signal(|| "Cargo.toml".to_string());
|
||||
let reload_nonce = use_signal(|| 0_u64);
|
||||
let preview_scroll = use_signal(|| 0.0_f32);
|
||||
|
||||
let file_contents = use_resource({
|
||||
let selected_path = selected_path.clone();
|
||||
let reload_nonce = reload_nonce.clone();
|
||||
move || {
|
||||
let path = selected_path.get();
|
||||
let _ = reload_nonce.get();
|
||||
async move {
|
||||
ruin_runtime::fs::read_to_string(&path)
|
||||
.await
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
use_effect({
|
||||
let selected_path = selected_path.clone();
|
||||
let reload_nonce = reload_nonce.clone();
|
||||
move || {
|
||||
eprintln!(
|
||||
"async resource dependencies changed: path={}, reload={}",
|
||||
selected_path.get(),
|
||||
reload_nonce.get()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
use_effect({
|
||||
let selected_path = selected_path.clone();
|
||||
let reload_nonce = reload_nonce.clone();
|
||||
let preview_scroll = preview_scroll.clone();
|
||||
move || {
|
||||
let _ = selected_path.get();
|
||||
let _ = reload_nonce.get();
|
||||
let _ = preview_scroll.set(0.0);
|
||||
}
|
||||
});
|
||||
|
||||
use_window_title({
|
||||
let selected_path = selected_path.clone();
|
||||
move || format!("RUIN Async Demo ({})", selected_path.get())
|
||||
});
|
||||
|
||||
view! {
|
||||
column(gap = 16.0, padding = 24.0) {
|
||||
text(role = TextRole::Heading(1), size = 32.0, weight = FontWeight::Semibold) {
|
||||
"Async data and effects"
|
||||
}
|
||||
|
||||
text(color = colors::muted(), wrap = TextWrap::Word) {
|
||||
"This is a smaller truthful slice of example 01: local signals drive a real async \
|
||||
resource, and an effect logs the dependency changes."
|
||||
}
|
||||
|
||||
FileControls(selected_path = selected_path.clone(), reload_nonce = reload_nonce.clone()) {}
|
||||
|
||||
block(
|
||||
padding = 16.0,
|
||||
gap = 10.0,
|
||||
background = surfaces::raised(),
|
||||
border_radius = 12.0,
|
||||
) {
|
||||
text(size = 18.0) { "selected = "; selected_path.clone() }
|
||||
|
||||
match file_contents.read() {
|
||||
Pending => view! {
|
||||
text(color = colors::muted()) {
|
||||
"Loading file contents..."
|
||||
}
|
||||
},
|
||||
Ready(Ok(contents)) => view! {
|
||||
column(background = surfaces::raised(), gap = 10.0) {
|
||||
text() { "bytes = "; contents.len() }
|
||||
|
||||
scroll_box(
|
||||
height = 420.0,
|
||||
offset_y = preview_scroll.clone(),
|
||||
padding = 12.0,
|
||||
background = surfaces::canvas(),
|
||||
border_radius = 10.0,
|
||||
border = (2.0, colors::muted()),
|
||||
) {
|
||||
text(
|
||||
color = colors::muted(),
|
||||
font_family = TextFontFamily::Monospace,
|
||||
) {
|
||||
contents
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Ready(Err(error)) => view! {
|
||||
text(color = colors::danger()) { error.to_string() }
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn FileControls(selected_path: Signal<String>, reload_nonce: Signal<u64>) -> impl IntoView {
|
||||
view! {
|
||||
row(gap = 8.0) {
|
||||
button(
|
||||
on_press = {
|
||||
let selected_path = selected_path.clone();
|
||||
move |_| {
|
||||
let _ = selected_path.set("Cargo.toml".to_string());
|
||||
}
|
||||
},
|
||||
) {
|
||||
"Cargo.toml"
|
||||
}
|
||||
|
||||
button(
|
||||
on_press = {
|
||||
let selected_path = selected_path.clone();
|
||||
move |_| {
|
||||
let _ = selected_path.set("Cargo.lock".to_string());
|
||||
}
|
||||
},
|
||||
) {
|
||||
"Cargo.lock"
|
||||
}
|
||||
|
||||
button(
|
||||
on_press = {
|
||||
let reload_nonce = reload_nonce.clone();
|
||||
move |_| {
|
||||
reload_nonce.update(|value| *value += 1);
|
||||
}
|
||||
},
|
||||
) {
|
||||
"Reload"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user