Skip to content

Conversation

@blazoncek
Copy link
Contributor

@blazoncek blazoncek commented Dec 20, 2025

  • use constants instead of magic numbers

Summary by CodeRabbit

  • New Features

    • Increased available dynamic palettes count, improving palette variety.
  • Bug Fixes

    • Fixed palette selection, indexing and bounds so correct palettes (fixed, dynamic, FastLED, gradients, custom) display and load reliably.
    • Corrected palette list pagination and page calculations for consistent palette browsing.

✏️ Tip: You can customize this high-level summary in your review settings.

- use constants instead of magic numbers
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 20, 2025

Walkthrough

Refactors palette handling: increments DYNAMIC_PALETTE_COUNT from 5 to 6, tightens and normalizes palette bounds/indexing across effect loading, JSON serialization, and a usermod by using FIXED_PALETTE_COUNT and adjusted offsets for dynamic/fastLED/gradient palette ranges.

Changes

Cohort / File(s) Summary
Palette Constants
wled00/const.h
Updated constexpr size_t DYNAMIC_PALETTE_COUNT from 5 to 6, affecting FIXED_PALETTE_COUNT calculations and related comments.
Palette Loading Logic
wled00/FX_fcn.cpp
Broadened out-of-bounds check to pal >= FIXED_PALETTE_COUNT; removed several +1 adjustments from limit checks; adjusted fastLED and gradient palette index arithmetic and switched gradient memcpy to use sizeof(tcp).
JSON Serialization / Pagination
wled00/json.cpp
Replaced runtime counts with compile-time constants; switched palette loop bounds to use FIXED_PALETTE_COUNT; adjusted pagination math (maxPage, start/end) and palette index expressions; updated fastLED/gradient palette lookups to use the new offsets.
Usermod Palette Handling
usermods/usermod_v2_rotary_encoder_ui_ALT/...
Reworked palette arrays and initialization to allocate with current palette count, insert custom palettes at FIXED_PALETTE_COUNT + i, and limit sorting to fixed palettes (legacy skip logic updated).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify index arithmetic in wled00/FX_fcn.cpp (fastLED and gradient offsets and memcpy size).
  • Confirm consistency between FIXED_PALETTE_COUNT, DYNAMIC_PALETTE_COUNT, and pagination logic in wled00/json.cpp.
  • Review usermod insertion/sorting changes to ensure custom palettes map to correct indices and UI lists.

Possibly related PRs

Suggested reviewers

  • DedeHai
  • Aircoookie

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Fix for #5201' is vague and does not clearly describe the actual changes made in the pull request. Replace with a more descriptive title that explains the main change, such as 'Replace magic numbers with palette count constants' or 'Fix palette indexing and bounds checks'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch palettes-fix

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97d3792 and acfb8b2.

