Repository navigation
Fix some issues on pov display usermod #5872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
40f09fb
392b5e5
fcadb44
df4c9c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,65 +5,81 @@ static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = "POV Image@!;;;;"; | |
|
|
||
| static POV s_pov; | ||
|
|
||
| // AI: below section was generated by an AI | ||
| void mode_pov_image(void) { | ||
| Segment& mainseg = strip.getMainSegment(); | ||
| const char* segName = mainseg.name; | ||
| // This effect displays columns from a BMP image for horizontal POV | ||
| // All logic is handled here to ensure it only runs when this effect is selected | ||
| // The image name is read from the segment actually running this effect (SEGMENT), | ||
| // not from the main segment, so a secondary segment can display its image even | ||
| // when the main segment has no name. The playback position is kept per segment | ||
| // (aux0), so multiple segments running this effect advance their own column. | ||
| // Note: BMPimage has a single shared pixel buffer, so only one image can be | ||
| // loaded at a time; segments naming different images take turns (re)loading it. | ||
| Segment& seg = SEGMENT; | ||
| const char* segName = seg.name; | ||
| if (!segName) { | ||
| return; | ||
| } | ||
| return; | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
|
|
||
| // Only proceed for files ending with .bmp (case-insensitive) | ||
| size_t segLen = strlen(segName); | ||
| if (segLen < 4) return; | ||
| const char* ext = segName + (segLen - 4); | ||
| // compare case-insensitive to ".bmp" | ||
| if (!((ext[0]=='.') && | ||
| (ext[1]=='b' || ext[1]=='B') && | ||
| (ext[2]=='m' || ext[2]=='M') && | ||
| (ext[3]=='p' || ext[3]=='P'))) { | ||
| return; | ||
|
|
||
| if ((ext[0] == '.') && | ||
| (ext[1] == 'b' || ext[1] == 'B') && | ||
| (ext[2] == 'm' || ext[2] == 'M') && | ||
| (ext[3] == 'p' || ext[3] == 'P')) { | ||
|
|
||
| const char* current = s_pov.getFilename(); | ||
| BMPimage* img = s_pov.currentImage(); | ||
|
|
||
| // If image is already loaded and matches, show next column | ||
| if (current && strcmp(segName, current) == 0) { | ||
| s_pov.showColumn(seg.aux0); | ||
| seg.aux0 = (seg.aux0 + 1) % img->width(); | ||
|
Comment on lines
+39
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Require a loaded image before advancing a matching filename. A segment can load image A, then another segment can try an invalid image B. 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This effect is not intended to be run on several segment at the same time, there is not enough memory to load/store that many pixel buffers in memory.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
ast-grep outline usermods/pov_display/pov.cpp
ast-grep outline usermods/pov_display/bmpimage.cpp
ast-grep outline usermods/pov_display/pov.h
rg -n -C 5 'loadImage|_filename|_loaded|bool BMPimage::|getFilename' usermods/pov_displayLength of output: 9547 🏁 Script executed: #!/bin/bash
sed -n '18,132p' usermods/pov_display/bmpimage.cppLength of output: 3378
The failed-load case still applies with one segment. The ✏️ Learnings added
You are interacting with an AI system. |
||
| return; | ||
| } | ||
|
|
||
| // Image is loaded but doesn't match, or not loaded yet | ||
| // If we have a different image loaded, keep displaying it while trying the new one | ||
| if (img->isLoaded()) { | ||
| s_pov.showColumn(seg.aux0); | ||
| seg.aux0 = (seg.aux0 + 1) % img->width(); | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
|
|
||
| // Try to load the new image (rate limited) | ||
| static unsigned long s_lastLoadAttemptMs = 0; | ||
| unsigned long nowMs = millis(); | ||
| // Try to load at most twice per second | ||
| if (nowMs - s_lastLoadAttemptMs >= 500) { | ||
| s_lastLoadAttemptMs = nowMs; | ||
| if (s_pov.loadImage(segName)) { | ||
| // Successfully loaded, show first column | ||
| seg.aux0 = 0; | ||
| s_pov.showColumn(seg.aux0); | ||
| seg.aux0 = (seg.aux0 + 1) % img->width(); | ||
| } | ||
| // If load fails, we'll keep displaying old image and retry on next call | ||
| } | ||
| } | ||
|
|
||
| const char* current = s_pov.getFilename(); | ||
| if (current && strcmp(segName, current) == 0) { | ||
| s_pov.showNextLine(); | ||
| return; | ||
| } | ||
|
|
||
| static unsigned long s_lastLoadAttemptMs = 0; | ||
| unsigned long nowMs = millis(); | ||
| // Retry at most twice per second if the image is not yet loaded. | ||
| if (nowMs - s_lastLoadAttemptMs < 500) return; | ||
| s_lastLoadAttemptMs = nowMs; | ||
| s_pov.loadImage(segName); | ||
| return; | ||
| } | ||
| // AI: end | ||
|
|
||
| class PovDisplayUsermod : public Usermod { | ||
| protected: | ||
| bool enabled = false; //WLEDMM | ||
| const char *_name; //WLEDMM | ||
| bool initDone = false; //WLEDMM | ||
| unsigned long lastTime = 0; //WLEDMM | ||
| public: | ||
|
|
||
| PovDisplayUsermod(const char *name, bool enabled) | ||
| : enabled(enabled) , _name(name) {} | ||
|
|
||
| void setup() override { | ||
| strip.addEffect(255, &mode_pov_image, _data_FX_MODE_POV_IMAGE); | ||
| //initDone removed (unused) | ||
| } | ||
|
|
||
|
|
||
| void loop() override { | ||
| // if usermod is disabled or called during strip updating just exit | ||
| // NOTE: on very long strips strip.isUpdating() may always return true so update accordingly | ||
| if (!enabled || strip.isUpdating()) return; | ||
|
|
||
| // do your magic here | ||
| if (millis() - lastTime > 1000) { | ||
| lastTime = millis(); | ||
| } | ||
| } | ||
|
|
||
| uint16_t getId() override { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.