diff --git a/wled00/data/index.js b/wled00/data/index.js
index eeea74d4c..c430ed2a8 100644
--- a/wled00/data/index.js
+++ b/wled00/data/index.js
@@ -409,7 +409,9 @@ function pName(i)
function isPlaylist(i)
{
- return pJson[i].playlist && pJson[i].playlist.ps;
+ if (isNumeric(i)) return pJson[i].playlist && pJson[i].playlist.ps;
+ if (isObj(i)) return i.playlist && i.playlist.ps;
+ return false;
}
function papiVal(i)
@@ -1905,15 +1907,16 @@ function resetUtil(off=false)
if (lSeg>2) d.querySelectorAll("#Segments .pop").forEach((e)=>{e.classList.remove("hide");});
}
-function makePlSel(el, incPl=false)
+function makePlSel(p, el)
{
var plSelContent = "";
delete pJson["0"]; // remove filler preset
Object.entries(pJson).sort(cmpP).forEach((a)=>{
var n = a[1].n ? a[1].n : "Preset " + a[0];
+ if (isPlaylist(a[1])) n += ' ▶'; // mark playlist
if (cfg.comp.idsort) n = a[0] + ' ' + n;
- if (!(!incPl && a[1].playlist && a[1].playlist.ps)) // skip playlists, sub-playlists not yet supported
- plSelContent += ``;
+ // skip endless playlists and itself
+ if (!isPlaylist(a[1]) || (a[1].playlist.repeat > 0 && a[0]!=p)) plSelContent += ``;
});
return plSelContent;
}
@@ -1938,21 +1941,23 @@ function refreshPlE(p)
});
}
-// p: preset ID, i: ps index
+// p: preset ID, i: playlist item index
function addPl(p,i)
{
- plJson[p].ps.splice(i+1,0,0);
- plJson[p].dur.splice(i+1,0,plJson[p].dur[i]);
- plJson[p].transition.splice(i+1,0,plJson[p].transition[i]);
+ const pl = plJson[p];
+ pl.ps.splice(i+1,0,1);
+ pl.dur.splice(i+1,0,pl.dur[i]);
+ pl.transition.splice(i+1,0,pl.transition[i]);
refreshPlE(p);
}
function delPl(p,i)
{
- if (plJson[p].ps.length < 2) return;
- plJson[p].ps.splice(i,1);
- plJson[p].dur.splice(i,1);
- plJson[p].transition.splice(i,1);
+ const pl = plJson[p];
+ if (pl.ps.length < 2) return;
+ pl.ps.splice(i,1);
+ pl.dur.splice(i,1);
+ pl.transition.splice(i,1);
refreshPlE(p);
}
@@ -2017,7 +2022,7 @@ function makeP(i,pl)
`;
@@ -2096,7 +2101,7 @@ function makePlEntry(p,i)
|
|
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h
index cf187bacd..f8580eb77 100644
--- a/wled00/fcn_declare.h
+++ b/wled00/fcn_declare.h
@@ -325,6 +325,7 @@ void serializePlaylist(JsonObject obj);
//presets.cpp
const char *getPresetsFileName(bool persistent = true);
+bool presetNeedsSaving();
void initPresetsFile();
void handlePresets();
bool applyPreset(byte index, byte callMode = CALL_MODE_DIRECT_CHANGE);
diff --git a/wled00/led.cpp b/wled00/led.cpp
index 9731da655..72c78a1af 100644
--- a/wled00/led.cpp
+++ b/wled00/led.cpp
@@ -112,10 +112,11 @@ void stateUpdated(byte callMode) {
}
}
+ unsigned long now = millis();
if (callMode != CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) {
briNlT = bri;
- nightlightDelayMs -= (millis() - nightlightStartTime);
- nightlightStartTime = millis();
+ nightlightDelayMs -= (now - nightlightStartTime);
+ nightlightStartTime = now;
}
if (briT == 0) {
if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning
@@ -141,7 +142,7 @@ void stateUpdated(byte callMode) {
} else
strip.setTransitionMode(true); // force all segments to transition mode
transitionActive = true;
- transitionStartTime = millis();
+ transitionStartTime = now;
}
diff --git a/wled00/playlist.cpp b/wled00/playlist.cpp
index 1908334d7..0897eddad 100644
--- a/wled00/playlist.cpp
+++ b/wled00/playlist.cpp
@@ -10,19 +10,19 @@ typedef struct PlaylistEntry {
uint16_t tr; //Duration of the transition TO this entry (in tenths of seconds)
} ple;
-byte playlistRepeat = 1; //how many times to repeat the playlist (0 = infinitely)
-byte playlistEndPreset = 0; //what preset to apply after playlist end (0 = stay on last preset)
-byte playlistOptions = 0; //bit 0: shuffle playlist after each iteration. bits 1-7 TBD
+static byte playlistRepeat = 1; //how many times to repeat the playlist (0 = infinitely)
+static byte playlistEndPreset = 0; //what preset to apply after playlist end (0 = stay on last preset)
+static byte playlistOptions = 0; //bit 0: shuffle playlist after each iteration. bits 1-7 TBD
-PlaylistEntry *playlistEntries = nullptr;
-byte playlistLen; //number of playlist entries
-int8_t playlistIndex = -1;
-uint16_t playlistEntryDur = 0; //duration of the current entry in tenths of seconds
+static PlaylistEntry *playlistEntries = nullptr;
+static byte playlistLen; //number of playlist entries
+static int8_t playlistIndex = -1;
+static uint16_t playlistEntryDur = 0; //duration of the current entry in tenths of seconds
//values we need to keep about the parent playlist while inside sub-playlist
-//int8_t parentPlaylistIndex = -1;
-//byte parentPlaylistRepeat = 0;
-//byte parentPlaylistPresetId = 0; //for re-loading
+static int16_t parentPlaylistIndex = -1;
+static byte parentPlaylistRepeat = 0;
+static byte parentPlaylistPresetId = 0; //for re-loading
void shufflePlaylist() {
@@ -54,6 +54,12 @@ void unloadPlaylist() {
int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
+ if (currentPlaylist > 0 && parentPlaylistPresetId > 0) return; // we are already in nested playlist, do nothing
+ if (currentPlaylist > 0) {
+ parentPlaylistIndex = playlistIndex;
+ parentPlaylistRepeat = playlistRepeat;
+ parentPlaylistPresetId = currentPlaylist;
+ }
unloadPlaylist();
JsonArray presets = playlistObj["ps"];
@@ -117,6 +123,19 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
shuffle = shuffle || playlistObj["r"];
if (shuffle) playlistOptions |= PL_OPTION_SHUFFLE;
+ if (parentPlaylistPresetId == 0 && parentPlaylistIndex > -1) {
+ // we are re-loading playlist when returning from nested playlist
+ playlistIndex = parentPlaylistIndex;
+ playlistRepeat = parentPlaylistRepeat;
+ parentPlaylistIndex = -1;
+ parentPlaylistRepeat = 0;
+ } else if (rep == 0) {
+ // endless playlist will never return to parent so erase parent information if it was called from it
+ parentPlaylistPresetId = 0;
+ parentPlaylistIndex = -1;
+ parentPlaylistRepeat = 0;
+ }
+
currentPlaylist = presetId;
DEBUG_PRINTLN(F("Playlist loaded."));
return currentPlaylist;
@@ -127,7 +146,7 @@ void handlePlaylist() {
static unsigned long presetCycledTime = 0;
if (currentPlaylist < 0 || playlistEntries == nullptr) return;
-if (millis() - presetCycledTime > (100 * playlistEntryDur) || doAdvancePlaylist) {
+ if (millis() - presetCycledTime > (100 * playlistEntryDur) || doAdvancePlaylist) {
presetCycledTime = millis();
if (bri == 0 || nightlightActive) return;
@@ -137,7 +156,10 @@ if (millis() - presetCycledTime > (100 * playlistEntryDur) || doAdvancePlaylist)
if (!playlistIndex) {
if (playlistRepeat == 1) { //stop if all repetitions are done
unloadPlaylist();
- if (playlistEndPreset) applyPresetFromPlaylist(playlistEndPreset);
+ if (parentPlaylistPresetId > 0) {
+ applyPresetFromPlaylist(parentPlaylistPresetId); // reload previous playlist (unfortunately asynchronous)
+ parentPlaylistPresetId = 0; // reset previous playlist but do not reset Index or Repeat (they will be loaded & reset in loadPlaylist())
+ } else if (playlistEndPreset) applyPresetFromPlaylist(playlistEndPreset);
return;
}
if (playlistRepeat > 1) playlistRepeat--; // decrease repeat count on each index reset if not an endless playlist
diff --git a/wled00/presets.cpp b/wled00/presets.cpp
index 15eed3e46..54f052637 100644
--- a/wled00/presets.cpp
+++ b/wled00/presets.cpp
@@ -22,6 +22,10 @@ const char *getPresetsFileName(bool persistent) {
return persistent ? presets_json : tmp_json;
}
+bool presetNeedsSaving() {
+ return presetToSave;
+}
+
static void doSaveState() {
bool persist = (presetToSave < 251);
@@ -269,7 +273,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
quickLoad = nullptr;
} else {
// store playlist
- // WARNING: playlist will be loaded in json.cpp after this call and will have repeat counter increased by 1
+ // WARNING: playlist will be loaded in json.cpp after this call and will have repeat counter increased by 1 it will also be randomised if selected
includeBri = true; // !sObj["on"].isNull();
playlistSave = true;
}
diff --git a/wled00/wled.cpp b/wled00/wled.cpp
index 2a5902d1b..2cb6da411 100644
--- a/wled00/wled.cpp
+++ b/wled00/wled.cpp
@@ -109,7 +109,6 @@ void WLED::loop()
if (WLED_CONNECTED && aOtaEnabled && !otaLock && correctPIN) ArduinoOTA.handle();
#endif
handleNightlight();
- handlePlaylist();
yield();
#ifndef WLED_DISABLE_HUESYNC
@@ -117,6 +116,10 @@ void WLED::loop()
yield();
#endif
+ if (!presetNeedsSaving()) {
+ handlePlaylist();
+ yield();
+ }
handlePresets();
yield();
@@ -553,10 +556,10 @@ void WLED::beginStrip()
strip.fill(BLACK);
strip.show();
}
+ colorUpdated(CALL_MODE_INIT); // will not send notification but will initiate transition
if (bootPreset > 0) {
applyPreset(bootPreset, CALL_MODE_INIT);
}
- colorUpdated(CALL_MODE_INIT); // will not send notification
// init relay pin
if (rlyPin >= 0) {