event dispatcher
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m37s
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
Aiden
2026-05-11 15:15:42 +10:00
parent 5503ce85a9
commit b3705d96cc
20 changed files with 1617 additions and 10 deletions

View File

@@ -0,0 +1,117 @@
#pragma once
#include "RuntimeEventQueue.h"
#include <atomic>
#include <functional>
#include <map>
#include <mutex>
#include <vector>
struct RuntimeEventDispatchResult
{
std::size_t dispatchedEvents = 0;
std::size_t handlerInvocations = 0;
std::size_t handlerFailures = 0;
};
class RuntimeEventDispatcher
{
public:
using Handler = std::function<void(const RuntimeEvent&)>;
explicit RuntimeEventDispatcher(std::size_t queueCapacity = 1024) :
mQueue(queueCapacity)
{
}
bool Publish(RuntimeEvent event)
{
if (!event.PayloadMatchesType())
return false;
if (event.sequence == 0)
event.sequence = mNextSequence.fetch_add(1);
return mQueue.Push(std::move(event));
}
template <typename Payload>
bool PublishPayload(Payload payload, std::string source = {})
{
return Publish(MakeRuntimeEvent(std::move(payload), std::move(source)));
}
void Subscribe(RuntimeEventType type, Handler handler)
{
std::lock_guard<std::mutex> lock(mHandlerMutex);
mHandlers[type].push_back(std::move(handler));
}
void SubscribeAll(Handler handler)
{
std::lock_guard<std::mutex> lock(mHandlerMutex);
mAllHandlers.push_back(std::move(handler));
}
RuntimeEventDispatchResult DispatchPending(std::size_t maxEvents = 0)
{
RuntimeEventDispatchResult result;
std::vector<RuntimeEvent> events = mQueue.Drain(maxEvents);
result.dispatchedEvents = events.size();
for (const RuntimeEvent& event : events)
{
std::vector<Handler> handlers = HandlersFor(event.type);
result.handlerInvocations += handlers.size();
for (const Handler& handler : handlers)
{
try
{
handler(event);
}
catch (...)
{
++result.handlerFailures;
}
}
}
return result;
}
bool TryPop(RuntimeEvent& event)
{
return mQueue.TryPop(event);
}
RuntimeEventQueueMetrics GetQueueMetrics(std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now()) const
{
return mQueue.GetMetrics(now);
}
std::size_t QueueDepth() const
{
return mQueue.Depth();
}
private:
std::vector<Handler> HandlersFor(RuntimeEventType type) const
{
std::lock_guard<std::mutex> lock(mHandlerMutex);
std::vector<Handler> handlers = mAllHandlers;
const auto found = mHandlers.find(type);
if (found != mHandlers.end())
handlers.insert(handlers.end(), found->second.begin(), found->second.end());
return handlers;
}
RuntimeEventQueue mQueue;
std::atomic<uint64_t> mNextSequence{ 1 };
mutable std::mutex mHandlerMutex;
std::map<RuntimeEventType, std::vector<Handler>> mHandlers;
std::vector<Handler> mAllHandlers;
};