📒 Files selected for processing (2)
  • wled00/FX_fcn.cpp (2 hunks)
  • wled00/json.cpp (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
wled00/**/*.cpp

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 2-space indentation for C++ source files (.cpp)

Files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
🧠 Learnings (12)
📓 Common learnings
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.
Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.949Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.
Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.
Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-15T20:25:25.807Z
Learning: The CSS palette preview in wled00/data/index.js genPalPrevCss() function uses raw RGB values in CSS linear-gradient() without applying WLED's gamma correction, while actual LED output goes through NeoGammaWLEDMethod gamma correction. This causes inherent discrepancies between the web UI palette preview and actual LED colors, especially noticeable with different gamma settings.
📚 Learning: 2025-11-14T13:37:11.994Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-08-28T08:09:20.630Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-11-14T13:37:30.955Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-12-15T20:25:25.807Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-15T20:25:25.807Z
Learning: The CSS palette preview in wled00/data/index.js genPalPrevCss() function uses raw RGB values in CSS linear-gradient() without applying WLED's gamma correction, while actual LED output goes through NeoGammaWLEDMethod gamma correction. This causes inherent discrepancies between the web UI palette preview and actual LED colors, especially noticeable with different gamma settings.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-11-16T19:40:46.260Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4926
File: wled00/FX.cpp:4727-4730
Timestamp: 2025-11-16T19:40:46.260Z
Learning: WLED AuroraWave (wled00/FX.cpp): wave_start and wave_end intentionally use int16_t; segments longer than 32k LEDs are not supported (bounded by MAX_LEDS), so widening to 32-bit is unnecessary.

Applied to files:

  • wled00/json.cpp
  • wled00/FX_fcn.cpp
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : DO NOT edit generated embedded web header files (wled00/html_*.h)

Applied to files:

  • wled00/json.cpp
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.

Applied to files:

  • wled00/FX_fcn.cpp
📚 Learning: 2025-11-27T06:33:11.436Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.

Applied to files:

  • wled00/FX_fcn.cpp
📚 Learning: 2025-09-16T18:08:42.848Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.

Applied to files:

  • wled00/FX_fcn.cpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: wled_build / Build Environments (esp32S3_wroom2)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (esp8266_2m)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (esp32S3_wroom2)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (lolin_s2_mini)
  • GitHub Check: wled_build / Build Environments (esp32dev_debug)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full)
  • GitHub Check: wled_build / Build Environments (esp8266_2m)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Build Environments (esp8266_2m_160)
  • GitHub Check: wled_build / Build Environments (nodemcuv2)
  • GitHub Check: Analyze (c-cpp)
🔇 Additional comments (9)
wled00/FX_fcn.cpp (4)

233-233: Correct fix for palette bounds check.

The change from > to >= properly excludes FIXED_PALETTE_COUNT itself from the valid range, fixing the off-by-one error. If FIXED_PALETTE_COUNT is 72, valid fixed palettes are 0-71, and palette 72 should be out of bounds.

Based on learnings, this correctly replaces magic number logic with the defined constant.


271-272: Correct fix for FastLED palette indexing.

Removing the +1 from the condition and -1 from the index calculation fixes the off-by-one error:

  • Old: pal < 14 incorrectly included palette 13 (first gradient palette) in the FastLED range
  • New: pal < 13 correctly limits to palettes 6-12 (7 FastLED palettes)
  • Index calculation now correctly maps palette 6 to index 0 and palette 12 to index 6

Based on learnings, this aligns with the PR objective to replace magic numbers with constants and fix palette indexing.


275-275: Excellent improvements to gradient palette handling.

Two improvements on this line:

  1. Index calculation fix: Removing -1 correctly maps palette 13 to gradient index 0, fixing the off-by-one error
  2. Replace magic number with sizeof(tcp): Using sizeof(tcp) instead of hardcoded 72 improves maintainability and follows coding best practices

Based on learnings, replacing the hardcoded 72 with sizeof(tcp) is exactly the type of magic number elimination requested.


227-281: Verify consistent palette constant usage across the codebase.

The palette constants are correctly defined in const.h as compile-time constants: FASTLED_PALETTE_COUNT = 7, DYNAMIC_PALETTE_COUNT = 5, GRADIENT_PALETTE_COUNT = 59, and FIXED_PALETTE_COUNT calculated from their sum. The loadPalette() function properly uses these constants for bounds checking and palette type detection.

However, consider that the setPalette() function uses GRADIENT_PALETTE_COUNT+13 where FIXED_PALETTE_COUNT would be more semantically clear, and hardcoded 245 for custom palette boundary checks. If not already done, define a constant for the custom palette boundary threshold to improve maintainability.

wled00/json.cpp (5)

947-951: Good use of constexpr for compile-time constants.

Converting itemPerPage to constexpr is a good practice that allows compile-time evaluation and better optimization.


953-954: Correct use of FIXED_PALETTE_COUNT constant.

Replacing the hardcoded palette count with FIXED_PALETTE_COUNT improves maintainability and aligns with the PR objective.

Based on learnings, this is the expected magic number replacement.


956-965: Critical fix for pagination bounds and off-by-one error.

The changes fix a boundary issue in the pagination logic:

