Scheduler
Source:
Scheduler.h
Scheduler¶
src/core/module/Scheduler.h:37The domain-neutral orchestrator: it owns the top-level modules, boots them, and drives every tick.
It also carries the tree-walk utilities, so deleting a subtree and uniquifying a name live once. The bodies are in Scheduler.cpp, and the boot phases are documented there.
Public Methods¶
inline void setLoadAllHook(LoadAllFn fn)
: Install the hook that overlays persisted values onto bound variables before any setup runs.
inline void setReapplyValuesHook(LoadAllFn fn)
: Install the hook that reapplies values once, after the first rebuild.
inline void setNoteDirtyHook(NoteDirtyFn fn)
: Install the hook that schedules a debounced save after a control mutation.
void addModule(MoonModule * mod)
: Register a top-level module, which the boot then walks in declared order.
void setup()
: Run the boot phases over every registered module.
void tick()
: One pass: tick every top-level module, then pace and publish the timing.
void release()
: Release every module, in reverse of the order they were added.
uint32_t elapsed() const
: Milliseconds since setup, which is the clock every effect animates against.
void prepareTree()
: Rebuild derived state across the whole tree, immediately, on the calling thread.
inline void requestPrepareTree()
: Ask for a rebuild at the next frame boundary, which is safe from any task.
inline void requestValuesReapply()
: Ask for a values-only reapply right after the next requested rebuild.
inline uint32_t tickTimeUs() const
: Average microseconds per tick over the last second, which is the primary performance metric.
inline uint32_t fps() const
: Frames a second, derived from the tick time above.
inline uint8_t moduleCount() const
: How many top-level modules are registered.
inline MoonModule * module(uint8_t i) const
: One top-level module by index, or null past the end.
void ensureUniqueName(MoonModule * mod)
: Make this module's name unique across the tree, the caller having placed it there already.
void deduplicateNamesInTree()
: Disambiguate every duplicated name in the tree, the first occurrence keeping its own.
MoonModule * firstByName(const char * name)
: The first module in tree-walk order with this name, or null.
SetControlResult setControl(const char * moduleName, const char * controlName, const char * valueJson)
: Set one control by module and control name, applying the whole control-change reaction.
bool getControl(const char * moduleName, const char * controlName, uint8_t & out) const
: Read one control as a byte, in the units a surface speaks, or false when there is none.
bool getControlWide(const char * moduleName, const char * controlName, int32_t & out) const
: Read one control at its own width, signed, or false when there is no numeric reading.
Public Static Methods¶
static void deleteTree(MoonModule * mod)
: Release and delete a whole subtree, children first.
static inline Scheduler * instance()
: The single live Scheduler, reachable so a factory-created module can drive a control.
Public Types¶
enum SetControlResult
: What setControl did, which each transport maps onto its own status codes.
| Value | Description |
|---|---|
Ok |
|
ModuleNotFound |
no module with that name in the tree |
ControlNotFound |
module exists but has no such control |
OutOfRange |
numeric value outside the control's bounds |
Malformed |
value didn't parse |
ReadOnly |
tried to write a display-only control |
using LoadAllFn = void()(Scheduler )
: The persistence hook's type, kept as a function pointer so Scheduler needs no include.
using NoteDirtyFn = void(*)()
: The dirty hook's type, the same decoupling as the load hook above.
More info¶
Three cadences cover every module¶
tick is the hot path, paced here by yielding between iterations, and two slower ticks follow it. Every top-level module ticks inline in one loop, and each drives its own children. Effects animate off a synchronized clock, so their speed holds at any frame rate.
Rebuilding derived state¶
A rebuild walks the tree, rebuilding buffers, mappings and any compiled script. prepareTree does it immediately and requestPrepareTree at the next frame boundary. Prefer the request: the immediate walk runs compiled code on the calling task's stack. A values-only reapply can follow it, for controls a script declares as it compiles.
Driving one control from anywhere¶
setControl names a module and a control, and applies the whole control-change reaction. It parses, rebuilds the control list, fires the hook, marks dirty, and rebuilds the tree. getControlWide reads at the control's own width, and getControl converts that to a byte. Clamping suits a surface and breaks arithmetic, so an input mapping reads the wide one.