cvkg-core
Purpose
cvkg-core is the foundational crate of the CVKG (Cyber Viking Kvasir Graph) framework. It defines the core view system, rendering abstraction, reactive state primitives, layout engine, and type system that every other crate in the workspace depends on.
The crate provides:
- The
Viewtrait — the composable building block for all UI elements - The
Renderertrait — the abstract drawing backend interface State<T>andBinding<T>— reactive state management with STM-backed transactionsColor,Rect,Size,SizeProposal— geometric and color primitivesKvasirId— process-unique identity type shared across scene, VDOM, and flow cratesLayoutCacheandLayoutView— layout engine integrationAnyView,MemoView,ModifiedView<V, M>— type erasure, memoization, and modifier composition
Boundaries
cvkg-core contains no platform code, no GPU calls, and no text shaping implementation. It defines interfaces and data types only. Platform backends (native, GPU, software, WASM) live in downstream crates such as cvkg-render-native, cvkg-render-gpu, and cvkg-render-software.
The crate is split into these modules:
| Module | Contents |
|---|---|
asset |
AssetKey, AssetState, TokenValue, DesignTokens |
dependency |
DependencyGraph, FrameBudgetTracker, SubsystemBudget, InputLatencyTracker |
error_boundary |
ComponentErrorState, ErrorBoundary |
knowledge |
AnnouncementPriority, KnowledgeFragment, KnowledgeId, AppState, MemoryLayer, UiFidelityLevel, TemporalEdge, TemporalNode |
renderer |
Sub-traits: RendererCore, RendererShapes, Renderer3D, RendererText, RendererImages, RendererEffects, RendererClipping, RendererTransforms, RendererOpacity, RendererBerserker, RendererCyberpunk, RendererCompute, RendererVolumetric, RendererAccessibility, RendererTelemetry, RendererVDOM, RendererZIndex, RendererLayoutDebug, RendererPointer, RendererMaterial, RendererDataViz, RendererVectorGraphics, RendererExport |
undo |
UndoGroup, UndoManager |
virtual_list |
Virtualized list view support |
window |
Window, WindowCloseAction, WindowConfig, WindowHandle, WindowId, WindowLevel |
Re-exports from future_views: HologramView, ParticleEmitter, StreamingText.
Dependency graph
graph TD
cvkg_core[cvkg-core]
cvkg_runic_text[cvkg-runic-text]
glam[glam]
serde[serde]
serde_json[serde_json]
tokio[tokio]
arc_swap[arc-swap]
bytemuck[bytemuck]
log[log]
once_cell[once_cell]
stl_io[stl_io]
tobj[tobj]
thiserror[thiserror]
anyhow[anyhow]
stm[stm\n<!-- native only -->]
rfd[rfd\n<!-- native only -->]
wasm_bindgen[wasm-bindgen\n<!-- wasm32 only -->]
wasm_bindgen_futures[wasm-bindgen-futures\n<!-- wasm32 only -->]
js_sys[js-sys\n<!-- wasm32 only -->]
getrandom[getrandom\n<!-- wasm32 only -->]
cvkg_core --> cvkg_runic_text
cvkg_core --> glam
cvkg_core --> serde
cvkg_core --> serde_json
cvkg_core --> tokio
cvkg_core --> arc_swap
cvkg_core --> bytemuck
cvkg_core --> log
cvkg_core --> once_cell
cvkg_core --> stl_io
cvkg_core --> tobj
cvkg_core --> thiserror
cvkg_core --> anyhow
cvkg_core --> stm
cvkg_core --> rfd
cvkg_core --> wasm_bindgen
cvkg_core --> wasm_bindgen_futures
cvkg_core --> js_sys
cvkg_core --> getrandom
Reverse dependents (crates that depend on cvkg-core): cvkg, cvkg-scene, cvkg-layout, cvkg-anim, cvkg-render-native, cvkg-render-gpu, cvkg-render-software, cvkg-telemetry, cvkg-compositor, cvkg-cli, cvkg-svg-serialize, cvkg-svg-filters, cvkg-webkit-server, cvkg-components, cvkg-icons, cvkg-themes, cvkg-macros, cvkg-runic-text (dev), cvkg-test, cvkg-physics, cvkg-flow, cvkg-scheduler, cvkg-spatial, cvkg-reflect, cvkg-materials, cvkg-accessibility, cvkg-certification, cvkg-gallery, cvkg-game-hud, cvkg-export-raster, and all demo crates.
Public API overview
Core traits
View — the composable UI building block. Every view has a Body type, a body() method, and a render() method. Primitive views use Never as Body and register paint commands directly. The trait provides default modifier methods (background, padding, opacity, frame, flex, border, elevation, on_click, etc.) that wrap self in ModifiedView<Self, M>.
Renderer — the abstract rendering backend. Requires ElapsedTime + Send. Provides methods for filled/stroked shapes, text, images, glass materials, squircles, focus rings, 3D cubes, and polygons. Default implementations are provided for most methods; backends override the ones they support.
ViewModifier — the modifier protocol. Each modifier wraps a View into a ModifiedView<V, M> and can intercept rendering, layout proposals, and size transformations.
LayoutView — for views that participate in the layout engine.
Key types
| Type | Description |
|---|---|
State<T> |
Reactive state container. Uses ArcSwap<T> for lock-free reads and stm::TVar<T> (native only) for atomic multi-field transactions. Supports conflict resolution, subscriber notifications, and batched updates. |
Binding<T> |
Read/write handle derived from State<T>. Does not own subscribers. Created via Binding::from_state(&state). |
Color |
RGBA color with components in [0.0, 1.0]. Provides named constants (BLACK, WHITE, RED, VIKING_GOLD, TACTICAL_OBSIDIAN, etc.), from_hex, lighten, darken, relative_luminance, and contrast_ratio (WCAG 2.x). Implements View (fills a rect). |
Rect |
Axis-aligned rectangle with x, y, width, height. Methods: new, inset, offset, zero, contains, intersects, size, split_horizontal, split_vertical. |
Size |
Two-dimensional size with width and height. Constant ZERO. |
SizeProposal |
Optional width/height proposal from a parent view during layout. |
KvasirId |
Process-unique identifier (pub struct KvasirId(pub u64)). Allocated via KvasirId::new() (atomic increment). Sentinel KvasirId::NULL (0). Used as NodeId across cvkg-scene, cvkg-vdom, and cvkg-flow. |
LayoutCache |
Per-frame layout context. Contains safe area insets, delta time, scale factor, viewport, time budget, size cache, parent map, generation counter, and previous rects for transitions. |
AnyView |
Type-erased View wrapper. Requires V: View + Clone + 'static. Created via view.erase() or AnyView::new(view). |
MemoView<V, F> |
Memoizing view wrapper. Skips re-rendering when data_hash is unchanged. |
ModifiedView<V, M> |
A View wrapped by a ViewModifier. |
Never |
Uninhabitable enum (pub enum Never {}). Used as Body for primitive views. |
EmptyView |
A view that renders nothing and has zero intrinsic size. |
GridPlacement |
Grid cell assignment: column, column_span, row, row_span. |
Alignment |
Cross-axis alignment: Center, Leading, Trailing, Top, Bottom. |
Distribution |
Main-axis distribution: Fill, Center, Leading, Trailing, SpaceBetween, SpaceAround, SpaceEvenly. |
EdgeInsets |
Padding/margin insets: top, leading, bottom, trailing. |
SafeArea |
Platform safe area insets. |
AriaRole |
WCAG 2.1 semantic role enum (52 variants). |
AriaProperties |
Accessibility metadata: role, label, description, value, pressed, checked, expanded, disabled, hidden, level, shortcut, focused, live, atomic. |
FocusableId |
Opaque focus target identifier. |
FocusManager |
Tab-order management with focus trap support. |
KeyModifiers |
Keyboard modifier flags: shift, ctrl, alt, meta. |
KeyShortcut |
Keyboard shortcut binding with description. |
DesignTokens |
Yggdrasil design token tree. |
AssetKey, AssetState |
Asset loading key and state. |
ErrorBoundary, ComponentErrorState |
Error boundary for view subtrees. |
UndoManager, UndoGroup |
Undo/redo stack. |
Window, WindowConfig, WindowHandle, WindowId, WindowLevel, WindowCloseAction |
Window management types. |
Renderer sub-traits
The Renderer trait aggregates all rendering capabilities. The renderer/ module splits these into fine-grained sub-traits so consumer code can depend on only the slice it needs:
| Sub-trait | Capability |
|---|---|
RendererCore |
request_redraw, is_over_budget |
RendererShapes |
2D filled/stroked primitives |
Renderer3D |
Cubes, meshes |
RendererText |
Text drawing, measurement, shaping |
RendererTextExt |
draw_text_centered (blanket impl) |
RendererImages |
Textures, image loading, VRAM prewarm |
RendererDataViz |
Heatmaps, data textures |
RendererVectorGraphics |
SVG loading and drawing |
RendererEffects |
Gradients, shadows, 9-slice, dashed strokes |
RendererClipping |
Clip-rect stack |
RendererTransforms |
2D affine transform stack |
RendererOpacity |
Opacity stack |
RendererBerserker |
Theme, rage, shatter, scene presets |
RendererExport |
PNG capture, print |
RendererCyberpunk |
Bifrost, Gungnir, Mani, Mjolnir, memoize |
RendererCompute |
GPU particle dispatch |
RendererVolumetric |
Holograms, raymarching |
RendererAccessibility |
ARIA, shared elements, keys |
RendererTelemetry |
Frame budget / performance data |
RendererVDOM |
Virtual-DOM node tracking, handler registration |
RendererZIndex |
Depth ordering |
RendererLayoutDebug |
Layout query / visualization |
RendererPointer |
Mouse / touch position query |
RendererMaterial |
Draw call routing for multi-pass pipeline |
Usage example
use ;
// Define a simple view
// Create reactive state
let state = new;
let binding = from_state;
// Build the view with modifiers
let view = CounterView
.background
.padding
.on_click;
// Type-erase when needed
let erased = view.erase;
Use cases
- Declarative UI composition — Build view trees using the
Viewtrait and modifier chain. Every UI element from a text label to a navigation controller is aView. - Cross-platform rendering — Implement
Rendereronce per backend (native, GPU, software, WASM). The trait provides default no-op implementations for most methods so backends only override what they support. - Reactive state management — Use
State<T>for shared mutable state with lock-free reads, STM-backed multi-field transactions (native), conflict resolution, and subscriber notifications. - Type erasure — Use
AnyView(viaview.erase()) when you need to store heterogeneous views in a collection or pass them across API boundaries. - Memoization — Wrap expensive subtrees in
MemoView::new(id, data_hash, || view)to skip re-rendering when data hasn't changed. - Accessibility — Implement
aria_properties()on your views and useFocusManagerfor keyboard navigation. TheAriaRoleenum covers all WCAG 2.1 roles. - Layout — Implement
LayoutViewfor custom layout containers. UseLayoutCachefor caching, budget enforcement, and transition tracking. - Shared element transitions — Use
bifrost_bridge(id)modifier to mark views that should animate geometry across view hierarchy changes.
Edge cases and limitations
Neveris uninhabitable — Primitive views useNeveras theirBodytype. Callingbody()on them isunreachable!(). This is a compile-time guarantee enforced by the type system, not a runtime check.State<T>requiresT: Clone + Send + Sync + 'static— TheClonebound is needed becauseget()returns a fresh copy. The'staticbound is required for subscriber storage.- STM transactions are native-only — On
wasm32,State::set()andState::mutate()fall back toArcSwap-only updates without atomic multi-field coordination.transact_pairis not available on WASM. Binding<T>does not own subscribers — It is a lightweight handle derived fromState<T>. Subscribers are attached to theState, not theBinding.AnyViewrequiresClone— Type erasure viaerase()requiresSelf: Clone + 'staticbecauseErasedView::clone_boxneeds to clone the inner value.Viewtypes must beSendbut notSync— This enables safe multi-threaded layout passes but means views cannot be shared between threads via&dyn View.changed()defaults totrue— For backward compatibility,View::changed()andLayoutView::changed()returntrueby default. Override to returnfalsefor static subtrees to enable incremental skip in the VDOM and layout engine.view_id()defaults toNone— Anonymous views returnNone. ReturnSome(id)for stable identity across VDOM rebuilds, enabling handler survival and incremental patch generation.- Renderer default implementations are no-ops or fallbacks — Most
Renderermethods have default implementations (e.g.,fill_squirclefalls back tofill_rounded_rect). Backends must override methods to get correct behavior. - No feature flags —
cvkg-corehas no Cargo features. All functionality is always enabled. - No environment variables — The crate reads no environment variables at build time or runtime.
Build flags / features / env vars
cvkg-core defines no Cargo features and reads no environment variables. The crate is always built with its full API surface.
Platform-specific dependencies are handled via standard Cargo target filters:
cfg(not(target_arch = "wasm32"))—stm(software transactional memory),rfd(native file dialogs)cfg(target_arch = "wasm32")—wasm-bindgen,wasm-bindgen-futures,js-sys,getrandom(withwasm_jsfeature)