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 /core | |
parent | e1e375e5238282c36ab7dddf148461c4370de39d (diff) |
Use a variant for AsyncEvent
Diffstat (limited to 'core')
-rw-r--r-- | core/async_event.h | 89 | ||||
-rw-r--r-- | core/context.h | 3 | ||||
-rw-r--r-- | core/voice.cpp | 20 |
3 files changed, 59 insertions, 53 deletions
diff --git a/core/async_event.h b/core/async_event.h index 5a2f5f91..9e2d1193 100644 --- a/core/async_event.h +++ b/core/async_event.h @@ -1,6 +1,9 @@ #ifndef CORE_EVENT_H #define CORE_EVENT_H +#include <stdint.h> +#include <variant> + #include "almalloc.h" struct EffectState; @@ -8,48 +11,50 @@ struct EffectState; using uint = unsigned int; -struct AsyncEvent { - enum : uint { - /* User event types. */ - SourceStateChange, - BufferCompleted, - Disconnected, - UserEventCount, - - /* Internal events, always processed. */ - ReleaseEffectState = 128, - - /* End event thread processing. */ - KillThread, - }; - - enum class SrcState { - Reset, - Stop, - Play, - Pause - }; - - const uint EnumType; - union { - char dummy; - struct { - uint id; - SrcState state; - } srcstate; - struct { - uint id; - uint count; - } bufcomp; - struct { - char msg[244]; - } disconnect; - EffectState *mEffectState; - } u{}; - - constexpr AsyncEvent(uint type) noexcept : EnumType{type} { } - - DISABLE_ALLOC() +enum class AsyncEnableBits : uint8_t { + SourceState, + BufferCompleted, + Disconnected, + + Count +}; + + +enum class AsyncSrcState : uint8_t { + Reset, + Stop, + Play, + Pause +}; + +using AsyncKillThread = std::monostate; + +struct AsyncSourceStateEvent { + uint mId; + AsyncSrcState mState; }; +struct AsyncBufferCompleteEvent { + uint mId; + uint mCount; +}; + +struct AsyncDisconnectEvent { + char msg[244]; +}; + +struct AsyncEffectReleaseEvent { + EffectState *mEffectState; +}; + +using AsyncEvent = std::variant<AsyncKillThread, + AsyncSourceStateEvent, + AsyncBufferCompleteEvent, + AsyncEffectReleaseEvent, + AsyncDisconnectEvent>; + +template<typename T, typename ...Args> +auto &InitAsyncEvent(AsyncEvent *evt, Args&& ...args) +{ return std::get<T>(*al::construct_at(evt, std::in_place_type<T>, std::forward<Args>(args)...)); } + #endif diff --git a/core/context.h b/core/context.h index 9723eac3..4febd38d 100644 --- a/core/context.h +++ b/core/context.h @@ -13,6 +13,7 @@ #include "async_event.h" #include "atomic.h" #include "bufferline.h" +#include "opthelpers.h" #include "threads.h" #include "vecmat.h" #include "vector.h" @@ -137,7 +138,7 @@ struct ContextBase { std::thread mEventThread; al::semaphore mEventSem; std::unique_ptr<RingBuffer> mAsyncEvents; - using AsyncEventBitset = std::bitset<AsyncEvent::UserEventCount>; + using AsyncEventBitset = std::bitset<al::to_underlying(AsyncEnableBits::Count)>; std::atomic<AsyncEventBitset> mEnabledEvts{0u}; /* Asynchronous voice change actions are processed as a linked list of diff --git a/core/voice.cpp b/core/voice.cpp index 478ea81f..3e78b176 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -226,10 +226,10 @@ void SendSourceStoppedEvent(ContextBase *context, uint id) auto evt_vec = ring->getWriteVector(); if(evt_vec.first.len < 1) return; - AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf), - AsyncEvent::SourceStateChange)}; - evt->u.srcstate.id = id; - evt->u.srcstate.state = AsyncEvent::SrcState::Stop; + AsyncSourceStateEvent &evt = InitAsyncEvent<AsyncSourceStateEvent>( + reinterpret_cast<AsyncEvent*>(evt_vec.first.buf)); + evt.mId = id; + evt.mState = AsyncSrcState::Stop; ring->writeAdvance(1); } @@ -1145,16 +1145,16 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi /* Send any events now, after the position/buffer info was updated. */ const auto enabledevt = Context->mEnabledEvts.load(std::memory_order_acquire); - if(buffers_done > 0 && enabledevt.test(AsyncEvent::BufferCompleted)) + if(buffers_done > 0 && enabledevt.test(al::to_underlying(AsyncEnableBits::BufferCompleted))) { RingBuffer *ring{Context->mAsyncEvents.get()}; auto evt_vec = ring->getWriteVector(); if(evt_vec.first.len > 0) { - AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf), - AsyncEvent::BufferCompleted)}; - evt->u.bufcomp.id = SourceID; - evt->u.bufcomp.count = buffers_done; + AsyncBufferCompleteEvent &evt = InitAsyncEvent<AsyncBufferCompleteEvent>( + reinterpret_cast<AsyncEvent*>(evt_vec.first.buf)); + evt.mId = SourceID; + evt.mCount = buffers_done; ring->writeAdvance(1); } } @@ -1165,7 +1165,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi * ensures any residual noise fades to 0 amplitude. */ mPlayState.store(Stopping, std::memory_order_release); - if(enabledevt.test(AsyncEvent::SourceStateChange)) + if(enabledevt.test(al::to_underlying(AsyncEnableBits::SourceState))) SendSourceStoppedEvent(Context, SourceID); } } |