Skip to content

PreviewModule

Owns the WebSocket pixel preview for any DriverLayer or ProducerModule source. Introduced in Release 5, Sprint 1 as the sole snapshot() owner in the pipeline — replacing the old fragile scan over all modules.


What it does

On each loop() call, PreviewModule calls source->pixelBuf() to obtain a raw RGB pointer and source dimensions, then packs the data into a 0x02 wire frame cached in an internal vector<uint8_t>. snapshot() returns that cache. ModuleManager::pixelSnapshot() locates it by name ("PreviewModule") and forwards the frame to WebSocket clients for the WebGL preview.

Wire frame format:

[0x02] [w_lo][w_hi] [h_lo][h_hi] [d_lo][d_hi] [R G B …]
 1 B       2 B          2 B          2 B        w×h×d×3 B

Source geometry (w, h, d) is always taken from pixelBuf(), not from the controls. Controls are virtual-grid hints for the frontend renderer; they do not gate the preview.


Controls

Key Type Range Default Description
width slider 1–512 0 (auto) Virtual grid width hint for frontend
height slider 1–512 0 (auto) Virtual grid height hint for frontend
depth slider 1–64 1 Virtual grid depth hint for frontend
logEveryN slider 1–1000 0 (off) Log checksum every N ticks (0 = silent)

source is a data-flow input wired via setInput("source", m) — typically a DriverLayer.


Wiring example

{ "id": "preview1", "type": "PreviewModule",
  "inputs": { "source": "driver1" },
  "props": { "width": 16, "height": 16, "logEveryN": 100 } }

Footprint

classSize() returns sizeof(PreviewModule) (~72 B on ESP32). heapSize() returns the capacity of snapBuf_ — for a 16×16×1 grid: 7 + 768 = 775 B.


Source

Test coverage

Wire frame header (type byte, little-endian dimensions, payload size), non-zero pixel values after SineEffectModule runs, snapshot() returns false before first loop(), ModuleManager::pixelSnapshot() routing, checksum consistency with DriverLayer::readyChannel().