Extending the System
This page collects the most common extension points: firmware processes/commands, new client apps, and new Hitloop game scenes.
Extending the Firmware
The firmware is process-driven (include/processes/*.h, src/*.cpp) and uses a shared CommandRegistry.
flowchart TD
subgraph Main Loop
PM["ProcessManager.updateProcesses()"]
end
subgraph Processes
CFG["ConfigurationProcess"]
WIFI[WiFiProcess]
BLE[BLEProcess]
IMU[IMUProcess]
LED[LedProcess]
VIB[VibrationProcess]
PUB[PublishProcess]
RX[ReceiveProcess]
end
subgraph IO
WS[WebSocketManager]
CR[CommandRegistry]
end
PM --> CFG & WIFI & BLE & IMU & LED & VIB & PUB & RX
RX --> CR
CR --> Processes
PUB --> WS
Add a Process
- Create
include/processes/MyProcess.handsrc/MyProcess.cppderiving fromProcess. - Implement
setup()andupdate(); guard work withif (!isProcessRunning()) return;. - In
setup()add any callbacks (e.g., register command handlers, attach to timers). - Register the process in
src/main.cpp: - Start/stop via
processManager.startProcess("myProcess")orhaltProcess(...).
Keep setup idempotent
ProcessManager.setupProcesses() runs once during boot. Avoid side effects that assume other processes are already running—check dependencies explicitly.
Add a Command
- In the relevant process (or globally in
registerGlobalCommands()), callcommandRegistry.registerCommand("name", handler);. - Handlers receive a
String parameterssegment (everything aftercmd:<id>:<command>:). - Validate and act; log failures with
Serial.printlnfor clarity. - If the command toggles LEDs or vibration, also update local state so subsequent status prints are accurate.
sequenceDiagram
participant App as Browser
participant WS as Socket Server
participant FW as Firmware
participant CR as CommandRegistry
App->>WS: cmd:1a2b:led:FF0000
WS-->>FW: cmd:1a2b:led:FF0000
FW->>CR: execute("led","FF0000")
CR-->>FW: handler runs (updates LED process)
Adding a New Client Application
Each app lives under client-hub/app/static/apps/<name>.
- Create a folder with
index.htmlplus any JS/CSS/assets. - Link assets relatively (
./client.js,./style.css). Shared libs are at/static/vendor/js/. - Optionally add a
README.md; it is rendered on the landing page card. - Restart
client_hub(ordocker compose up client_hub) — the landing page auto-discovers the new folder. - Access at
http://localhost:5004/apps/<name>/.
Config injection
/config.js exposes window.APP_CONFIG with wsDefaultUrl, cdnBaseUrl, and appsBaseUrl. Use it to avoid hardcoding endpoints.
Adding a Hitloop Games Scene
Scenes live in client-hub/app/static/apps/hitloop-games/scenes/ and inherit from Scene.
- Create
scenes/MyScene.js: - Register it in
sketch.js: - Use
this.deviceManagerto read live device data: - Implement
drawDebugText()and toggle with thedkey when you need on-screen diagnostics.
flowchart LR
DM[HitloopDeviceManager]
SM[SceneManager]
SCN[MyScene]
DM --> SM
SM --> SCN
SCN -->|render| Canvas
SCN -->|commands| DM
Pruning behavior
HitloopDeviceManager prunes devices after 5 seconds of silence. If you simulate devices, send frames at least every 5 seconds to avoid auto-removal.