MoonLiveBuiltins light
Source:
MoonLiveBuiltins_light.h
AddControlSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:355Public Attributes¶
AddControlFn fn = nullptr
void * ctx = nullptr
AddLightSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:344PER-THREAD, not one global: the sink belongs to whichever thread is running a script, and more than one does.
A layout is asked for its light count and its coordinates from the HTTP task when a control is edited, while the render task walks the same layout for the frame: as one global, one thread cleared the sink while the other was mid-run and the built-in called through a live function pointer with a null context. That is a null dereference on the render core, seen as an intermittent crash while resizing a scripted layout.
Keyed on platform::currentThreadId() rather than C++ thread_local, which is UNUSABLE on the ESP32: the compiler reaches TLS through the THREADPTR special register, and a FreeRTOS task created without TLS has THREADPTR = 0: so the access dereferences a small offset from null and dies inside the exception handler. Measured: EXCVADDR 0xfffffff0, Double exception in _xt_context_save, on every scripted LAYOUT (the only binding whose script calls a host function). Reading the task handle costs one load and needs no per-task setup.
The function and the context are ONE struct so they cannot be observed half-updated. Two slots: the render task and whichever task edits a control are the two that ever run a script at once, and a third would mean a genuinely new concurrency story rather than a bigger table.
Public Attributes¶
AddLightFn fn = nullptr
void * ctx = nullptr
CoordSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:381Public Attributes¶
CoordFn fn = nullptr
void * ctx = nullptr
FadeSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:363Public Attributes¶
FadeFn fn = nullptr
void * ctx = nullptr
FlowSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:411The trail plane a script advects and decays, and the frame's dt.
A data handle rather than a function sink, for PoolSink's reason: the script names a flow and a persistence, and the BINDING owns the two planes, their geometry and the ping-pong between them. Framerate independence is the system's property too: dtMs arrives here rather than being asked of the script, so a script author cannot get it wrong and a slow frame cannot skip the decay.
Public Attributes¶
uint16_t * a = nullptr
: one of the two planes, three uint16 per light
uint16_t * b = nullptr
: the other; which one holds the trail is front
bool * front = nullptr
: Points at the BINDING's own flag, so a script's advect calls flip the owner's state directly.
const uint32_t * frame = nullptr
: the binding's frame counter, for fieldRate
lengthType w = 0
lengthType h = 0
lengthType d = 0
uint32_t dtMs = 0
Public Methods¶
inline uint16_t * live() const
inline uint16_t * spare() const
MotionSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:390Public Attributes¶
MotionFn fn = nullptr
void * ctx = nullptr
PalSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:386Public Attributes¶
PalFn fn = nullptr
void * ctx = nullptr
PoolSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:403Public Attributes¶
particles::Pool * pool = nullptr
uint32_t scale =
PoolSizeSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:402Public Attributes¶
PoolSizeFn fn = nullptr
void * ctx = nullptr
TrailSizeSink¶
src/light/moonlive/MoonLiveBuiltins_light.h:399Public Attributes¶
TrailSizeFn fn = nullptr
void * ctx = nullptr
SinkSlot¶
src/light/moonlive/MoonLiveBuiltins_light.h:433Public Attributes¶
std::atomic< uintptr_t > owner {0}
AddLightSink sink
draw::Canvas canvas
AddControlSink controls
FadeSink fade
MotionSink motion
CoordSink coord
PalSink pal
PoolSizeSink poolSize
PoolSink pool
FlowSink flow
TrailSizeSink trailSize