Playlist Library: Improve failed preset handling using a loop

Also removing failed presets immediately, which will prevent the same preset from being tried again. Increased default retry count to 500.
This commit is contained in:
Kai Blaschke 2025-09-29 14:47:19 +02:00
parent 3e67f6e477
commit 2da6db297e
No known key found for this signature in database
GPG Key ID: B014B6811527389F
3 changed files with 69 additions and 51 deletions

View File

@ -62,6 +62,11 @@ void PlaylistCWrapper::OnPresetSwitchFailed(const char* presetFilename, const ch
}
auto* playlist = reinterpret_cast<PlaylistCWrapper*>(userData);
playlist->m_lastPresetSwitchFailed = true;
playlist->m_lastFailedPresetFileName = presetFilename;
playlist->m_lastFailedPresetError = message;
auto lastDirection = playlist->GetLastNavigationDirection();
if (lastDirection != NavigationDirection::Last)
@ -69,38 +74,6 @@ void PlaylistCWrapper::OnPresetSwitchFailed(const char* presetFilename, const ch
// Don't let the user go back to a broken preset.
playlist->RemoveLastHistoryEntry();
}
// Preset switch may fail due to broken presets, retry a few times before giving up.
if (playlist->m_presetSwitchFailedCount >= playlist->m_presetSwitchRetryCount)
{
if (playlist->m_presetSwitchFailedEventCallback != nullptr)
{
playlist->m_presetSwitchFailedEventCallback(presetFilename, message,
playlist->m_presetSwitchFailedEventUserData);
}
return;
}
playlist->m_presetSwitchFailedCount++;
uint32_t playlistIndex{};
switch (lastDirection)
{
case NavigationDirection::Previous:
playlistIndex = playlist->PreviousPresetIndex();
break;
case NavigationDirection::Next:
playlistIndex = playlist->NextPresetIndex();
break;
case NavigationDirection::Last:
playlistIndex = playlist->LastPresetIndex();
break;
}
playlist->PlayPresetIndex(playlistIndex, playlist->m_hardCutRequested, false);
}
@ -132,22 +105,64 @@ void PlaylistCWrapper::SetPresetSwitchFailedCallback(projectm_playlist_preset_sw
void PlaylistCWrapper::PlayPresetIndex(uint32_t index, bool hardCut, bool resetFailureCount)
{
if (resetFailureCount)
{
m_presetSwitchFailedCount = 0;
}
m_hardCutRequested = hardCut;
const auto& playlistItems = Items();
auto& playlistItems = Items();
if (playlistItems.size() <= index)
uint32_t failedCount = 0;
while (true)
{
return;
}
if (playlistItems.size() <= index)
{
return;
}
projectm_load_preset_file(m_projectMInstance,
playlistItems.at(index).Filename().c_str(), !hardCut);
projectm_load_preset_file(m_projectMInstance,
playlistItems.at(index).Filename().c_str(), !hardCut);
if (!m_lastPresetSwitchFailed)
{
break;
}
failedCount++;
if (failedCount >= m_presetSwitchRetryCount)
{
if (m_presetSwitchFailedEventCallback != nullptr)
{
m_presetSwitchFailedEventCallback(m_lastFailedPresetFileName.c_str(),
m_lastFailedPresetError.c_str(),
m_presetSwitchFailedEventUserData);
}
return;
}
m_lastPresetSwitchFailed = false;
// Remove failed preset from playlist
RemoveItem(index);
if (playlistItems.empty())
{
return;
}
// Set next index to proper value depending on navigation
switch (GetLastNavigationDirection())
{
case NavigationDirection::Last:
index = LastPresetIndex();
break;
case NavigationDirection::Next:
index = NextPresetIndex();
break;
case NavigationDirection::Previous:
index = PreviousPresetIndex();
break;
}
}
if (m_presetSwitchedEventCallback != nullptr)
{
@ -156,13 +171,13 @@ void PlaylistCWrapper::PlayPresetIndex(uint32_t index, bool hardCut, bool resetF
}
void PlaylistCWrapper::SetLastNavigationDirection(PlaylistCWrapper::NavigationDirection direction)
void PlaylistCWrapper::SetLastNavigationDirection(NavigationDirection direction)
{
m_lastNavigationDirection = direction;
}
auto PlaylistCWrapper::GetLastNavigationDirection() const -> PlaylistCWrapper::NavigationDirection
auto PlaylistCWrapper::GetLastNavigationDirection() const -> NavigationDirection
{
return m_lastNavigationDirection;
}
@ -263,7 +278,7 @@ auto projectm_playlist_items(projectm_playlist_handle instance, uint32_t start,
if (start >= items.size())
{
auto* array = new char* [1] {};
auto* array = new char*[1]{};
return array;
}

View File

@ -98,8 +98,10 @@ public:
private:
projectm_handle m_projectMInstance{nullptr}; //!< The projectM instance handle this instance is connected to.
uint32_t m_presetSwitchRetryCount{5}; //!< Number of switch retries before sending the failure event to the application.
uint32_t m_presetSwitchFailedCount{0}; //!< Number of retries since the last preset switch.
uint32_t m_presetSwitchRetryCount{500}; //!< Number of switch retries before sending the failure event to the application.
bool m_lastPresetSwitchFailed{false}; //!< Indicates that the last preset switch has failed.
std::string m_lastFailedPresetFileName; //!< File name of the last failed preset.
std::string m_lastFailedPresetError; //!< Error message of the last failure.
bool m_hardCutRequested{false}; //!< Stores the type of the last requested switch attempt.

View File

@ -28,8 +28,8 @@
#include "projectM-4/playlist_types.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@ -53,9 +53,10 @@ PROJECTM_PLAYLIST_EXPORT bool projectm_playlist_get_shuffle(projectm_playlist_ha
/**
* @brief Sets the number of retries after failed preset switches.
* @note Don't set this value too high, as each retry is done recursively.
* @note Retry behavior changed in v4.2, using a loop. Default retry count is now 500. Failed items
* are also being removed from the playlist, so they're not tried again.
* @param instance The playlist manager instance.
* @param retry_count The number of retries after failed preset switches. Default is 5. Set to 0
* @param retry_count The number of retries after failed preset switches. Default is 500. Set to 0
* to simply forward the failure event from projectM.
* @since 4.0.0
*/