phase 2 progress
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m26s
CI / Windows Release Package (push) Successful in 2m30s

This commit is contained in:
Aiden
2026-05-11 16:18:34 +10:00
parent 6e600be112
commit d4f6a4a268
16 changed files with 463 additions and 140 deletions

View File

@@ -246,6 +246,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::LoadStackPreset(const std::string&
RuntimeCoordinatorResult RuntimeCoordinator::RequestShaderReload(bool preserveFeedbackState)
{
std::lock_guard<std::mutex> lock(mMutex);
PublishManualReloadRequested(preserveFeedbackState, "RequestShaderReload");
RuntimeCoordinatorResult result = BuildQueuedReloadResult(preserveFeedbackState);
PublishCoordinatorFollowUpEvents("RequestShaderReload", result);
return result;
@@ -266,6 +267,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::PollRuntimeStoreChanges(bool& regis
if (reloadRequested)
{
PublishFileChangeDetected("PollRuntimeStoreChanges", registryChanged, reloadRequested);
RuntimeCoordinatorResult result = BuildQueuedReloadResult(false);
PublishCoordinatorFollowUpEvents("PollRuntimeStoreChanges", result);
return result;
@@ -273,6 +275,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::PollRuntimeStoreChanges(bool& regis
if (registryChanged)
{
PublishFileChangeDetected("PollRuntimeStoreChanges", registryChanged, reloadRequested);
RuntimeCoordinatorResult result = BuildAcceptedNoReloadResult();
PublishCoordinatorFollowUpEvents("PollRuntimeStoreChanges", result);
return result;
@@ -332,6 +335,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildSuccess()
RuntimeCoordinatorResult RuntimeCoordinator::HandleRuntimeReloadRequest()
{
std::lock_guard<std::mutex> lock(mMutex);
PublishManualReloadRequested(false, "HandleRuntimeReloadRequest");
RuntimeCoordinatorResult result = BuildQueuedReloadResult(false);
PublishCoordinatorFollowUpEvents("HandleRuntimeReloadRequest", result);
return result;
@@ -493,6 +497,36 @@ RuntimeCoordinatorResult RuntimeCoordinator::BuildAcceptedNoReloadResult() const
return result;
}
void RuntimeCoordinator::PublishFileChangeDetected(const std::string& reason, bool registryChanged, bool reloadRequested) const
{
try
{
FileChangeDetectedEvent event;
event.path = reason;
event.shaderPackageCandidate = registryChanged || reloadRequested;
event.runtimeConfigCandidate = false;
event.presetCandidate = false;
mRuntimeEventDispatcher.PublishPayload(event, "RuntimeCoordinator");
}
catch (...)
{
}
}
void RuntimeCoordinator::PublishManualReloadRequested(bool preserveFeedbackState, const std::string& reason) const
{
try
{
ManualReloadRequestedEvent event;
event.preserveFeedbackState = preserveFeedbackState;
event.reason = reason;
mRuntimeEventDispatcher.PublishPayload(event, "RuntimeCoordinator");
}
catch (...)
{
}
}
void RuntimeCoordinator::PublishCoordinatorResult(const std::string& action, const RuntimeCoordinatorResult& result) const
{
try

View File

@@ -93,6 +93,8 @@ private:
RuntimeCoordinatorResult ApplyStoreMutation(bool succeeded, const std::string& errorMessage, bool reloadRequired, bool preserveFeedbackState, bool persistenceRequested);
RuntimeCoordinatorResult BuildQueuedReloadResult(bool preserveFeedbackState);
RuntimeCoordinatorResult BuildAcceptedNoReloadResult() const;
void PublishFileChangeDetected(const std::string& reason, bool registryChanged, bool reloadRequested) const;
void PublishManualReloadRequested(bool preserveFeedbackState, const std::string& reason) const;
void PublishCoordinatorResult(const std::string& action, const RuntimeCoordinatorResult& result) const;
void PublishCoordinatorFollowUpEvents(const std::string& action, const RuntimeCoordinatorResult& result) const;

View File

@@ -29,6 +29,17 @@ inline std::string RuntimeEventDefaultCoalescingKey(const RuntimeEvent& event)
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->routeKey;
if (const auto* payload = std::get_if<FileChangeDetectedEvent>(&event.payload))
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->path;
if (const auto* payload = std::get_if<ShaderBuildEvent>(&event.payload))
return std::string(RuntimeEventTypeName(event.type)) + ":" +
std::to_string(payload->inputWidth) + "x" +
std::to_string(payload->inputHeight) + ":" +
(payload->preserveFeedbackState ? "preserve" : "reset");
if (const auto* payload = std::get_if<RenderSnapshotPublishRequestedEvent>(&event.payload))
return std::string(RuntimeEventTypeName(event.type)) + ":" +
std::to_string(payload->outputWidth) + "x" +
std::to_string(payload->outputHeight);
if (const auto* payload = std::get_if<TimingSampleRecordedEvent>(&event.payload))
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->subsystem + ":" + payload->metric;
if (const auto* payload = std::get_if<QueueDepthChangedEvent>(&event.payload))
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->queueName;

View File

@@ -1,7 +1,9 @@
#pragma once
#include "RuntimeEventCoalescingQueue.h"
#include "RuntimeEventQueue.h"
#include <algorithm>
#include <atomic>
#include <functional>
#include <map>
@@ -22,7 +24,8 @@ public:
using Handler = std::function<void(const RuntimeEvent&)>;
explicit RuntimeEventDispatcher(std::size_t queueCapacity = 1024) :
mQueue(queueCapacity)
mQueue(queueCapacity),
mCoalescingQueue(queueCapacity)
{
}
@@ -34,6 +37,9 @@ public:
if (event.sequence == 0)
event.sequence = mNextSequence.fetch_add(1);
if (ShouldCoalesce(event))
return mCoalescingQueue.Push(std::move(event));
return mQueue.Push(std::move(event));
}
@@ -59,6 +65,7 @@ public:
{
const auto startedAt = std::chrono::steady_clock::now();
RuntimeEventDispatchResult result;
FlushCoalescedToFifo(maxEvents);
std::vector<RuntimeEvent> events = mQueue.Drain(maxEvents);
result.dispatchedEvents = events.size();
@@ -92,15 +99,56 @@ public:
RuntimeEventQueueMetrics GetQueueMetrics(std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now()) const
{
return mQueue.GetMetrics(now);
RuntimeEventQueueMetrics metrics = mQueue.GetMetrics(now);
const RuntimeEventCoalescingQueueMetrics coalescingMetrics = mCoalescingQueue.GetMetrics(now);
if (metrics.depth == 0)
metrics.oldestEventAgeMilliseconds = coalescingMetrics.oldestEventAgeMilliseconds;
else if (coalescingMetrics.depth > 0)
metrics.oldestEventAgeMilliseconds = (std::max)(metrics.oldestEventAgeMilliseconds, coalescingMetrics.oldestEventAgeMilliseconds);
metrics.depth += coalescingMetrics.depth;
metrics.capacity += coalescingMetrics.capacity;
metrics.droppedCount += coalescingMetrics.droppedCount;
metrics.coalescedCount = coalescingMetrics.coalescedCount;
return metrics;
}
std::size_t QueueDepth() const
{
return mQueue.Depth();
return mQueue.Depth() + mCoalescingQueue.Depth();
}
private:
static bool ShouldCoalesce(const RuntimeEvent& event)
{
switch (event.type)
{
case RuntimeEventType::OscValueReceived:
case RuntimeEventType::OscCommitRequested:
case RuntimeEventType::RuntimeStateBroadcastRequested:
case RuntimeEventType::FileChangeDetected:
case RuntimeEventType::RuntimeReloadRequested:
case RuntimeEventType::ShaderBuildRequested:
case RuntimeEventType::RenderSnapshotPublishRequested:
case RuntimeEventType::TimingSampleRecorded:
case RuntimeEventType::QueueDepthChanged:
return true;
default:
return false;
}
}
void FlushCoalescedToFifo(std::size_t maxEvents)
{
const std::size_t fifoDepth = mQueue.Depth();
if (maxEvents != 0 && fifoDepth >= maxEvents)
return;
const std::size_t flushLimit = maxEvents == 0 ? 0 : maxEvents - fifoDepth;
std::vector<RuntimeEvent> events = mCoalescingQueue.Drain(flushLimit);
for (RuntimeEvent& event : events)
mQueue.Push(std::move(event));
}
std::vector<Handler> HandlersFor(RuntimeEventType type) const
{
std::lock_guard<std::mutex> lock(mHandlerMutex);
@@ -114,6 +162,7 @@ private:
}
RuntimeEventQueue mQueue;
RuntimeEventCoalescingQueue mCoalescingQueue;
std::atomic<uint64_t> mNextSequence{ 1 };
mutable std::mutex mHandlerMutex;
std::map<RuntimeEventType, std::vector<Handler>> mHandlers;

View File

@@ -13,6 +13,7 @@ struct RuntimeEventQueueMetrics
std::size_t depth = 0;
std::size_t capacity = 0;
std::size_t droppedCount = 0;
std::size_t coalescedCount = 0;
double oldestEventAgeMilliseconds = 0.0;
};