From 8a1b57aa803b50a395063cdb3d102815e6cb56df Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Wed, 18 Aug 2021 13:35:54 +0200 Subject: [PATCH] Added context data to event callbacks, re-enabling SDL window title change on preset switch. --- src/libprojectM/ProjectMCWrapper.cpp | 23 ++++++---- src/libprojectM/ProjectMCWrapper.hpp | 5 +++ src/libprojectM/projectM.h | 64 ++++++++++++++++++++-------- src/projectM-sdl/pmSDL.cpp | 13 +++--- src/projectM-sdl/pmSDL.hpp | 4 +- 5 files changed, 75 insertions(+), 34 deletions(-) diff --git a/src/libprojectM/ProjectMCWrapper.cpp b/src/libprojectM/ProjectMCWrapper.cpp index fb50d50dd..aeaf1702b 100644 --- a/src/libprojectM/ProjectMCWrapper.cpp +++ b/src/libprojectM/ProjectMCWrapper.cpp @@ -19,7 +19,7 @@ void projectMWrapper::presetSwitchedEvent(bool isHardCut, size_t presetIndex) co { if (_presetSwitchedEventCallback) { - _presetSwitchedEventCallback(isHardCut, presetIndex); + _presetSwitchedEventCallback(isHardCut, presetIndex, _presetSwitchedEventUserData); } } @@ -27,7 +27,7 @@ void projectMWrapper::shuffleEnabledValueChanged(bool shuffle_enabled) const { if (_shuffleEnableChangedEventCallback) { - _shuffleEnableChangedEventCallback(shuffle_enabled); + _shuffleEnableChangedEventCallback(shuffle_enabled, _shuffleEnableChangedEventUserData); } } @@ -36,7 +36,8 @@ void projectMWrapper::presetSwitchFailedEvent(bool isHardCut, unsigned int prese { if (_presetSwitchFailedEventCallback) { - _presetSwitchFailedEventCallback(isHardCut, presetIndex, failureMessage.c_str()); + _presetSwitchFailedEventCallback(isHardCut, presetIndex, + failureMessage.c_str(), _presetSwitchFailedEventUserData); } } @@ -44,7 +45,8 @@ void projectMWrapper::presetRatingChanged(unsigned int presetIndex, int rating, { if (_presetRatingChangedEventCallback) { - _presetRatingChangedEventCallback(presetIndex, rating, static_cast(ratingType)); + _presetRatingChangedEventCallback(presetIndex, rating, static_cast(ratingType), + _presetRatingChangedEventUserData); } } @@ -159,31 +161,36 @@ void projectm_destroy(projectm_handle instance) delete projectMInstance; } -void projectm_set_preset_switched_event_callback(projectm_handle instance, projectm_preset_switched_event callback) +void projectm_set_preset_switched_event_callback(projectm_handle instance, projectm_preset_switched_event callback, + void* user_data) { auto projectMInstance = handle_to_instance(instance); projectMInstance->_presetSwitchedEventCallback = callback; + projectMInstance->_presetSwitchedEventUserData = user_data; } void projectm_set_shuffle_enable_changed_event_callback(projectm_handle instance, - projectm_shuffle_enable_changed_event callback) + projectm_shuffle_enable_changed_event callback, void* user_data) { auto projectMInstance = handle_to_instance(instance); projectMInstance->_shuffleEnableChangedEventCallback = callback; + projectMInstance->_shuffleEnableChangedEventUserData = user_data; } void projectm_set_preset_switch_failed_event_callback(projectm_handle instance, - projectm_preset_switch_failed_event callback) + projectm_preset_switch_failed_event callback, void* user_data) { auto projectMInstance = handle_to_instance(instance); projectMInstance->_presetSwitchFailedEventCallback = callback; + projectMInstance->_presetSwitchFailedEventUserData = user_data; } void projectm_set_preset_rating_changed_event_callback(projectm_handle instance, - projectm_preset_rating_changed_event callback) + projectm_preset_rating_changed_event callback, void* user_data) { auto projectMInstance = handle_to_instance(instance); projectMInstance->_presetRatingChangedEventCallback = callback; + projectMInstance->_presetRatingChangedEventUserData = user_data; } void projectm_reset_gl(projectm_handle instance, int width, int height) diff --git a/src/libprojectM/ProjectMCWrapper.hpp b/src/libprojectM/ProjectMCWrapper.hpp index 1bd346aa4..3e85476d5 100644 --- a/src/libprojectM/ProjectMCWrapper.hpp +++ b/src/libprojectM/ProjectMCWrapper.hpp @@ -47,4 +47,9 @@ public: projectm_shuffle_enable_changed_event _shuffleEnableChangedEventCallback{ nullptr }; projectm_preset_switch_failed_event _presetSwitchFailedEventCallback{ nullptr }; projectm_preset_rating_changed_event _presetRatingChangedEventCallback{ nullptr }; + + void* _presetSwitchedEventUserData{ nullptr }; + void* _shuffleEnableChangedEventUserData{ nullptr }; + void* _presetSwitchFailedEventUserData{ nullptr }; + void* _presetRatingChangedEventUserData{ nullptr }; }; diff --git a/src/libprojectM/projectM.h b/src/libprojectM/projectM.h index 050dda985..85fbb123b 100644 --- a/src/libprojectM/projectM.h +++ b/src/libprojectM/projectM.h @@ -122,31 +122,32 @@ PROJECTM_EXPORT char* projectm_alloc_string(unsigned int length); /** * @brief Frees the memory of an allocated string. * - * Frees the memory allocated by a call to projectm_alloc_string() or any - * (const) char* pointers returned by an API call. + *

Frees the memory allocated by a call to projectm_alloc_string() or any + * (const) char* pointers returned by an API call.

* - * Do not use free() to delete the pointer! + *

Do not use free() to delete the pointer!

* * @param settings A pointer returned by projectm_alloc_string(). */ PROJECTM_EXPORT void projectm_free_string(const char* str); /** - * @brief Allocates memory for a projectm_settings_t struct and returns the pointer. + * @brief Allocates memory for a projectm_settings struct and returns the pointer. * * To free the allocated memory, call projectm_free_settings(). Do not use free()! * - * @return A pointer to a zero-initialized projectm_settings_t struct. + * @return A pointer to a zero-initialized projectm_settings struct. */ PROJECTM_EXPORT projectm_settings* projectm_alloc_settings(); /** - * @brief Frees the memory of an allocated projectm_settings_t structure. + * @brief Frees the memory of an allocated projectm_settings structure. * - * Frees the memory allocated by a call to projectm_alloc_settings() or any - * projectm_settings_t* returned by an API call. + *

Frees the memory allocated by a call to projectm_alloc_settings() or any + * projectm_settings pointer returned by an API call. Any non-null char pointers + * will also be free'd using projectm_free_string().

* - * Do not use free() to delete the pointer! + *

Do not use free() to delete the pointer!

* * @param settings A pointer returned by projectm_alloc_settings(). */ @@ -160,14 +161,18 @@ PROJECTM_EXPORT void projectm_free_settings(const projectm_settings* settings); * * @param is_hard_cut True if the preset was switched using a hard cut via beat detection. * @param index The playlist index of the new preset. + * @param user_data A user-defined data pointer that was provided when registering the callback, + * e.g. context information. */ -typedef void(* projectm_preset_switched_event)(bool is_hard_cut, unsigned int index); +typedef void(* projectm_preset_switched_event)(bool is_hard_cut, unsigned int index, void* user_data); /** * @brief Callback function that is executed is the shuffle setting has changed. * @param shuffle_enabled True if shuffle is enabled, false if it was disabled. + * @param user_data A user-defined data pointer that was provided when registering the callback, + * e.g. context information. */ -typedef void(* projectm_shuffle_enable_changed_event)(bool shuffle_enabled); +typedef void(* projectm_shuffle_enable_changed_event)(bool shuffle_enabled, void* user_data); /** * @brief Callback function that is executed if a preset change failed. @@ -178,8 +183,11 @@ typedef void(* projectm_shuffle_enable_changed_event)(bool shuffle_enabled); * @param is_hard_cut True if the preset was switched using a hard cut via beat detection. * @param index The playlist index of the new preset. * @param message The error message. + * @param user_data A user-defined data pointer that was provided when registering the callback, + * e.g. context information. */ -typedef void(* projectm_preset_switch_failed_event)(bool is_hard_cut, unsigned int index, const char* message); +typedef void(* projectm_preset_switch_failed_event)(bool is_hard_cut, unsigned int index, const char* message, + void* user_data); /** * @brief Callback function that is executed if a preset rating has been changed. @@ -189,9 +197,11 @@ typedef void(* projectm_preset_switch_failed_event)(bool is_hard_cut, unsigned i * @param index The playlist index of the new preset. * @param rating The new rating value. * @param rating_type The rating type that has been changed. + * @param user_data A user-defined data pointer that was provided when registering the callback, + * e.g. context information. */ typedef void(* projectm_preset_rating_changed_event)(unsigned int index, int rating, - projectm_preset_rating_type rating_type); + projectm_preset_rating_type rating_type, void* user_data); @@ -226,35 +236,55 @@ PROJECTM_EXPORT void projectm_destroy(projectm_handle instance); /** * @brief Sets a callback function that will be called when a preset changes. + * + * Only one callback can be registered per projectM instance. To remove the callback, use NULL. + * * @param instance The projectM instance handle. * @param callback A pointer to the callback function. + * @param user_data A pointer to any data that will be sent back in the callback, e.g. context information. */ PROJECTM_EXPORT void projectm_set_preset_switched_event_callback(projectm_handle instance, - projectm_preset_switched_event callback); + projectm_preset_switched_event callback, + void* user_data); /** * @brief Sets a callback function that will be called when the shuffle setting changes. + * + * Only one callback can be registered per projectM instance. To remove the callback, use NULL. + * * @param instance The projectM instance handle. * @param callback A pointer to the callback function. + * @param user_data A pointer to any data that will be sent back in the callback, e.g. context information. */ PROJECTM_EXPORT void projectm_set_shuffle_enable_changed_event_callback(projectm_handle instance, - projectm_shuffle_enable_changed_event callback); + projectm_shuffle_enable_changed_event callback, + void* user_data); /** * @brief Sets a callback function that will be called when a preset change failed. + * + * Only one callback can be registered per projectM instance. To remove the callback, use NULL. + * * @param instance The projectM instance handle. * @param callback A pointer to the callback function. + * @param user_data A pointer to any data that will be sent back in the callback, e.g. context information. */ PROJECTM_EXPORT void projectm_set_preset_switch_failed_event_callback(projectm_handle instance, - projectm_preset_switch_failed_event callback); + projectm_preset_switch_failed_event callback, + void* user_data); /** * @brief Sets a callback function that will be called when a preset rating changed. + * + * Only one callback can be registered per projectM instance. To remove the callback, use NULL. + * * @param instance The projectM instance handle. * @param callback A pointer to the callback function. + * @param user_data A pointer to any data that will be sent back in the callback, e.g. context information. */ PROJECTM_EXPORT void projectm_set_preset_rating_changed_event_callback(projectm_handle instance, - projectm_preset_rating_changed_event callback); + projectm_preset_rating_changed_event callback, + void* user_data); /** * @brief Reset the projectM OpenGL renderer. diff --git a/src/projectM-sdl/pmSDL.cpp b/src/projectM-sdl/pmSDL.cpp index d863712b3..2c8ead6ad 100644 --- a/src/projectM-sdl/pmSDL.cpp +++ b/src/projectM-sdl/pmSDL.cpp @@ -39,8 +39,7 @@ projectMSDL::projectMSDL(SDL_GLContext glCtx, projectm_settings* settings, int f { width = projectm_get_window_width(_projectM); height = projectm_get_window_height(_projectM); - done = false; - isFullScreen = false; + projectm_set_preset_switched_event_callback(_projectM, &projectMSDL::presetSwitchedEvent, static_cast(this)); } projectMSDL::projectMSDL(SDL_GLContext glCtx, std::string config_file, int flags) @@ -50,8 +49,7 @@ projectMSDL::projectMSDL(SDL_GLContext glCtx, std::string config_file, int flags { width = projectm_get_window_width(_projectM); height = projectm_get_window_height(_projectM); - done = 0; - isFullScreen = false; + projectm_set_preset_switched_event_callback(_projectM, &projectMSDL::presetSwitchedEvent, static_cast(this)); } projectMSDL::~projectMSDL() @@ -521,15 +519,16 @@ std::string projectMSDL::getActivePresetName() return {}; } -void projectMSDL::presetSwitchedEvent(bool isHardCut, size_t index) const +void projectMSDL::presetSwitchedEvent(bool isHardCut, unsigned int index, void* context) { - auto presetName = projectm_get_preset_name(_projectM, index); + auto app = reinterpret_cast(context); + auto presetName = projectm_get_preset_name(app->_projectM, index); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Displaying preset: %s\n", presetName); std::string newTitle = "projectM ➫ " + std::string(presetName); projectm_free_string(presetName); - SDL_SetWindowTitle(win, newTitle.c_str()); + SDL_SetWindowTitle(app->win, newTitle.c_str()); } const projectm_settings* projectMSDL::settings() diff --git a/src/projectM-sdl/pmSDL.hpp b/src/projectM-sdl/pmSDL.hpp index f6aa00ede..e4dcba2a5 100644 --- a/src/projectM-sdl/pmSDL.hpp +++ b/src/projectM-sdl/pmSDL.hpp @@ -128,8 +128,6 @@ public: bool keymod = false; std::string getActivePresetName(); void addFakePCM(); - - virtual void presetSwitchedEvent(bool isHardCut, size_t index) const; const projectm_settings* settings(); @@ -142,6 +140,8 @@ public: SDL_GLContext glCtx{ nullptr }; private: + static void presetSwitchedEvent(bool isHardCut, unsigned int index, void* context); + static void audioInputCallbackF32(void *userdata, unsigned char *stream, int len); static void audioInputCallbackS16(void *userdata, unsigned char *stream, int len);