[Change] FFUUUUU!! Do *NOT* call MIX_* functions from callbacks,

especially when locked! Jeezus!
This commit is contained in:
Allanis 2014-03-10 20:54:40 +00:00
parent 25f0e6f9fe
commit 4003fd7c5f
3 changed files with 73 additions and 11 deletions

View File

@ -4,6 +4,7 @@
*/ */
#include <SDL/SDL_mixer.h> #include <SDL/SDL_mixer.h>
#include <SDL/SDL_mutex.h>
#include <SDL.h> #include <SDL.h>
#include "llua.h" #include "llua.h"
@ -22,9 +23,21 @@
int music_disabled = 0; /**< Whether or not music is disabled. */ int music_disabled = 0; /**< Whether or not music is disabled. */
/* Handle if music should run Lua script. Must be locked to ensure same
* behaviour always!
*/
static SDL_mutex* music_lock = NULL; /**< Lock for music_runLua so it doesn't
run twise in a row with weird
results.
DO NOT CALL MIX* FUNCTIONS WHEN
LOCKED!!!! FUCK!!!! */
static int music_runchoose = 0; /**< Whether or not music should run the choose function. */
static char music_situation[PATH_MAX]; /**< What situation music is in. */
/* Global music lua. */ /* Global music lua. */
static lua_State* music_lua = NULL; /**< The Lua music control state. */ static lua_State* music_lua = NULL; /**< The Lua music control state. */
/* Functions. */ /* Functions. */
static int music_runLua(char* situation);
static int musicL_load(lua_State* L); static int musicL_load(lua_State* L);
static int musicL_play(lua_State* L); static int musicL_play(lua_State* L);
static int musicL_stop(lua_State* L); static int musicL_stop(lua_State* L);
@ -51,6 +64,41 @@ static void music_rechoose(void);
static int music_luaInit(void); static int music_luaInit(void);
static void music_luaQuit(void); static void music_luaQuit(void);
/**
* @brief Update the music.
*/
void music_update(void) {
char buf[PATH_MAX];
/* Lock music and see if it needs to update. */
SDL_mutexP(music_lock);
if(music_runchoose == 0) {
SDL_mutexV(music_lock);
return;
}
music_runchoose = 0;
strncpy(buf, music_situation, PATH_MAX);
SDL_mutexV(music_lock);
music_runLua(buf);
}
/**
* @brief Run the Lua music choose function.
* @param situation Situation in to choose music for.
* @return 0 on success.
*/
static int music_runLua(char* situation) {
/* Run the choose function in Lua. */
lua_getglobal(music_lua, "choose");
lua_pushstring(music_lua, situation);
if(lua_pcall(music_lua, 1, 0, 0)) /* Error has occured. */
WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1));
return 0;
}
/** /**
* @fn int music init(void) * @fn int music init(void)
* *
@ -64,6 +112,9 @@ int music_init(void) {
if(music_luaInit() < 0) return -1; if(music_luaInit() < 0) return -1;
music_volume(0.8); music_volume(0.8);
/* Create the lock. */
music_lock = SDL_CreateMutex();
return 0; return 0;
} }
@ -74,6 +125,12 @@ int music_init(void) {
*/ */
void music_exit(void) { void music_exit(void) {
music_free(); music_free();
/* Destroy the lock. */
if(music_lock != NULL) {
SDL_DestroyMutex(music_lock);
music_lock = NULL;
}
} }
/** /**
@ -303,13 +360,8 @@ int lua_loadMusic(lua_State* L, int read_only) {
int music_choose(char* situation) { int music_choose(char* situation) {
if(music_disabled) return 0; if(music_disabled) return 0;
lua_getglobal(music_lua, "choose"); music_runLua(situation);
lua_pushstring(music_lua, situation);
if(lua_pcall(music_lua, 1, 0, 0)) {
/* Error occured. */
WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1));
return -1;
}
return 0; return 0;
} }
@ -317,9 +369,15 @@ int music_choose(char* situation) {
* @fn static void music_rechoose(void) * @fn static void music_rechoose(void)
* *
* @brief Attempts to rechoose the music. * @brief Attempts to rechoose the music.
*
* ARGH! DO NOT CALL MIX_* FUNCTIONS FROM WITHIN THE CALLBACKS!
*/ */
static void music_rechoose(void) { static void music_rechoose(void) {
music_choose("idle"); /* Lock so it doesn't run in between an update. */
SDL_mutexP(music_lock);
music_runchoose = 1;
strncpy(music_situation, "idle", PATH_MAX);
SDL_mutexV(music_lock);
} }
/* The music lua functions. */ /* The music lua functions. */

View File

@ -3,9 +3,8 @@
extern int music_disabled; extern int music_disabled;
/* Thread. */ /* Updating. */
int music_thread(void* unused); void music_update(void);
void music_kill(void);
/* Init/Exit. */ /* Init/Exit. */
int music_init(void); int music_init(void);

View File

@ -345,6 +345,9 @@ int sound_updatePos(int voice, double x, double y) {
int sound_update(void) { int sound_update(void) {
alVoice* v, *tv; alVoice* v, *tv;
/* Update music if needed. */
music_update();
if(sound_disabled) return 0; if(sound_disabled) return 0;
if(voice_active == NULL) return 0; if(voice_active == NULL) return 0;
@ -627,6 +630,8 @@ void sound_stopGroup(int group) {
* @fn static void voice_markStopped(int channel) * @fn static void voice_markStopped(int channel)
* *
* @brief Mark the voice to which channel belongs to as stopped. * @brief Mark the voice to which channel belongs to as stopped.
*
* URGH! DO NOT CALL MIX_* FUNCTIONS FROM CALLBACKS!
*/ */
static void voice_markStopped(int channel) { static void voice_markStopped(int channel) {
alVoice* v; alVoice* v;