From 7b1548af3cdda7f0023510a9ec12813a137a1668 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 30 Nov 2018 21:39:59 -0800 Subject: Handle source state changed events uniquely in the event loop To avoid the need of constructing the string in the mixer thread, which is commonly formatted anyway. --- OpenAL32/Include/alMain.h | 10 +++++++--- OpenAL32/alSource.cpp | 18 +++++------------- OpenAL32/event.cpp | 21 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 17 deletions(-) (limited to 'OpenAL32') diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 898c8a08..bff3d52e 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -841,10 +841,14 @@ enum { EventType_ReleaseEffectState = 65536, }; -typedef struct AsyncEvent { +struct AsyncEvent { unsigned int EnumType; union { char dummy; + struct { + ALuint id; + ALenum state; + } srcstate; struct { ALenum type; ALuint id; @@ -853,8 +857,8 @@ typedef struct AsyncEvent { } user; EffectState *mEffectState; } u; -} AsyncEvent; -#define ASYNC_EVENT(t) { t, { 0 } } +}; +#define ASYNC_EVENT(t) AsyncEvent{ t, { 0 } } void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends); diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index 87729c73..11cea945 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -684,21 +684,13 @@ inline bool SourceShouldUpdate(ALsource *source, ALCcontext *context) /** Can only be called while the mixer is locked! */ void SendStateChangeEvent(ALCcontext *context, ALuint id, ALenum state) { - AsyncEvent evt = ASYNC_EVENT(EventType_SourceStateChange); - ALbitfieldSOFT enabledevt; - - enabledevt = context->EnabledEvts.load(std::memory_order_acquire); + ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)}; if(!(enabledevt&EventType_SourceStateChange)) return; - evt.u.user.type = AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT; - evt.u.user.id = id; - evt.u.user.param = state; - snprintf(evt.u.user.msg, sizeof(evt.u.user.msg), "Source ID %u state changed to %s", id, - (state==AL_INITIAL) ? "AL_INITIAL" : - (state==AL_PLAYING) ? "AL_PLAYING" : - (state==AL_PAUSED) ? "AL_PAUSED" : - (state==AL_STOPPED) ? "AL_STOPPED" : "" - ); + AsyncEvent evt{ASYNC_EVENT(EventType_SourceStateChange)}; + evt.u.srcstate.id = id; + evt.u.srcstate.state = state; + /* The mixer may have queued a state change that's not yet been processed, * and we don't want state change messages to occur out of order, so send * it through the async queue to ensure proper ordering. diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp index b7599a02..4980abee 100644 --- a/OpenAL32/event.cpp +++ b/OpenAL32/event.cpp @@ -39,7 +39,26 @@ static int EventThread(ALCcontext *context) } ALbitfieldSOFT enabledevts{context->EnabledEvts.load(std::memory_order_acquire)}; - if(context->EventCb && (enabledevts&evt.EnumType) == evt.EnumType) + if(!context->EventCb) continue; + + if(evt.EnumType == EventType_SourceStateChange) + { + if(!(enabledevts&EventType_SourceStateChange)) + continue; + char msg[1024]{}; + int msglen{snprintf(msg, sizeof(msg), "Source ID %u state changed to %s", + evt.u.srcstate.id, + (evt.u.srcstate.state==AL_INITIAL) ? "AL_INITIAL" : + (evt.u.srcstate.state==AL_PLAYING) ? "AL_PLAYING" : + (evt.u.srcstate.state==AL_PAUSED) ? "AL_PAUSED" : + (evt.u.srcstate.state==AL_STOPPED) ? "AL_STOPPED" : "" + )}; + if(msglen < 1) msglen = strlen(msg); + context->EventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.u.srcstate.id, + evt.u.srcstate.state, msglen, msg, context->EventParam + ); + } + else if((enabledevts&evt.EnumType) == evt.EnumType) context->EventCb(evt.u.user.type, evt.u.user.id, evt.u.user.param, (ALsizei)strlen(evt.u.user.msg), evt.u.user.msg, context->EventParam ); -- cgit v1.2.3