diff --git a/src/playlist/PlaylistCWrapper.cpp b/src/playlist/PlaylistCWrapper.cpp index b7d05629b..3c2e6be6e 100644 --- a/src/playlist/PlaylistCWrapper.cpp +++ b/src/playlist/PlaylistCWrapper.cpp @@ -62,26 +62,45 @@ void PlaylistCWrapper::OnPresetSwitchFailed(const char* presetFilename, const ch } auto* playlist = reinterpret_cast(userData); + auto lastDirection = playlist->GetLastNavigationDirection(); - // ToDo: Add different retry behavior for set/next/previous/last calls. - - // Don't go back to a broken preset. - playlist->RemoveLastHistoryEntry(); + if (lastDirection != NavigationDirection::Last) + { + // 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) - { - playlist->m_presetSwitchFailedCount++; - playlist->PlayPresetIndex(playlist->NextPresetIndex(), playlist->m_hardCutRequested, false); - } - else + 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); } @@ -136,6 +155,18 @@ void PlaylistCWrapper::PlayPresetIndex(uint32_t index, bool hardCut, bool resetF } } + +void PlaylistCWrapper::SetLastNavigationDirection(PlaylistCWrapper::NavigationDirection direction) +{ + m_lastNavigationDirection = direction; +} + + +auto PlaylistCWrapper::GetLastNavigationDirection() const -> PlaylistCWrapper::NavigationDirection +{ + return m_lastNavigationDirection; +} + } // namespace Playlist } // namespace libprojectM @@ -459,6 +490,7 @@ auto projectm_playlist_set_position(projectm_playlist_handle instance, uint32_t bool hard_cut) -> uint32_t { auto* playlist = playlist_handle_to_instance(instance); + playlist->SetLastNavigationDirection(libprojectM::Playlist::PlaylistCWrapper::NavigationDirection::Next); try { auto newIndex = playlist->SetPresetIndex(new_position); @@ -475,6 +507,7 @@ auto projectm_playlist_set_position(projectm_playlist_handle instance, uint32_t uint32_t projectm_playlist_play_next(projectm_playlist_handle instance, bool hard_cut) { auto* playlist = playlist_handle_to_instance(instance); + playlist->SetLastNavigationDirection(libprojectM::Playlist::PlaylistCWrapper::NavigationDirection::Next); try { auto newIndex = playlist->NextPresetIndex(); @@ -491,6 +524,7 @@ uint32_t projectm_playlist_play_next(projectm_playlist_handle instance, bool har uint32_t projectm_playlist_play_previous(projectm_playlist_handle instance, bool hard_cut) { auto* playlist = playlist_handle_to_instance(instance); + playlist->SetLastNavigationDirection(libprojectM::Playlist::PlaylistCWrapper::NavigationDirection::Previous); try { auto newIndex = playlist->PreviousPresetIndex(); @@ -507,6 +541,8 @@ uint32_t projectm_playlist_play_previous(projectm_playlist_handle instance, bool uint32_t projectm_playlist_play_last(projectm_playlist_handle instance, bool hard_cut) { auto* playlist = playlist_handle_to_instance(instance); + + playlist->SetLastNavigationDirection(libprojectM::Playlist::PlaylistCWrapper::NavigationDirection::Last); try { auto newIndex = playlist->LastPresetIndex(); diff --git a/src/playlist/PlaylistCWrapper.hpp b/src/playlist/PlaylistCWrapper.hpp index fe4eec35a..20d315f07 100644 --- a/src/playlist/PlaylistCWrapper.hpp +++ b/src/playlist/PlaylistCWrapper.hpp @@ -4,8 +4,7 @@ #include "Playlist.hpp" -#include -#include +#include namespace libprojectM { namespace Playlist { @@ -13,6 +12,16 @@ namespace Playlist { class PlaylistCWrapper : public Playlist { public: + /** + * Last navigational direction used to switch a preset. + */ + enum class NavigationDirection : uint8_t + { + Previous, //!< Previous item in the playlist + Next, //!< Next item in the playlist + Last //!< Previous item in the playback history + }; + PlaylistCWrapper() = delete; /** @@ -73,6 +82,19 @@ public: virtual void SetPresetSwitchFailedCallback(projectm_playlist_preset_switch_failed_event callback, void* userData); + /** + * @brief Sets the last navigation direction used to switch a preset. + * This is used when retrying on a failed preset load, keeping the same direction/logic as in the original switch. + * @param direction The direction. + */ + void SetLastNavigationDirection(NavigationDirection direction); + + /** + * @brief Returns the last navigation direction used to switch a preset. + * @returns The last switch direction. + */ + auto GetLastNavigationDirection() const -> NavigationDirection; + private: projectm_handle m_projectMInstance{nullptr}; //!< The projectM instance handle this instance is connected to. @@ -86,6 +108,8 @@ private: projectm_playlist_preset_switch_failed_event m_presetSwitchFailedEventCallback{nullptr}; //!< Preset switch failed callback pointer set by the application. void* m_presetSwitchFailedEventUserData{nullptr}; //!< Context data pointer set by the application. + + NavigationDirection m_lastNavigationDirection{NavigationDirection::Next}; //!< Last direction used to switch a preset. }; } // namespace Playlist