We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2462 - make Mix_ChannelFinished work in C++
Summary: make Mix_ChannelFinished work in C++
Status: ASSIGNED
Alias: None
Product: SDL_mixer
Classification: Unclassified
Component: misc (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Assignee: Ryan C. Gordon
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-23 13:38 UTC by Daniel Sobe
Modified: 2017-10-28 20:36 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Sobe 2014-03-23 13:38:43 UTC
Hi,

I suggest to change the Mix_ChannelFinished callback (or add a new appropriate one if API compatibility is a must). The patch below changes the callback to also carry a void* argument, so that C++ objects can be supplied, and thus C++ can utilize the callback.

--- SDL_mixer/SDL_mixer.h	2014-03-23 14:04:43.089323652 +0100
+++ SDL_mixer_new/SDL_mixer.h	2014-03-23 11:04:40.000000000 +0100
@@ -223,7 +223,7 @@
  *  inside the audio callback, or SDL_mixer will explicitly lock the audio
  *  before calling your callback.
  */
-extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (*channel_finished)(int channel));
+extern DECLSPEC void SDLCALL Mix_ChannelFinished(void *userdata, void (*channel_finished)(void *userdata, int channel));
 
 
 /* Special Effects API by ryan c. gordon. (icculus@icculus.org) */

--- SDL_mixer/mixer.c	2014-03-23 14:04:46.421417431 +0100
+++ SDL_mixer_new/mixer.c	2014-03-23 11:17:49.000000000 +0100
@@ -93,7 +94,8 @@
 static void *mix_postmix_data = NULL;
 
 /* rcg07062001 callback to alert when channels are done playing. */
-static void (*channel_done_callback)(int channel) = NULL;
+static void (*channel_done_callback)(void *userdata, int channel) = NULL;
+static void *channel_done_callback_userdata;
 
 /* Music function declarations */
 extern int open_music(SDL_AudioSpec *mixer);
@@ -261,7 +317,7 @@
 static void _Mix_channel_done_playing(int channel)
 {
     if (channel_done_callback) {
-        channel_done_callback(channel);
+        channel_done_callback(channel_done_callback_userdata, channel);
     }
 
     /*
@@ -842,10 +903,11 @@
     return(music_data);
 }
 
-void Mix_ChannelFinished(void (*channel_finished)(int channel))
+void Mix_ChannelFinished(void *userdata, void (*channel_finished)(void *userdata, int channel))
 {
     SDL_LockAudio();
     channel_done_callback = channel_finished;
+    channel_done_callback_userdata = userdata;
     SDL_UnlockAudio();
 }
Comment 1 Sam Lantinga 2017-10-21 20:07:05 UTC
This is a good idea, but needs to wait for a breaking ABI rev
Comment 2 Ivan Epifanov 2017-10-28 20:36:55 UTC
Having userdata in callback would be great not only from c++ POV.
But, you can use this in c++ even now by utilizing std::bind and some more magic. See https://github.com/falltergeist/falltergeist/blob/develop/src/Audio/Mixer.cpp#L154 for example.