#pragma once #include "RuntimeJson.h" #include "ShaderTypes.h" #include #include #include #include #include #include class ControlServer; class OpenGLComposite; class OscServer; class RuntimeHost; struct RuntimePollEvents { bool registryChanged = false; bool reloadRequested = false; bool failed = false; std::string error; }; class RuntimeServices { public: struct AppliedOscUpdate { std::string layerKey; std::string parameterKey; JsonValue targetValue; }; RuntimeServices(); ~RuntimeServices(); bool Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error); void BeginPolling(RuntimeHost& runtimeHost); void Stop(); void BroadcastState(); void RequestBroadcastState(); bool QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error); bool ApplyPendingOscUpdates(std::vector& appliedUpdates, std::string& error); RuntimePollEvents ConsumePollEvents(); private: struct PendingOscUpdate { std::string layerKey; std::string parameterKey; std::string valueJson; }; void StartPolling(RuntimeHost& runtimeHost); void StopPolling(); void PollLoop(RuntimeHost& runtimeHost); std::unique_ptr mControlServer; std::unique_ptr mOscServer; std::thread mPollThread; std::atomic mPollRunning; std::atomic mRegistryChanged; std::atomic mReloadRequested; std::atomic mPollFailed; std::mutex mPollErrorMutex; std::string mPollError; std::mutex mPendingOscMutex; std::map mPendingOscUpdates; };