Remember last playlist navigation direction in case a preset fails to load.

The playlist wrapper will now continue to repeat the directional navigation command issued in the original API call.
This commit is contained in:
Kai Blaschke
2024-02-06 11:11:01 +01:00
parent c5ecad05db
commit 4eefc2c05c
2 changed files with 72 additions and 12 deletions

View File

@ -62,26 +62,45 @@ void PlaylistCWrapper::OnPresetSwitchFailed(const char* presetFilename, const ch
}
auto* playlist = reinterpret_cast<PlaylistCWrapper*>(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();

View File

@ -4,8 +4,7 @@
#include "Playlist.hpp"
#include <string>
#include <vector>
#include <cstdint>
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