diff options
author | Chris Robinson <[email protected]> | 2023-05-08 20:01:14 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-05-08 20:01:14 -0700 |
commit | d2b000c7602bcc337a4f4e5590ef65c1cfcb4cb2 (patch) | |
tree | 8caeb4a6d06f8d017bd3c2c0e286e6d8cab1fa23 /al/event.cpp | |
parent | e1e375e5238282c36ab7dddf148461c4370de39d (diff) |
Use a variant for AsyncEvent
Diffstat (limited to 'al/event.cpp')
-rw-r--r-- | al/event.cpp | 94 |
1 files changed, 54 insertions, 40 deletions
diff --git a/al/event.cpp b/al/event.cpp index 4fa1bf56..eb6af45c 100644 --- a/al/event.cpp +++ b/al/event.cpp @@ -32,7 +32,15 @@ #include "threads.h" -static int EventThread(ALCcontext *context) +namespace { + +template<typename... Ts> +struct overloaded : Ts... { using Ts::operator()...; }; + +template<typename... Ts> +overloaded(Ts...) -> overloaded<Ts...>; + +int EventThread(ALCcontext *context) { RingBuffer *ring{context->mAsyncEvents.get()}; bool quitnow{false}; @@ -51,81 +59,87 @@ static int EventThread(ALCcontext *context) evt_data.buf += sizeof(AsyncEvent); evt_data.len -= 1; - AsyncEvent evt{*evt_ptr}; + AsyncEvent event{std::move(*evt_ptr)}; std::destroy_at(evt_ptr); ring->readAdvance(1); - quitnow = evt.EnumType == AsyncEvent::KillThread; + quitnow = std::holds_alternative<AsyncKillThread>(event); if(quitnow) UNLIKELY break; - if(evt.EnumType == AsyncEvent::ReleaseEffectState) - { - al::intrusive_ptr<EffectState>{evt.u.mEffectState}; - continue; - } - auto enabledevts = context->mEnabledEvts.load(std::memory_order_acquire); - if(!context->mEventCb) continue; - - if(evt.EnumType == AsyncEvent::SourceStateChange) + auto proc_killthread = [](AsyncKillThread&) { }; + auto proc_release = [](AsyncEffectReleaseEvent &evt) + { + al::intrusive_ptr<EffectState>{evt.mEffectState}; + }; + auto proc_srcstate = [context,enabledevts](AsyncSourceStateEvent &evt) { - if(!enabledevts.test(AsyncEvent::SourceStateChange)) - continue; + if(!context->mEventCb + || !enabledevts.test(al::to_underlying(AsyncEnableBits::SourceState))) + return; ALuint state{}; - std::string msg{"Source ID " + std::to_string(evt.u.srcstate.id)}; + std::string msg{"Source ID " + std::to_string(evt.mId)}; msg += " state has changed to "; - switch(evt.u.srcstate.state) + switch(evt.mState) { - case AsyncEvent::SrcState::Reset: + case AsyncSrcState::Reset: msg += "AL_INITIAL"; state = AL_INITIAL; break; - case AsyncEvent::SrcState::Stop: + case AsyncSrcState::Stop: msg += "AL_STOPPED"; state = AL_STOPPED; break; - case AsyncEvent::SrcState::Play: + case AsyncSrcState::Play: msg += "AL_PLAYING"; state = AL_PLAYING; break; - case AsyncEvent::SrcState::Pause: + case AsyncSrcState::Pause: msg += "AL_PAUSED"; state = AL_PAUSED; break; } - context->mEventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.u.srcstate.id, - state, static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam); - } - else if(evt.EnumType == AsyncEvent::BufferCompleted) + context->mEventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.mId, state, + static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam); + }; + auto proc_buffercomp = [context,enabledevts](AsyncBufferCompleteEvent &evt) { - if(!enabledevts.test(AsyncEvent::BufferCompleted)) - continue; + if(!context->mEventCb + || !enabledevts.test(al::to_underlying(AsyncEnableBits::BufferCompleted))) + return; - std::string msg{std::to_string(evt.u.bufcomp.count)}; - if(evt.u.bufcomp.count == 1) msg += " buffer completed"; + std::string msg{std::to_string(evt.mCount)}; + if(evt.mCount == 1) msg += " buffer completed"; else msg += " buffers completed"; - context->mEventCb(AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT, evt.u.bufcomp.id, - evt.u.bufcomp.count, static_cast<ALsizei>(msg.length()), msg.c_str(), - context->mEventParam); - } - else if(evt.EnumType == AsyncEvent::Disconnected) + context->mEventCb(AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT, evt.mId, evt.mCount, + static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam); + }; + auto proc_disconnect = [context,enabledevts](AsyncDisconnectEvent &evt) { - const std::string_view message{evt.u.disconnect.msg}; + const std::string_view message{evt.msg}; context->debugMessage(DebugSource::System, DebugType::Error, 0, DebugSeverity::High, static_cast<ALsizei>(message.length()), message.data()); - if(enabledevts.test(AsyncEvent::Disconnected)) + if(context->mEventCb + && enabledevts.test(al::to_underlying(AsyncEnableBits::Disconnected))) context->mEventCb(AL_EVENT_TYPE_DISCONNECTED_SOFT, 0, 0, static_cast<ALsizei>(message.length()), message.data(), context->mEventParam); - } + }; + + std::visit(overloaded + {proc_srcstate, proc_buffercomp, proc_release, proc_disconnect, proc_killthread}, + event); } while(evt_data.len != 0); } return 0; } +} // namespace + + void StartEventThrd(ALCcontext *ctx) { try { @@ -150,7 +164,7 @@ void StopEventThrd(ALCcontext *ctx) evt_data = ring->getWriteVector().first; } while(evt_data.len == 0); } - al::construct_at(reinterpret_cast<AsyncEvent*>(evt_data.buf), AsyncEvent::KillThread); + std::ignore = InitAsyncEvent<AsyncKillThread>(reinterpret_cast<AsyncEvent*>(evt_data.buf)); ring->writeAdvance(1); ctx->mEventSem.post(); @@ -174,11 +188,11 @@ START_API_FUNC [&flags](ALenum type) noexcept -> bool { if(type == AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT) - flags.set(AsyncEvent::BufferCompleted); + flags.set(al::to_underlying(AsyncEnableBits::BufferCompleted)); else if(type == AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT) - flags.set(AsyncEvent::SourceStateChange); + flags.set(al::to_underlying(AsyncEnableBits::SourceState)); else if(type == AL_EVENT_TYPE_DISCONNECTED_SOFT) - flags.set(AsyncEvent::Disconnected); + flags.set(al::to_underlying(AsyncEnableBits::Disconnected)); else return false; return true; |