#pragma once #include "RuntimeJson.h" #include "ShaderTypes.h" #include #include #include #include #include struct RuntimeLiveOscUpdate { std::string routeKey; std::string layerKey; std::string parameterKey; JsonValue targetValue; }; struct RuntimeLiveOscCommitCompletion { std::string routeKey; uint64_t generation = 0; }; struct RuntimeLiveOscCommitRequest { std::string routeKey; std::string layerKey; std::string parameterKey; JsonValue value; uint64_t generation = 0; }; struct RuntimeLiveStateApplyOptions { bool allowCommit = false; double smoothing = 0.0; std::chrono::milliseconds commitDelay = std::chrono::milliseconds(150); std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); }; class RuntimeLiveState { public: void Clear(); void ClearForLayerKey(const std::string& layerKey); std::size_t OverlayCount() const; void ApplyOscUpdates(const std::vector& updates); void ApplyOscCommitCompletions(const std::vector& completedCommits); void PruneIncompatibleOverlays(const std::vector& states); void ApplyToLayerStates( std::vector& states, const RuntimeLiveStateApplyOptions& options, std::vector* commitRequests); private: struct OscOverlayState { std::string layerKey; std::string parameterKey; JsonValue targetValue; ShaderParameterValue currentValue; bool hasCurrentValue = false; std::chrono::steady_clock::time_point lastUpdatedTime; std::chrono::steady_clock::time_point lastAppliedTime; uint64_t generation = 0; uint64_t pendingCommitGeneration = 0; bool commitQueued = false; }; static bool OverlayMatchesLayerKey(const OscOverlayState& overlay, const std::string& layerKey); static bool TryResolveOverlayTarget( const OscOverlayState& overlay, const std::vector& states, std::vector::const_iterator& stateIt, std::vector::const_iterator& definitionIt); std::map mOscOverlayStates; };