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 |
|
|
|
|