lgui-core 0.2.2

Platform-neutral runtime and UI primitives for LGUI
Documentation
# UI Core Runtime

`core` is the backend-independent retained UI runtime. The library boundary and public-crate
constraints live in [`../../../../ARCHITECTURE.md`](../../../../ARCHITECTURE.md).

## Public component model

Application UI is expressed as retained function components and declarative `Element` content:

```rust
fn counter(cx: &mut RenderCx<'_, '_>) -> Element {
    let count = cx.state(0_u32);
    let current = count.get();
    let rect = UiRect::new(0.0, 0.0, 160.0, 48.0);

    cx.use_effect((current,), move || {
        move || tracing::debug!(count = current, "counter effect cleanup")
    });

    group(rect).content((
        current,
        button(rect, "Add", ButtonStyle::default())
            .on_click(move |_| count.update(|value| *value += 1)),
    ))
}
```

Element handlers receive the generic `UiEventContext`, which provides propagation control,
default prevention, async spawning, Store/Router access, and the current Window handle.

## Ownership and update flow

- `ComponentTree` owns component identity, keyed reconciliation, cached output, Hook order, and
  component dirtiness.
- `HookStateStore` and `UiUpdateQueue` own typed State, thread-safe batched updates and
  session-bound focus requests.
- `EffectRegistry` stages Effects during render and runs them only after a successful present;
  dependency changes and unmounts run cleanup first.
- `ContextRegistry`, `Observable`, and `RouterContext` provide typed Context, Store selectors, and
  application-defined routing without business commands in Core.
- `HostTree` is the retained backend-independent projection. A clean component boundary keeps its
  Host subtree without visiting descendants.
- `LayoutRuntime` consumes projection changes and lays out only affected boundaries.
- `HostRuntime` reconciles generated Host mutations, retained Scene nodes, and commit-driven damage.
- Skia encodes the same retained `Scene` owned by a window-level `UiSession`.

The normal update chain is:

```text
generic input -> Element handler -> queued update -> dirty component execution
  -> Host projection changes -> incremental layout -> retained Scene update
  -> damage -> backend present -> committed Effects
```

## Dependency boundary

Core contains no Win32, Skia, page, application route, settings, or domain-store types.
Platform code translates native messages to `InputEvent`; applications provide theme data,
pure Store types, and route values. Control-specific retained state (text editing, selection, scroll,
slider, rich editor) remains separate from component Hook State.

The implementation modules follow their ownership boundaries:

- `foundation`: geometry, IDs, and backend-neutral styles.
- `component`: component identity, hooks, contexts, effects, and update execution.
- `input`: input vocabulary, dispatch, handler contracts, and interaction state.
- `layout`: layout computation and dirty tracking.
- `scene`: scene primitives, compilation, signatures, transforms, and retained raster snapshots.
- `view`: declarative elements, host nodes, projection, and hit testing.

`runtime` sits outside `core` and owns the per-window session, retained host commit pipeline, and
frame invalidation. Renderer preference is defined by `lgui-render-api`; concrete renderer probing
and selection is composed by the `lgui` facade.

## Identity rules

- Components use generated `ComponentId { index, generation }` identities.
- Host runtime nodes use generated `HostNodeId { index, generation }` identities.
- Unkeyed children have position semantics; `.key(...)` gives stable list identity.
- Application pages do not construct `UiScope`, `UiRenderContext`, or render IDs.
- Stale State setters and async results cannot recreate an unmounted component generation.

## Required verification

Run from the `native` workspace:

```powershell
cargo fmt --all --check
cargo test -p lgui --no-default-features --quiet
cargo test -p lgui --all-features --quiet
cargo check -p liugc --bin liugc
cargo test -p liugc --bin liugc frontend:: --quiet
cargo check -p lgui-showcase --all-features
```

Then run `git diff --check` from the repository root. Architecture scans must find no compatibility
markers, deprecated allowances, old `cx.component` calls, business `ui_dispatcher` calls, or Core
dependencies on platform/application modules.