tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Definiciones

⎇ main llimphi-jaula/examples/emitir_fixture.rs Rust · 146 líneas · 5.4 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo — 128 miembros, los 76 widgets y los 11 módulos b3f12e136 · Sergio ·

1// =============================================================================
2//  emitir_fixture :: la escena que el kernel va a reproducir
3// -----------------------------------------------------------------------------
4//  El encoder (esta jaula) y el reproductor (`llimphi-wawa`) NO pueden vivir en
5//  el mismo binario: `wire` y `cpu` son backends excluyentes de `llimphi-text`,
6//  y encender los dos dispara un `compile_error!` puesto a propósito. Eso no es
7//  un obstáculo del diseño, es el diseño — son dos procesos en dos lados de una
8//  frontera, y forzarlos a convivir para testearlos sería probar otra cosa.
9//
10//  Así que la costura del test es la misma que la de producción: **bytes**. Este
11//  ejemplo compone una vista con el compositor de verdad, la serializa, y deja
12//  el resultado donde el test del otro lado lo levanta con `include_bytes!`.
13//
14//      cargo run --example emitir_fixture --no-default-features --features std
15//
16//  Si alguna vez el fixture y el reproductor dejan de entenderse, el test de
17//  `llimphi-wawa` lo dice — que es exactamente lo que uno quiere que pase si
18//  alguien cambia el formato del cable de un solo lado.
19// =============================================================================
20
21use std::io::Write;
22
23use llimphi_jaula::taffy::prelude::*;
24use llimphi_jaula::{Color, Jaula, Style, View};
25use llimphi_text::wire::{Medida, Peticion};
26
27/// El destino, relativo a este crate.
28const DESTINO: &str = "../llimphi-wawa/pruebas/fixture_jaula.postcard";
29
30#[derive(Clone, Debug, PartialEq)]
31enum Msg {
32    Toque,
33}
34
35/// El medidor de la jaula.
36///
37/// **Acá está la única pieza de W4 que todavía es un muñón**, y conviene que se
38/// vea: en wawa esto tiene que ser un `sys_medir_texto` que cruza a parley del
39/// lado nativo. Mientras no exista, el fixture se layoutea con una fórmula. La
40/// consecuencia práctica: el texto del fixture se pinta bien —el kernel lo
41/// shapea de verdad— pero ubicado según una medida aproximada.
42fn medidor(p: &Peticion<'_>) -> Medida {
43    let chars = p.cadena.chars().count() as f32;
44    let ancho = chars * p.estilo.tamano_px * 0.52;
45    Medida {
46        width: ancho,
47        full_width: ancho,
48        height: p.estilo.tamano_px * p.estilo.alto_linea,
49    }
50}
51
52fn vista() -> View<Msg> {
53    let raiz = Style {
54        size: Size {
55            width: length(320.0),
56            height: length(72.0),
57        },
58        flex_direction: FlexDirection::Column,
59        justify_content: Some(JustifyContent::CENTER),
60        padding: Rect {
61            left: length(14.0),
62            right: length(14.0),
63            top: length(10.0),
64            bottom: length(10.0),
65        },
66        ..Default::default()
67    };
68
69    View::new(raiz)
70        .fill(Color::from_rgba8(22, 26, 38, 255))
71        .radius(8.0)
72        .children(vec![
73            View::new(Style::default()).text(
74                "escena emitida por la jaula",
75                15.0,
76                Color::from_rgba8(230, 232, 240, 255),
77            ),
78            View::new(Style::default())
79                .text(
80                    "shapeada del otro lado",
81                    12.0,
82                    Color::from_rgba8(140, 200, 175, 255),
83                )
84                .on_click(Msg::Toque),
85        ])
86}
87
88fn main() {
89    let mut jaula = Jaula::new(320.0, 72.0, medidor);
90    let _montado = jaula.fotograma(vista());
91    let escena = jaula.escena();
92
93    let bytes = postcard::to_allocvec(escena).expect("serializar");
94
95    println!("órdenes      : {}", escena.len());
96    println!("textos       : {}", escena.textos());
97    println!("estilos      : {}", escena.estilos().len());
98    println!("estimadas    : {}", jaula.medidas_estimadas());
99    println!("bytes        : {}", bytes.len());
100
101    let destino = std::path::Path::new(DESTINO);
102    if let Some(dir) = destino.parent() {
103        std::fs::create_dir_all(dir).expect("crear directorio");
104    }
105    let mut f = std::fs::File::create(destino).expect("crear fixture");
106    f.write_all(&bytes).expect("escribir fixture");
107    println!("escrito en   : {}", destino.display());
108
109    emitir_peticion_de_prueba();
110}
111
112/// Emite además los bytes de una `PeticionMedida` lista para embeber en una app
113/// `.wasm` sin asignador.
114///
115/// `hello_wasm` es `no_std` y **sin alloc**: no puede construir un `String` para
116/// armar la petición en tiempo de ejecución. Pero tampoco lo necesita — lo único
117/// que el syscall pide son bytes, y los bytes se pueden calcular acá y embeber
118/// como constante. Así la app de prueba ejercita el cruce de verdad sin arrastrar
119/// un asignador que no le hace falta para nada más.
120fn emitir_peticion_de_prueba() {
121    use llimphi_jaula::wire::{EstiloTextoWire, PeticionMedida};
122
123    let peticion = PeticionMedida {
124        cadena: "wawa mide texto".into(),
125        estilo: EstiloTextoWire {
126            tamano_px: 16.0,
127            ..Default::default()
128        },
129        ancho_max: None,
130    };
131    let bytes = postcard::to_allocvec(&peticion).expect("serializar peticion");
132
133    println!("\n// --- pegar en 03_ukupacha/wawa/apps/hello_wasm/src/lib.rs ---");
134    println!(
135        "/// `PeticionMedida {{ cadena: {:?}, tamano_px: {} }}` en postcard.",
136        peticion.cadena, peticion.estilo.tamano_px
137    );
138    print!("const PETICION_MEDIDA: [u8; {}] = [", bytes.len());
139    for (i, b) in bytes.iter().enumerate() {
140        if i % 12 == 0 {
141            print!("\n    ");
142        }
143        print!("0x{b:02x}, ");
144    }
145    println!("\n];");
146}