Added config editor in front end
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m46s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
Aiden
2026-05-30 19:33:40 +10:00
parent f0f8b080ca
commit 8ffc011ca0
26 changed files with 1201 additions and 55 deletions

View File

@@ -1,7 +1,9 @@
#pragma once
#include "AppConfig.h"
#include "AppConfigJson.h"
#include "AppConfigProvider.h"
#include "AppRestart.h"
#include "RuntimeLayerController.h"
#include "../logging/Logger.h"
#include "../control/RuntimeStateJson.h"
@@ -10,6 +12,7 @@
#include "VideoIOEdges.h"
#include "VideoOutputThread.h"
#include <atomic>
#include <chrono>
#include <filesystem>
#include <functional>
@@ -56,10 +59,12 @@ public:
RenderThread& renderThread,
SystemFrameExchange& frameExchange,
AppConfig config,
std::unique_ptr<IVideoOutputEdge> output) :
std::unique_ptr<IVideoOutputEdge> output,
std::filesystem::path configPath = std::filesystem::path()) :
mRenderThread(renderThread),
mFrameExchange(frameExchange),
mConfig(config),
mConfigPath(std::move(configPath)),
mOutput(std::move(output)),
mOutputThread(*mOutput, mFrameExchange, VideoOutputThreadConfig{
mConfig.outputThread.targetBufferedFrames,
@@ -242,6 +247,9 @@ private:
callbacks.getStateJson = [this]() {
return BuildStateJson();
};
callbacks.getConfigJson = [this]() {
return BuildConfigJson();
};
callbacks.addLayer = [this](const std::string& body) {
return mRuntimeLayers.HandleAddLayer(body);
};
@@ -249,6 +257,11 @@ private:
return mRuntimeLayers.HandleRemoveLayer(body);
};
callbacks.executePost = [this](const std::string& path, const std::string& body) {
if (path == "/api/config/save")
return HandleConfigSave(body);
if (path == "/api/app/restart")
return HandleAppRestart();
RuntimeControlCommand command;
std::string error;
if (!ParseRuntimeControlCommand(path, body, command, error))
@@ -303,6 +316,56 @@ private:
});
}
std::string BuildConfigJson() const
{
AppConfig diskConfig = mConfig;
std::string loadError;
bool diskLoaded = false;
if (!mConfigPath.empty())
{
AppConfigProvider provider;
diskLoaded = provider.Load(mConfigPath, loadError);
if (diskLoaded)
diskConfig = provider.Config();
}
JsonValue root = JsonValue::MakeObject();
root.set("ok", JsonValue(true));
root.set("path", JsonValue(mConfigPath.string()));
root.set("active", AppConfigToJsonValue(mConfig));
root.set("disk", AppConfigToJsonValue(diskConfig));
root.set("diskLoaded", JsonValue(diskLoaded));
root.set("restartRequired", JsonValue(mRestartRequired.load(std::memory_order_relaxed)));
if (!loadError.empty())
root.set("error", JsonValue(loadError));
return SerializeJson(root);
}
ControlActionResult HandleConfigSave(const std::string& body)
{
AppConfig nextConfig;
std::string error;
if (!ParseAppConfigJson(body, nextConfig, error))
return ControlActionResult{ false, error };
if (!SaveAppConfigToFile(nextConfig, mConfigPath, error))
return ControlActionResult{ false, error };
mRestartRequired.store(true, std::memory_order_relaxed);
Log("app", "Saved runtime host config to " + mConfigPath.string() + "; restart required for startup-owned services.");
return ControlActionResult{ true };
}
ControlActionResult HandleAppRestart()
{
std::string error;
if (!ScheduleProcessRestart(error))
return ControlActionResult{ false, error };
Log("app", "App restart requested from HTTP control.");
return ControlActionResult{ true };
}
void ApplyVideoInputMetrics(CadenceTelemetrySnapshot& telemetry)
{
if (!mVideoInputMetricsProvider)
@@ -335,6 +398,7 @@ private:
RenderThread& mRenderThread;
SystemFrameExchange& mFrameExchange;
AppConfig mConfig;
std::filesystem::path mConfigPath;
std::unique_ptr<IVideoOutputEdge> mOutput;
VideoOutputThread<SystemFrameExchange> mOutputThread;
TelemetryHealthMonitor mTelemetryHealth;
@@ -344,6 +408,7 @@ private:
RuntimeLayerController mRuntimeLayers;
std::function<VideoInputEdgeMetrics()> mVideoInputMetricsProvider;
uint64_t mLastInputCapturedFrames = 0;
std::atomic<bool> mRestartRequired{ false };
bool mStarted = false;
bool mVideoOutputEnabled = false;
std::string mVideoOutputStatus = "Video output not started.";