Added CLAUDE.md
This commit is contained in:
69
CLAUDE.md
Normal file
69
CLAUDE.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Build the entire workspace
|
||||
cargo build
|
||||
|
||||
# Run a specific example (all live in lib/ruin_app/example/)
|
||||
cargo run --example 00_bootstrap_and_counter -p ruin_app
|
||||
cargo run --example 01_async_data_and_effects -p ruin_app
|
||||
cargo run --example 03_fine_grained_list -p ruin_app
|
||||
|
||||
# Run tests
|
||||
cargo test
|
||||
|
||||
# Run tests for a specific crate
|
||||
cargo test -p ruin_reactivity
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
RUIN is a layered, single-threaded reactive UI framework targeting Linux/Wayland. The layers build on each other strictly from bottom to top:
|
||||
|
||||
### Layer Stack
|
||||
|
||||
**`ruin-runtime`** (`lib/runtime/`) — Linux x86_64 async runtime. io_uring-backed I/O, single-threaded event loop with JavaScript-style microtask/macrotask scheduling. Entry points are `#[ruin_runtime::async_main]` and `#[ruin_runtime::main]` macros. Provides `fs::*`, `net::*`, `time::*`, `channel::*` (mpsc, oneshot).
|
||||
|
||||
**`ruin_reactivity`** (`lib/reactivity/`) — Fine-grained reactive graph. Key primitives: `Cell` (root signal), `Thunk`/`Memo` (derived values), `Effect` (side-effects), `Event` (subscriptions). The reactor is single-threaded and schedules deferred jobs via the runtime's microtask queue. No async inside the reactive graph — async work feeds results in via state updates at the edges.
|
||||
|
||||
**`ruin_ui`** (`lib/ui/`) — Platform/renderer-agnostic UI substrate. Intentionally uses explicit Rust construction (no proc-macros at this layer). Key modules: `layout.rs` (flexbox-style layout engine), `text.rs` (cosmic-text integration), `scene.rs` (display list/scene graph), `interaction.rs` (pointer/keyboard routing), `platform.rs` (platform abstraction traits), `tree.rs` (element tree and styling).
|
||||
|
||||
**`ruin_ui_platform_wayland`** (`lib/ui_platform_wayland/`) — Wayland backend. Entry point: `start_wayland_ui()`. Handles window creation, input events, clipboard via wayland-client + wgpu renderer.
|
||||
|
||||
**`ruin_ui_renderer_wgpu`** (`lib/ui_renderer_wgpu/`) — GPU rendering via wgpu. Text rasterization with cosmic-text.
|
||||
|
||||
**`ruin_app`** (`lib/ruin_app/`) — High-level app/runtime glue. This is the crate most application code targets. Exports `App`, `Window`, `Mountable`, and the proc-macros `#[component]`, `view!`, `#[context_provider]`. **Intentionally low-level** — it is the expansion target for proc-macros, not the final ergonomic API.
|
||||
|
||||
**`ruin_app_proc_macros`** (`lib/ruin_app_proc_macros/`) — Procedural macros: `#[component]` wraps component functions, `view!` is the DSL for UI tree construction, `#[context_provider]` injects context values.
|
||||
|
||||
### Application Model
|
||||
|
||||
A typical app entry point:
|
||||
|
||||
```rust
|
||||
#[ruin_runtime::async_main]
|
||||
async fn main() -> ruin_app::Result<()> {
|
||||
App::new()
|
||||
.window(Window::new().title("My App").app_id("dev.ruin.myapp").size(960.0, 640.0))
|
||||
.mount(view! { MyRootComponent() {} })
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
```
|
||||
|
||||
Components use `#[component]` and return `impl IntoView`. Reactive state uses `use_signal`, `use_memo`, `use_effect`. Layout uses `view!` with primitives like `column`, `row`, `block`, `text`, `button`.
|
||||
|
||||
### The `aspirational_examples/` Directory
|
||||
|
||||
These files (`00_` through `07_`) define the **desired future API** — a cleaner `ruin::prelude::*` surface with shorter syntax like `use_signal` instead of `use_signal(|| ...)`. They are **not wired into the build**. The corresponding **ported implementations** live in `lib/ruin_app/example/` and represent the current actual API. When porting an aspirational example, the goal is to make the example/ version match the aspirational design as closely as the current framework allows.
|
||||
|
||||
### Key Design Constraints
|
||||
|
||||
- The reactive graph is strictly single-threaded — never share reactive values across threads.
|
||||
- `Signal<T>` must be `.clone()`d before being moved into closures (it's `Rc`-based, not `Arc`).
|
||||
- All float layout values are `f32` (e.g., `gap = 8.0`, not `gap = 8`).
|
||||
- `ruin_app` is the integration target; avoid bypassing it to call `ruin_ui` or `ruin_reactivity` directly in application code unless writing low-level infrastructure.
|
||||
Reference in New Issue
Block a user