aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-05-08 20:01:14 -0700
committerChris Robinson <[email protected]>2023-05-08 20:01:14 -0700
commitd2b000c7602bcc337a4f4e5590ef65c1cfcb4cb2 (patch)
tree8caeb4a6d06f8d017bd3c2c0e286e6d8cab1fa23 /core
parente1e375e5238282c36ab7dddf148461c4370de39d (diff)
Use a variant for AsyncEvent
Diffstat (limited to 'core')
-rw-r--r--core/async_event.h89
-rw-r--r--core/context.h3
-rw-r--r--core/voice.cpp20
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);
}
}