The framework
Vel's reactive widget substrate — Signal, Widget, App, EventDispatcher.
The framework is everything in framework/ — the layer between the rendering engine (Lume) and the opinionated component set (Vel UI).
It owns:
- Reactive primitives —
Signal<T>,Computed<T>,AsyncSignal<T>,PersistentSignal<T>, plus the effect plumbing. - The widget tree —
Widget(base class), measure/place/paint/tick lifecycle, parent/child pointers. - Layout primitives —
Box,Flex,Stack,Grid,Text,ScrollView,VirtualList,Splitter. - The App loop — GLFW window, event loop, theme management, hot-reload plumbing.
- EventDispatcher — hit-testing, focus, keyboard, drag capture that survives signal-driven rebuilds.
- Non-rendering substrate —
Net,Io,Router,Storage,Time,Validate,Notify.
Dependency direction
registry → framework → engine
A framework/ source file may include engine/ headers. The reverse is forbidden — engine/ is a self-contained renderer and knows nothing about widgets.
Widget lifecycle
Every widget passes through five phases each frame:
- measure — receives
BoxConstraints, returns intrinsicSize. - place — receives final
Rect, places children. - paint — receives a
Painter, draws. - tick — receives
Δt, advances animations. - handleEvent — receives an event from
EventDispatcher.
If nothing called markDirty() and no animations are running, the frame short-circuits at the global frameDirty flag and the entire pipeline is skipped. The app sits in glfwWaitEventsTimeout at ~0 CPU until something actually changes.
Cross-references
- Signals & reactivity — the reactive contract in detail.
- Recipes › Hot reload — how
dlopenplus state preservation work. - Lume — the renderer this framework talks to via
vel::Painter.