Core supporting modules¶
The core machinery the UI modules lean on — not directly user-facing, so no controls of their own. Each row links to its generated technical page (the full API, from the .h) and its tests. Cross-file design rationale that no single .h owns lives in the prose sections below the table.
| Name | Preview | Controls | Links |
|---|---|---|---|
| Control A named, typed value a MoonModule exposes to the UI — the binding between a class variable and its web-UI widget, DMX channel, and persisted value. Every module's controls_ is a list of these. |
— | — | Tests Technical |
| Scheduler Orders module setup() by declared init-order dependencies (WiFi before HTTP, HTTP before WebSocket) and drives the per-tick tick() sweep. The one place init-order lives, so modules declare a dependency instead of hard-coding boot sequence. |
— | — | Tests Technical |
| MoonModule The base class every module derives from — the shared lifecycle ( setup / tick / release), the controls_ list, child propagation, and the self-reporting footprint (classSize / dynamicBytes / tickTimeUs). Learn the pattern once, apply it everywhere. |
— | — | Tests Technical |
| Filesystem The persistence engine: writes control values to /.config/*.json and restores them on boot, overlaying loaded values through each control's pointer during defineControls(). A non-UI module (renders no card); its "last saved" status is surfaced by the File Manager. The home of the no-reboot live-reconfiguration behaviour (see below). |
— | — | Tests Technical |
Persistence and dynamic rebuild¶
Control values persist via FilesystemModule, which overlays loaded values through each control's variable pointer during defineControls(). Calling defineControls() again at runtime (e.g. when a Select changes mode) clears and rebuilds the set, so only the controls relevant to the current mode show — this is how a control's conditional hidden flag re-evaluates. The rebuild sweep is also how a config change applies live, with no reboot.