#pragma once #include "HealthTelemetry.h" #include "RuntimeJson.h" #include "ShaderTypes.h" #include #include #include #include #include #include #include #include class RuntimeStore; class RuntimeSnapshotProvider; class RuntimeHost { public: RuntimeHost(); void SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName); bool TrySetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName); void SetDeckLinkOutputStatus(const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage); void SetVideoIOStatus(const std::string& backendName, const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying, bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage); void SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds); bool TrySetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds); void SetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); bool TrySetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); HealthTelemetry& GetHealthTelemetry() { return mHealthTelemetry; } const HealthTelemetry& GetHealthTelemetry() const { return mHealthTelemetry; } const std::filesystem::path& GetRepoRoot() const { return mRepoRoot; } const std::filesystem::path& GetUiRoot() const { return mUiRoot; } const std::filesystem::path& GetDocsRoot() const { return mDocsRoot; } const std::filesystem::path& GetRuntimeRoot() const { return mRuntimeRoot; } unsigned short GetServerPort() const { return mServerPort; } unsigned short GetOscPort() const { return mConfig.oscPort; } const std::string& GetOscBindAddress() const { return mConfig.oscBindAddress; } double GetOscSmoothing() const { return mConfig.oscSmoothing; } unsigned GetMaxTemporalHistoryFrames() const { return mConfig.maxTemporalHistoryFrames; } unsigned GetPreviewFps() const { return mConfig.previewFps; } bool ExternalKeyingEnabled() const { return mConfig.enableExternalKeying; } const std::string& GetInputVideoFormat() const { return mConfig.inputVideoFormat; } const std::string& GetInputFrameRate() const { return mConfig.inputFrameRate; } const std::string& GetOutputVideoFormat() const { return mConfig.outputVideoFormat; } const std::string& GetOutputFrameRate() const { return mConfig.outputFrameRate; } void SetServerPort(unsigned short port); bool AutoReloadEnabled() const { return mAutoReloadEnabled; } private: struct AppConfig { std::string shaderLibrary = "shaders"; unsigned short serverPort = 8080; unsigned short oscPort = 9000; std::string oscBindAddress = "127.0.0.1"; double oscSmoothing = 0.18; bool autoReload = true; unsigned maxTemporalHistoryFrames = 4; unsigned previewFps = 30; bool enableExternalKeying = false; std::string inputVideoFormat = "1080p"; std::string inputFrameRate = "59.94"; std::string outputVideoFormat = "1080p"; std::string outputFrameRate = "59.94"; }; struct LayerPersistentState { std::string id; std::string shaderId; bool bypass = false; std::map parameterValues; }; struct PersistentState { std::vector layers; }; bool LoadConfig(std::string& error); bool LoadPersistentState(std::string& error); bool SavePersistentState(std::string& error) const; bool ScanShaderPackages(std::string& error); bool NormalizeAndValidateValue(const ShaderParameterDefinition& definition, const JsonValue& value, ShaderParameterValue& normalizedValue, std::string& error) const; ShaderParameterValue DefaultValueForDefinition(const ShaderParameterDefinition& definition) const; void EnsureLayerDefaultsLocked(LayerPersistentState& layerState, const ShaderPackage& shaderPackage) const; std::string ReadTextFile(const std::filesystem::path& path, std::string& error) const; bool WriteTextFile(const std::filesystem::path& path, const std::string& contents, std::string& error) const; bool ResolvePaths(std::string& error); JsonValue SerializeLayerStackLocked() const; bool DeserializeLayerStackLocked(const JsonValue& layersValue, std::vector& layers, std::string& error); void NormalizePersistentLayerIdsLocked(); std::vector GetStackPresetNamesLocked() const; std::string MakeSafePresetFileStem(const std::string& presetName) const; JsonValue SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value) const; std::string TemporalHistorySourceToString(TemporalHistorySource source) const; LayerPersistentState* FindLayerById(const std::string& layerId); const LayerPersistentState* FindLayerById(const std::string& layerId) const; std::string GenerateLayerId(); void MarkRenderStateDirtyLocked(); void MarkParameterStateDirtyLocked(); private: friend class RuntimeStore; friend class RuntimeSnapshotProvider; HealthTelemetry mHealthTelemetry; mutable std::mutex mMutex; AppConfig mConfig; PersistentState mPersistentState; std::filesystem::path mRepoRoot; std::filesystem::path mUiRoot; std::filesystem::path mDocsRoot; std::filesystem::path mShaderRoot; std::filesystem::path mRuntimeRoot; std::filesystem::path mPresetRoot; std::filesystem::path mRuntimeStatePath; std::filesystem::path mConfigPath; std::filesystem::path mWrapperPath; std::filesystem::path mGeneratedGlslPath; std::filesystem::path mPatchedGlslPath; std::map mPackagesById; std::vector mPackageOrder; std::vector mPackageStatuses; bool mReloadRequested; bool mCompileSucceeded; std::string mCompileMessage; double mStartupRandom; unsigned short mServerPort; bool mAutoReloadEnabled; std::chrono::steady_clock::time_point mStartTime; std::chrono::steady_clock::time_point mLastScanTime; std::atomic mFrameCounter{ 0 }; std::atomic mRenderStateVersion{ 0 }; std::atomic mParameterStateVersion{ 0 }; uint64_t mNextLayerId; };