Old logic issue:

  • Loop used i <= end (inclusive)
  • Could attempt to access index equal to total count, causing out-of-bounds access
  • Example: With 74 palettes on page 9, would try to access indices 72, 73, 74 (index 74 doesn't exist)

New logic (correct):

  • Loop uses i < end (exclusive)
  • Treats end as an exclusive upper bound
  • Example: With 74 palettes on page 9, accesses indices 72, 73 only ✓

The adjustment to maxPage calculation (removing -1) maintains correct page count while fixing the boundary logic.


966-966: Critical fix for custom palette index calculation.

The new formula correctly maps iteration indices to custom palette indices:

Old formula bug:

  • For first custom palette (i=72): returned 72 instead of 255
  • For second custom palette (i=73): returned 255 instead of 254

New formula (correct):

  • For i=72: 255 - 72 + 72 = 255
  • For i=73: 255 - 73 + 72 = 254
  • Fixed palettes (i < 72): returns i directly ✓

This is a critical correctness fix that ensures custom palettes are properly indexed.


995-1000: Consistent palette categorization using constants.

The changes correctly replace magic numbers with named constants and fix the categorization logic:

  1. Line 995: i >= palettesCount correctly identifies custom palettes (was incorrectly i > palettesCount)
  2. Line 997: Uses DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT instead of hardcoded 13
  3. Lines 998, 1000: Index calculations use constants for clarity and maintainability

The logic is now consistent with the changes in wled00/FX_fcn.cpp.

Based on learnings, this properly eliminates magic numbers by using defined constants.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wled00/json.cpp (2)

966-1001: Critical: Loop bounds and JSON key calculation bugs will cause incorrect behavior or crashes.

Several issues with the palette serialization logic:

  1. Loop condition i <= end (line 966): When there are no custom palettes, end = palettesCount = 72. The loop iterates with i = 72, which triggers the custom palette branch (line 996: i >= palettesCount), attempting to access customPalettes[0] on an empty vector — undefined behavior or crash.

  2. JSON key calculation (line 967): The condition i <= palettesCount is true when i = 72, producing key 72. However, palette index 72 is the first custom palette, which should have key 255, not 72. Custom palettes use keys counting down from 255.

  3. Off-by-one in custom palette key formula: When i = 73 (second custom palette), the formula 255 - (i - (palettesCount + 1)) = 255 - (73 - 73) = 255, but it should be 254.

🔎 Proposed fix
-  for (int i = start; i <= end; i++) {
-    JsonArray curPalette = palettes.createNestedArray(String(i<=palettesCount ? i : 255 - (i - (palettesCount + 1))));
+  for (int i = start; i < end; i++) {
+    JsonArray curPalette = palettes.createNestedArray(String(i < palettesCount ? i : 255 - (i - palettesCount)));

The fixes:

  • Change i <= end to i < end to prevent iterating past valid palette indices
  • Change i <= palettesCount to i < palettesCount to correctly identify custom palettes starting at index 72
  • Change formula from 255 - (i - (palettesCount + 1)) to 255 - (i - palettesCount) for correct custom palette keys

954-961: Minor: maxPage calculation may produce an extra empty page.

The formula change from (count - 1) / itemPerPage to count / itemPerPage can result in an extra page when the total count is exactly divisible by itemPerPage.

For example, with 72 fixed palettes and 0 custom palettes using 8 items per page:

  • Old: (72 - 1) / 8 = 8 → pages 0-8 (9 pages, last page has 8 items)
  • New: 72 / 8 = 9 → pages 0-9 (10 pages, page 9 would be empty)

If the loop bounds issue above is fixed to use i < end, this becomes a minor UI issue (empty last page) rather than a crash, but it's still incorrect.

🔎 Proposed fix
-  int maxPage = (palettesCount + customPalettesCount) / itemPerPage;
+  int maxPage = (palettesCount + customPalettesCount - 1) / itemPerPage;
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 304c59e and 97d3792.

📒 Files selected for processing (4)
  • usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp (1 hunks)
  • wled00/FX_fcn.cpp (2 hunks)
  • wled00/const.h (1 hunks)
  • wled00/json.cpp (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
wled00/**/!(html_*)*.h

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 2-space indentation for non-generated C++ header files (.h)

Files:

  • wled00/const.h
wled00/**/*.cpp

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 2-space indentation for C++ source files (.cpp)

Files:

  • wled00/FX_fcn.cpp
  • wled00/json.cpp
🧠 Learnings (17)
📓 Common learnings
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.949Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR #4876, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.
📚 Learning: 2025-04-26T19:19:07.600Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4658
File: wled00/const.h:140-141
Timestamp: 2025-04-26T19:19:07.600Z
Learning: In WLED, the WLED_MAX_PANELS macro is intentionally defined as a fixed constant value (18) with no redefinition mechanism, making it "unoverridable" - there's no need for a static assertion to check its maximum value.

Applied to files:

  • wled00/const.h
📚 Learning: 2025-11-14T13:37:30.955Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.

Applied to files:

  • wled00/const.h
  • wled00/json.cpp
📚 Learning: 2025-11-14T13:37:11.994Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.

Applied to files:

  • wled00/const.h
  • wled00/json.cpp
📚 Learning: 2025-08-28T08:09:20.630Z
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
  • wled00/json.cpp
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
  • wled00/json.cpp
📚 Learning: 2025-06-15T09:59:52.720Z
Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
📚 Learning: 2025-11-27T06:33:11.436Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
📚 Learning: 2025-11-16T19:40:46.260Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4926
File: wled00/FX.cpp:4727-4730
Timestamp: 2025-11-16T19:40:46.260Z
Learning: WLED AuroraWave (wled00/FX.cpp): wave_start and wave_end intentionally use int16_t; segments longer than 32k LEDs are not supported (bounded by MAX_LEDS), so widening to 32-bit is unnecessary.

Applied to files:

  • wled00/const.h
  • wled00/FX_fcn.cpp
  • wled00/json.cpp
📚 Learning: 2025-10-20T09:38:51.997Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4995
File: wled00/FX.cpp:5223-5226
Timestamp: 2025-10-20T09:38:51.997Z
Learning: WLED matrices: each dimension (SEG_W, SEG_H) is limited to ≤255; 256 or larger per side is not supported/feasible on ESP32, so effects should assume per-dimension max 255.

Applied to files:

  • wled00/const.h
📚 Learning: 2025-11-22T12:12:53.486Z
Learnt from: DedeHai
Repo: wled/WLED PR: 5105
File: wled00/FX.h:968-968
Timestamp: 2025-11-22T12:12:53.486Z
Learning: In WLED's WS2812FX class (wled00/FX.h), the _pixels array stores LED colors indexed by unmapped (logical) LED positions, not physical positions. The getPixelColor(n) function intentionally checks if the logical LED at index n maps to a valid physical position via getMappedPixelIndex(n), then accesses _pixels[n] with the unmapped index. If the mapping is invalid (e.g., -1 for gaps in LED maps, or out of bounds), it returns 0 (black). This allows peek preview to correctly show gaps in LED mappings as black pixels. The mapping from logical to physical positions is only applied when writing to the hardware bus, not when reading from the pixel buffer.
<!-- [add_learning]

Applied to files:

  • wled00/const.h
📚 Learning: 2025-05-09T18:43:15.355Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4682
File: wled00/FX.cpp:8997-9005
Timestamp: 2025-05-09T18:43:15.355Z
Learning: In the WLED codebase, SEGMENT.custom3 is always constrained to the range 0-31 and will not exceed this range.

Applied to files:

  • wled00/const.h
📚 Learning: 2025-12-15T20:25:25.807Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-15T20:25:25.807Z
Learning: The CSS palette preview in wled00/data/index.js genPalPrevCss() function uses raw RGB values in CSS linear-gradient() without applying WLED's gamma correction, while actual LED output goes through NeoGammaWLEDMethod gamma correction. This causes inherent discrepancies between the web UI palette preview and actual LED colors, especially noticeable with different gamma settings.

Applied to files:

  • wled00/FX_fcn.cpp
  • wled00/json.cpp
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.

Applied to files:

  • wled00/FX_fcn.cpp
  • wled00/json.cpp
📚 Learning: 2025-11-14T05:48:44.673Z
Learnt from: DedeHai
Repo: wled/WLED PR: 5040
File: wled00/image_loader.cpp:84-96
Timestamp: 2025-11-14T05:48:44.673Z
Learning: In WLED (wled00/FX_2Dfcn.cpp), the Segment::setPixelColorXY() function performs internal bounds checking against vWidth() and vHeight(), returning early if coordinates are out of bounds. No additional guards are needed when calling this function, even in upscaling loops where coordinates might exceed segment dimensions.

Applied to files:

  • wled00/FX_fcn.cpp
📚 Learning: 2025-09-12T17:29:43.826Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.

Applied to files:

  • wled00/json.cpp
🧬 Code graph analysis (1)
usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp (1)
wled00/colors.h (1)
  • getPaletteCount (127-127)
🪛 Clang (14.0.6)
wled00/const.h

[error] 9-9: unknown type name 'constexpr'

(clang-diagnostic-error)


[error] 9-9: expected ';' after top level declarator

(clang-diagnostic-error)


[error] 10-10: unknown type name 'constexpr'

(clang-diagnostic-error)


[error] 10-10: expected ';' after top level declarator

(clang-diagnostic-error)


[error] 11-11: unknown type name 'constexpr'

(clang-diagnostic-error)


[error] 11-11: expected ';' after top level declarator

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: wled_build / Build Environments (esp32c3dev_qio)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
  • GitHub Check: wled_build / Build Environments (esp32dev_debug)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32c3dev)
  • GitHub Check: wled_build / Build Environments (esp32_wrover)
  • GitHub Check: wled_build / Build Environments (nodemcuv2_160)
  • GitHub Check: wled_build / Build Environments (esp32_eth)
  • GitHub Check: wled_build / Build Environments (esp32dev)
  • GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full)
  • GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
  • GitHub Check: wled_build / Test cdata.js
  • GitHub Check: Analyze (c-cpp)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: wled_build / Build Environments (usermods)
  • GitHub Check: wled_build / Build Environments (esp32S3_wroom2)
  • GitHub Check: wled_build / Build Environments (esp32dev_debug)
🔇 Additional comments (4)
usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.cpp (1)

404-416: LGTM! Palette handling correctly updated to use FIXED_PALETTE_COUNT.

The changes properly align with the palette categorization:

  • Custom palettes are now correctly inserted starting at index FIXED_PALETTE_COUNT (72)
  • Sorting is limited to fixed palettes only, which prevents custom palette indices from being reordered
  • The getPaletteCount() function (from colors.h) correctly computes total palettes as FIXED_PALETTE_COUNT + customPalettes.size()

This follows the learnings about replacing magic numbers with defined constants for maintainability.

wled00/const.h (1)

9-12: LGTM! Updated palette count constants with clear documentation.

The constants now correctly reflect the palette categorization:

  • DYNAMIC_PALETTE_COUNT = 6 covers palettes 0-5 (dynamic/color-derived)
  • FASTLED_PALETTE_COUNT = 7 covers palettes 6-12 (FastLED built-ins)
  • GRADIENT_PALETTE_COUNT = 59 covers palettes 13-71 (gradient palettes)
  • FIXED_PALETTE_COUNT = 72 is the total of all built-in palettes

The updated comments documenting the index ranges improve maintainability. Based on learnings, replacing magic numbers with these constants is the recommended approach.

Note: The static analysis warnings about constexpr being an "unknown type" are false positives - the analyzer appears to be running in C mode rather than C++11+ mode. These can be safely ignored.

wled00/FX_fcn.cpp (2)

233-233: LGTM! Correct bounds check for out-of-range palettes.

The condition pal >= FIXED_PALETTE_COUNT && pal <= 255-customPalettes.size() correctly identifies invalid palette indices:

  • Valid fixed palettes: 0 to 71 (FIXED_PALETTE_COUNT - 1)
  • Valid custom palettes: 255 down to (256 - customPalettes.size())
  • Gap (invalid): 72 to (255 - customPalettes.size()) → reset to default palette 0

The change from > to >= correctly rejects palette index 72 which doesn't exist.


271-275: LGTM! FastLED and gradient palette indexing correctly uses constants.

The indexing logic correctly replaces magic numbers with defined constants:

  • FastLED palettes (6-12): pal - DYNAMIC_PALETTE_COUNT maps to indices 0-6
  • Gradient palettes (13-71): pal - (DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT) maps to indices 0-58

This aligns with the updated constants in const.h and follows the project learnings about using defined constants instead of hardcoded values.

@netmindz netmindz requested a review from DedeHai December 20, 2025 13:59
@DedeHai
Copy link
Collaborator

DedeHai commented Dec 20, 2025

I think the rabbit is right about there now being a one-off in custom palettes, at least its logic makes sense to me

@DedeHai
Copy link
Collaborator

DedeHai commented Dec 22, 2025

@coderabbitai is the cusom palette logic correct now?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR diff to see the exact changes
gh pr diff 5215 --repo wled/WLED > /tmp/pr_diff.txt
head -n 500 /tmp/pr_diff.txt

Length of output: 8224


🏁 Script executed:

#!/bin/bash
# Get the rest of the diff if it's longer
tail -n +501 /tmp/pr_diff.txt | head -n 500

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Examine the const.h file to understand the palette constants
cat wled00/const.h | grep -A 5 -B 5 "PALETTE_COUNT"

Length of output: 996


🏁 Script executed:

#!/bin/bash
# Look at the FX_fcn.cpp loadPalette function to understand the logic
ast-grep --pattern $'void loadPalette($$$) {
  $$$
}'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for custom palette handling in json.cpp
rg -n -A 10 -B 5 "customPalettes" wled00/json.cpp | head -n 100

Length of output: 3170


@DedeHai Yes, the custom palette logic appears to be correct now! Let me walk through the indexing to confirm:

Custom Palette Indexing (with FIXED_PALETTE_COUNT = 72)

In json.cpp (serializePalettes):

// Linear iteration i=72, 73, 74... maps to palette indices:
String(i >= palettesCount ? 255 - i + palettesCount : i)
// i=72 → 255-72+72 = 255 (1st custom)
// i=73 → 255-73+72 = 254 (2nd custom)
// i=74 → 255-74+72 = 253 (3rd custom) ✓

// Array access:
customPalettes[i - palettesCount]
// i=72 → customPalettes[0]
// i=73 → customPalettes[1] ✓

In FX_fcn.cpp (loadPalette):

// Boundary check with 3 custom palettes:
if (pal >= 72 && pal <= 252) pal = 0;  // catches invalid indices 72-252 ✓

// Custom palette loading:
if (pal > 252) {  // handles 253-255
  targetPalette = customPalettes[255-pal];
  // pal=255 → customPalettes[0]
  // pal=254 → customPalettes[1]
  // pal=253 → customPalettes[2] ✓
}

FastLED and Gradient Palettes:

  • FastLED (indices 6-12): fastledPalettes[pal - 6]
  • Gradient (indices 13-71): gGradientPalettes[pal - 13]

In usermod:

// Places custom palettes at linear array positions 72, 73, 74...
palettes_alpha_indexes[FIXED_PALETTE_COUNT+i] = 255-i;  // stores 255, 254, 253...
// Sorts only fixed palettes (0-71) ✓

The off-by-one issue has been resolved. All palette ranges are now correctly bounded and indexed:

  • Dynamic: 0-5
  • FastLED: 6-12
  • Gradient: 13-71
  • Custom: 255, 254, 253... (downward from 255)

🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.

Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.

Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.949Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants