Skip to content

Code Analysis

Auto-generated by deploy/codeanalysis.py. Do not edit manually. Generated: 2026-05-08 10:51

Column Descriptions

Column What it measures 🟡 amber threshold 🔴 red / CI-fail threshold
LOC Non-comment lines of code (lizard NLOC) > 150 > 400 (modules), > 800 (core)
Fns Number of functions / methods
Max CC Highest cyclomatic complexity across all functions > 10 > 25 (modules), > 60 (core)
Static RAM BSS + data bytes from firmware.map; non-zero means a static/global member exists > 0 > 512 B (modules), > 4096 B (core)
classSize sizeof(Derived) via CRTP: true heap cost per module instance > 300 B > 800 B
Runtime baseHeapUsage(): classSize + controls[] heap array + pendingProps_ doc. Test binary measures fresh instances (no setup called), so this equals classSize at zero controls; each registered control adds ~64 B at runtime. > 1024 B > 4096 B
Heap setup Allocation patterns (new, malloc, psram_malloc, etc.) detected in setup() and private helpers (allocate_()) any
Heap loop Allocation patterns detected in loop() body (must not allocate per tick) any
Blocking Blocking calls (delay, vTaskDelay, LOG_INFO, LOG_DEBUG) in loop() body any
Leak? Alloc keyword found in setup() with no matching free in teardown() any

Layer buffer allocations (e.g. EffectsLayer, DriverLayer) appear in Heap setup as psram_malloc (via allocate_()) — byte count is runtime-determined and not shown statically.

Legend

Indicator Meaning
🟢 Within aspirational target (LOC <= 150, CC <= 10)
🟡 Above aspirational but within CI threshold
🔴 Exceeds CI threshold (fails build)

RAM Accounting

Total .dram0.data + .dram0.bss: 31,902 B (from firmware.map; matches PlatformIO RAM report).

Origin Bytes Share
Our source (src/) 3,421 10%
External libraries (ESP-IDF, WiFi, BT, lwIP, ...) 28,481 89%

Our source breakdown:

File Bytes
src/core/Logger.cpp.o 1,549
src/core/Runtime.cpp.o 988
src/core/CoreRegistrations.cpp.o 476
src/modules/ModuleRegistrations.cpp.o 260
src/core/AppRoutes.cpp.o 72
src/core/TypeRegistry.cpp.o 32
src/core/ModuleManager.cpp.o 24
src/core/AppSetup.cpp.o 20

External library RAM is not directly reducible without disabling features (e.g. CONFIG_BT_ENABLED=n saves ~4,600 B). The only meaningful reduction within our control is the Logger ring buffer.

Notable Findings

  • Large instance size: DeviceDiscoveryModule (1344 B), FileManagerModule (968 B) — likely contain fixed char[] buffers.
  • Heap allocation in loop(): GameOfLifeEffect, PreviewModule — conditional psram_malloc on geometry resize (intentional, not a per-tick alloc).
  • High cyclomatic complexity in core: Scheduler (CC 53), ModuleManager (CC 33), StatefulModule (CC 14), AppSetup (CC 11).
  • Large core files (candidates for future splitting): ModuleManager (732 LOC), StatefulModule (583 LOC), Scheduler (391 LOC), WsServer (313 LOC), HttpServer (235 LOC), AppRoutes (232 LOC), AppSetup (179 LOC).
  • Layer buffer PSRAM allocations (EffectsLayer, DriverLayer) are runtime-sized: byte count is not shown statically. See Heap setup column for allocation presence.

Core Infrastructure

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
ModuleManager (.h+.cpp) 🟡 732 39 🟡 33 🟡 24 🟡 456 -
StatefulModule (.h) 🟡 583 66 🟡 14 0 🟢 256 -
Scheduler (.h+.cpp) 🟡 391 24 🟡 53 0 🟡 448 -
WsServer (.h) 🟡 313 27 🟢 10 0 🟢 104 -
HttpServer (.h) 🟡 235 19 🟢 9 0 🟡 792 -
AppRoutes (.h+.cpp) 🟡 232 0 🟢 0 🟡 72 - -
AppSetup (.h+.cpp) 🟡 179 8 🟡 11 🟡 20 - -
KvStore (.h) 🟢 123 16 🟢 7 0 🟡 392 -
Logger (.h+.cpp) 🟢 88 5 🟢 8 🟡 1549 - -
PhysMap (.h) 🟢 57 10 🟢 5 0 🟢 16 -
TypeRegistry (.h+.cpp) 🟢 49 6 🟢 2 🟡 32 🟢 24 -
Module (.h) 🟢 34 24 🟢 2 0 🟢 8 -
ProducerModule (.h) 🟢 31 9 🟢 4 0 🟢 280 -
Timing (.h) 🟢 24 6 🟢 3 0 🟢 32 -
Runtime (.h+.cpp) 🟢 23 4 🟢 1 🟡 988 - -
CoreRegistrations (.cpp) 🟢 19 0 🟢 0 🟡 476 - -
Coord3D (.h) 🟢 18 6 🟢 3 0 - -
ConsumerModule (.h) 🟢 11 1 🟢 2 0 🟢 264 -
OtaState (.h) 🟢 4 0 🟢 0 0 - -

Effects

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
FlowFluidEffect 🟡 315 22 🟡 14 0 🟡 384 🟢 384
GameOfLifeEffect 🟡 167 16 🟡 22 0 🟢 296 🟢 296 🔴 psram_malloc 🔴 psram_malloc
SineEffectModule 🟡 155 21 🟢 7 0 🟢 280 🟢 280
NoiseEffect2D 🟢 105 13 🟢 7 0 🟢 272 🟢 272
RipplesEffectModule 🟢 85 10 🟢 7 0 🟢 272 🟢 272
DistortionWaves2DEffect 🟢 77 10 🟢 7 0 🟢 272 🟢 272
ArtNetInModule 🟢 74 10 🟡 18 0 🟢 280 🟢 280
LinesEffectModule 🟢 64 10 🟡 17 0 🟢 272 🟢 272

Layers

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
DriverLayer 🟡 251 25 🟡 16 0 🟡 544 🟢 544 🔴 psram_malloc
EffectsLayer 🟡 232 35 🟡 12 0 🟡 360 🟢 360 🔴 psram_malloc

Layouts

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
GridLayout 🟢 100 15 🟢 7 0 🟡 320 🟢 320
XmasTreeLayout 🟢 59 10 🟢 4 0 🟢 288 🟢 288
WheelLayout 🟢 50 9 🟢 3 0 🟢 288 🟢 288
RingLayout 🟢 47 9 🟢 2 0 🟢 288 🟢 288

Modifiers

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
RotateModifier 🟢 74 11 🟢 5 0 🟢 296 🟢 296
ScrollModifier 🟢 34 7 🟢 7 0 🟢 280 🟢 280
TileModifier 🟢 28 8 🟢 4 0 🟢 264 🟢 264
MirrorModifier 🟢 27 7 🟢 7 0 🟢 264 🟢 264
CheckerboardModifier 🟢 11 5 🟢 2 0 🟢 264 🟢 264

Drivers

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
PreviewModule 🟢 118 17 🟡 13 0 🟢 296 🟢 296 🔴 psram_malloc
ArtNetOutModule 🟢 88 11 🟢 10 0 🟡 304 🟢 304 🔴 malloc

System

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
SystemStatusModule 🟢 140 7 🟢 8 0 🟡 400 🟢 400
FileManagerModule 🟢 48 7 🟢 5 0 🔴 968 🟢 968
TasksModule 🟢 36 7 🟢 4 0 🟡 776 🟢 776
FirmwareUpdateModule 🟢 24 5 🟢 1 0 🟡 328 🟢 328

Network

Name LOC Fns Max CC Static RAM (B) classSize (B) Runtime (B) Heap setup Heap loop Blocking Leak?
DeviceDiscoveryModule 🟢 116 12 🟡 12 0 🔴 1344 🟡 1344
EthernetModule 🟢 101 11 🟢 8 0 🟡 368 🟢 368
WifiStaModule 🟢 98 8 🟢 10 0 🟡 416 🟢 416
NetworkModule 🟢 80 9 🟡 14 0 🟡 352 🟢 352
WifiApModule 🟢 64 9 🟢 5 0 🟢 296 🟢 296