PreviewDriver
Source:
PreviewDriver.h
PreviewDriver¶
src/light/drivers/PreviewDriver.h:42Inherits:
DriverBase
Streams a true-shape 3D preview to the web UI over the binary WebSocket.
The preview is a POINT LIST, not a dense grid: only the real lights are sent, at their real (x,y,z) positions. This is the proven MoonLight model (virtual grid → physical sparse lights; positions sent once at mapping time, channels per frame). Two message types — PreviewDriver owns both wire formats; the HTTP server is a domain-neutral BinaryBroadcaster that just writes the bytes: 0x03 coordinate table (sent when the geometry changes — every LUT/layout rebuild via prepare — and when a new client connects, so a refresh gets it; never per-frame): [0x03][count:u32][bx:u8][by:u8][bz:u8][stride:u16][(x,y,z):u8×3 × count] bx/by/bz = bounding-box extent (for client centring); positions are 1 byte/axis (a layout box ≤255/axis is the realistic case). count is u32 so a >65535-light panel (big ArtNet/HUB75 walls) isn't capped by the wire format — it matches nrOfLightsType (u32 on PSRAM boards).
0x02 per-frame channels: [0x02][count:u32][stride:u16][(r,g,b) × count] RGB by driver index, every stride-th light. The browser positions triple i at coord-table entry i*stride. count is the number of points actually kept after lattice downsampling (the lights whose position satisfies pos ≡ 0 mod stride) — a client sizes its buffer from this count, not from the light total. stride rises above 1 only when the point set would exceed the runtime send-buffer cap (min(display, memory)); below the cap every light is sent (stride 1), so a sparse layout streams in full.

Public Attributes¶
uint8_t fps = 24
: Preview stream rate (Hz), independent of render FPS.
Public Methods¶
virtual inline bool userEditable() const override
: The 3D preview the web UI renders streams from this driver.
inline void setBroadcaster(BinaryBroadcaster * b)
: Set the sink each message is pushed to (HttpServerModule, as a BinaryBroadcaster).
inline void setResumableFramesForTest(bool on)
: Test-only: flip the resumableFrames A/B directly (production toggles it through the control + affectsPrepare path).
virtual inline bool hasCorrectionControls() const override
: Preview shows the raw logical buffer, no correction.
virtual inline void defineDriverControls() override
: Bind the controls: fps (1-60) and resumableFrames (the downsampled-frame transport A/B).
virtual inline void setSourceBuffer(Buffer * buf) override
: Point the driver at the sparse driver buffer the LED/ArtNet drivers also read (the MappingLUT fills it with exactly the real lights).
virtual inline void prepare() override
: A rebuild (layout add/replace/remove, resize, modifier change) ran — the light set / positions may have changed, so rebuild + broadcast the coordinate table (the MoonLight "positions once at mapping time").
virtual inline void release() override
: Clear every shared status string on release — fail buffer, config error, and config warning — so a stopped driver leaves nothing behind (frees the owned failBuf_; retracts the warning the same "clear only MY status" way as the error), then chain to MoonModule::release() so any ScratchBuffer the driver holds frees on disable and children recurse.
virtual inline bool affectsPrepare(constchar * name) const override
: The resumableFrames A/B flips the transport AND which buffers exist, so a change re-runs prepare (which allocates them when ON, frees them when OFF) — the standard "config change applies live" path, off the render thread.
virtual inline void tick() override
: Per-tick: (re)stream the coordinate table when the geometry or client set changed, then stream one color frame if the previous one finished draining.
inline void buildAndSendCoordTable()
: Build (or rebuild) the cached coordinate table from the layout's real lights and broadcast it (the 0x03 message).
inline bool sendFrame()
: Stream one per-frame 0x02 RGB message straight from the producer buffer — no intermediate copy.