642 lines
18 KiB
C++
642 lines
18 KiB
C++
#include "RuntimeStore.h"
|
|
|
|
#include "RuntimeStatePresenter.h"
|
|
|
|
#include <cctype>
|
|
#include <fstream>
|
|
#include <mutex>
|
|
#include <random>
|
|
#include <sstream>
|
|
|
|
namespace
|
|
{
|
|
std::string ToLowerCopy(std::string text)
|
|
{
|
|
std::transform(text.begin(), text.end(), text.begin(),
|
|
[](unsigned char ch) { return static_cast<char>(std::tolower(ch)); });
|
|
return text;
|
|
}
|
|
|
|
double GenerateStartupRandom()
|
|
{
|
|
std::random_device randomDevice;
|
|
std::uniform_real_distribution<double> distribution(0.0, 1.0);
|
|
return distribution(randomDevice);
|
|
}
|
|
|
|
}
|
|
|
|
RuntimeStore::RuntimeStore() :
|
|
mRenderSnapshotBuilder(*this),
|
|
mHealthTelemetry(),
|
|
mReloadRequested(false),
|
|
mCompileSucceeded(false),
|
|
mStartupRandom(GenerateStartupRandom()),
|
|
mServerPort(8080),
|
|
mAutoReloadEnabled(true),
|
|
mStartTime(std::chrono::steady_clock::now()),
|
|
mLastScanTime((std::chrono::steady_clock::time_point::min)())
|
|
{
|
|
}
|
|
|
|
HealthTelemetry& RuntimeStore::GetHealthTelemetry()
|
|
{
|
|
return mHealthTelemetry;
|
|
}
|
|
|
|
const HealthTelemetry& RuntimeStore::GetHealthTelemetry() const
|
|
{
|
|
return mHealthTelemetry;
|
|
}
|
|
|
|
RenderSnapshotBuilder& RuntimeStore::GetRenderSnapshotBuilder()
|
|
{
|
|
return mRenderSnapshotBuilder;
|
|
}
|
|
|
|
const RenderSnapshotBuilder& RuntimeStore::GetRenderSnapshotBuilder() const
|
|
{
|
|
return mRenderSnapshotBuilder;
|
|
}
|
|
|
|
bool RuntimeStore::InitializeStore(std::string& error)
|
|
{
|
|
try
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
|
|
if (!mConfigStore.Initialize(error))
|
|
return false;
|
|
if (!LoadPersistentState(error))
|
|
return false;
|
|
if (!ScanShaderPackages(error))
|
|
return false;
|
|
mCommittedLiveState.NormalizeLayerIds();
|
|
mCommittedLiveState.EnsureDefaultsForAllLayers(mShaderCatalog);
|
|
mCommittedLiveState.EnsureDefaultLayer(mShaderCatalog);
|
|
|
|
mServerPort = mConfigStore.GetConfig().serverPort;
|
|
mAutoReloadEnabled = mConfigStore.GetConfig().autoReload;
|
|
mReloadRequested = true;
|
|
mCompileMessage = "Waiting for shader compile.";
|
|
return true;
|
|
}
|
|
catch (const std::exception& exception)
|
|
{
|
|
error = std::string("RuntimeStore::InitializeStore exception: ") + exception.what();
|
|
return false;
|
|
}
|
|
catch (...)
|
|
{
|
|
error = "RuntimeStore::InitializeStore threw a non-standard exception.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string RuntimeStore::BuildPersistentStateJson() const
|
|
{
|
|
return RuntimeStatePresenter::BuildRuntimeStateJson(*this);
|
|
}
|
|
|
|
PersistenceSnapshot RuntimeStore::BuildRuntimeStatePersistenceSnapshot(const PersistenceRequest& request) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return BuildRuntimeStatePersistenceSnapshotLocked(request);
|
|
}
|
|
|
|
PersistenceSnapshot RuntimeStore::BuildRuntimeStatePersistenceSnapshotLocked(const PersistenceRequest& request) const
|
|
{
|
|
PersistenceSnapshot snapshot;
|
|
snapshot.targetKind = PersistenceTargetKind::RuntimeState;
|
|
snapshot.targetPath = mConfigStore.GetRuntimeStatePath();
|
|
snapshot.contents = SerializeJson(mCommittedLiveState.BuildPersistentStateValue(mShaderCatalog), true);
|
|
snapshot.reason = request.reason;
|
|
snapshot.debounceKey = request.debounceKey;
|
|
snapshot.debounceAllowed = request.debounceAllowed;
|
|
snapshot.flushRequested = request.flushRequested;
|
|
snapshot.generation = request.sequence;
|
|
return snapshot;
|
|
}
|
|
|
|
bool RuntimeStore::PollStoredFileChanges(bool& registryChanged, bool& reloadRequested, std::string& error)
|
|
{
|
|
try
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
registryChanged = false;
|
|
reloadRequested = false;
|
|
|
|
if (!mAutoReloadEnabled)
|
|
{
|
|
reloadRequested = mReloadRequested;
|
|
return true;
|
|
}
|
|
|
|
const auto now = std::chrono::steady_clock::now();
|
|
if (mLastScanTime != (std::chrono::steady_clock::time_point::min)() &&
|
|
std::chrono::duration_cast<std::chrono::milliseconds>(now - mLastScanTime).count() < 250)
|
|
{
|
|
reloadRequested = mReloadRequested;
|
|
return true;
|
|
}
|
|
|
|
mLastScanTime = now;
|
|
|
|
std::string scanError;
|
|
const ShaderPackageCatalog::Snapshot previousCatalog = mShaderCatalog.CaptureSnapshot();
|
|
if (!ScanShaderPackages(scanError))
|
|
{
|
|
error = scanError;
|
|
return false;
|
|
}
|
|
|
|
registryChanged = mShaderCatalog.HasCatalogChangedSince(previousCatalog);
|
|
|
|
mCommittedLiveState.EnsureDefaultsForAllLayers(mShaderCatalog);
|
|
for (RuntimeStore::LayerPersistentState& layer : mCommittedLiveState.Layers())
|
|
{
|
|
const ShaderPackage* active = mShaderCatalog.FindPackage(layer.shaderId);
|
|
if (!active)
|
|
continue;
|
|
if (mShaderCatalog.HasPackageChangedSince(previousCatalog, layer.shaderId))
|
|
mReloadRequested = true;
|
|
}
|
|
|
|
reloadRequested = mReloadRequested;
|
|
if (registryChanged || reloadRequested)
|
|
MarkRenderStateDirtyLocked();
|
|
return true;
|
|
}
|
|
catch (const std::exception& exception)
|
|
{
|
|
error = std::string("RuntimeStore::PollStoredFileChanges exception: ") + exception.what();
|
|
return false;
|
|
}
|
|
catch (...)
|
|
{
|
|
error = "RuntimeStore::PollStoredFileChanges threw a non-standard exception.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool RuntimeStore::CreateStoredLayer(const std::string& shaderId, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
if (!mCommittedLiveState.CreateLayer(mShaderCatalog, shaderId, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::DeleteStoredLayer(const std::string& layerId, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
if (!mCommittedLiveState.DeleteLayer(layerId, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::MoveStoredLayer(const std::string& layerId, int direction, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
bool shouldMove = false;
|
|
if (!mCommittedLiveState.ResolveLayerMove(layerId, direction, shouldMove, error))
|
|
return false;
|
|
if (!shouldMove)
|
|
return true;
|
|
|
|
if (!mCommittedLiveState.MoveLayer(layerId, direction, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::MoveStoredLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
bool shouldMove = false;
|
|
if (!mCommittedLiveState.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error))
|
|
return false;
|
|
if (!shouldMove)
|
|
return true;
|
|
|
|
if (!mCommittedLiveState.MoveLayerToIndex(layerId, targetIndex, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::SetStoredLayerBypassState(const std::string& layerId, bool bypassed, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
if (!mCommittedLiveState.SetLayerBypassState(layerId, bypassed, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkParameterStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::SetStoredLayerShaderSelection(const std::string& layerId, const std::string& shaderId, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
if (!mCommittedLiveState.SetLayerShaderSelection(mShaderCatalog, layerId, shaderId, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std::string& parameterId, const ShaderParameterValue& value, bool persistState, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
|
|
if (!mCommittedLiveState.SetParameterValue(layerId, parameterId, value, error))
|
|
return false;
|
|
|
|
MarkParameterStateDirtyLocked();
|
|
return !persistState || SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::ResetStoredLayerParameterValues(const std::string& layerId, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
|
|
if (!mCommittedLiveState.ResetLayerParameterValues(mShaderCatalog, layerId, error))
|
|
return false;
|
|
|
|
MarkParameterStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::SaveStackPresetSnapshot(const std::string& presetName, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
const std::string safeStem = LayerStackStore::MakeSafePresetFileStem(presetName);
|
|
if (safeStem.empty())
|
|
{
|
|
error = "Preset name must include at least one letter or number.";
|
|
return false;
|
|
}
|
|
|
|
return mPersistenceWriter.WriteSnapshot(BuildStackPresetPersistenceSnapshot(presetName), error);
|
|
}
|
|
|
|
bool RuntimeStore::LoadStackPresetSnapshot(const std::string& presetName, std::string& error)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
const std::string safeStem = LayerStackStore::MakeSafePresetFileStem(presetName);
|
|
if (safeStem.empty())
|
|
{
|
|
error = "Preset name must include at least one letter or number.";
|
|
return false;
|
|
}
|
|
|
|
const std::filesystem::path presetPath = mConfigStore.GetPresetRoot() / (safeStem + ".json");
|
|
std::string presetText = ReadTextFile(presetPath, error);
|
|
if (presetText.empty())
|
|
return false;
|
|
|
|
JsonValue root;
|
|
if (!ParseJson(presetText, root, error))
|
|
return false;
|
|
|
|
if (!mCommittedLiveState.LoadStackPresetValue(mShaderCatalog, root, error))
|
|
return false;
|
|
|
|
mReloadRequested = true;
|
|
MarkRenderStateDirtyLocked();
|
|
return SavePersistentState(error);
|
|
}
|
|
|
|
bool RuntimeStore::HasStoredLayer(const std::string& layerId) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mCommittedLiveState.HasLayer(layerId);
|
|
}
|
|
|
|
bool RuntimeStore::HasStoredShader(const std::string& shaderId) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mShaderCatalog.HasPackage(shaderId);
|
|
}
|
|
|
|
bool RuntimeStore::TryGetStoredParameterById(const std::string& layerId, const std::string& parameterId, StoredParameterSnapshot& snapshot, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
|
|
return mCommittedLiveState.TryGetParameterById(mShaderCatalog, layerId, parameterId, snapshot, error);
|
|
}
|
|
|
|
bool RuntimeStore::TryGetStoredParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, StoredParameterSnapshot& snapshot, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
|
|
return mCommittedLiveState.TryGetParameterByControlKey(mShaderCatalog, layerKey, parameterKey, snapshot, error);
|
|
}
|
|
|
|
bool RuntimeStore::ResolveStoredLayerMove(const std::string& layerId, int direction, bool& shouldMove, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mCommittedLiveState.ResolveLayerMove(layerId, direction, shouldMove, error);
|
|
}
|
|
|
|
bool RuntimeStore::ResolveStoredLayerMoveToIndex(const std::string& layerId, std::size_t targetIndex, bool& shouldMove, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mCommittedLiveState.ResolveLayerMoveToIndex(layerId, targetIndex, shouldMove, error);
|
|
}
|
|
|
|
bool RuntimeStore::IsValidStackPresetName(const std::string& presetName) const
|
|
{
|
|
return !LayerStackStore::MakeSafePresetFileStem(presetName).empty();
|
|
}
|
|
|
|
double RuntimeStore::GetRuntimeElapsedSeconds() const
|
|
{
|
|
return std::chrono::duration_cast<std::chrono::duration<double>>(
|
|
std::chrono::steady_clock::now() - mStartTime).count();
|
|
}
|
|
|
|
const std::filesystem::path& RuntimeStore::GetRuntimeRepositoryRoot() const
|
|
{
|
|
return mConfigStore.GetRepoRoot();
|
|
}
|
|
|
|
const std::filesystem::path& RuntimeStore::GetRuntimeUiRoot() const
|
|
{
|
|
return mConfigStore.GetUiRoot();
|
|
}
|
|
|
|
const std::filesystem::path& RuntimeStore::GetRuntimeDocsRoot() const
|
|
{
|
|
return mConfigStore.GetDocsRoot();
|
|
}
|
|
|
|
const std::filesystem::path& RuntimeStore::GetRuntimeDataRoot() const
|
|
{
|
|
return mConfigStore.GetRuntimeRoot();
|
|
}
|
|
|
|
unsigned short RuntimeStore::GetConfiguredControlServerPort() const
|
|
{
|
|
return mServerPort;
|
|
}
|
|
|
|
unsigned short RuntimeStore::GetConfiguredOscPort() const
|
|
{
|
|
return mConfigStore.GetConfig().oscPort;
|
|
}
|
|
|
|
const std::string& RuntimeStore::GetConfiguredOscBindAddress() const
|
|
{
|
|
return mConfigStore.GetConfig().oscBindAddress;
|
|
}
|
|
|
|
double RuntimeStore::GetConfiguredOscSmoothing() const
|
|
{
|
|
return mConfigStore.GetConfig().oscSmoothing;
|
|
}
|
|
|
|
unsigned RuntimeStore::GetConfiguredMaxTemporalHistoryFrames() const
|
|
{
|
|
return mConfigStore.GetConfig().maxTemporalHistoryFrames;
|
|
}
|
|
|
|
unsigned RuntimeStore::GetConfiguredPreviewFps() const
|
|
{
|
|
return mConfigStore.GetConfig().previewFps;
|
|
}
|
|
|
|
bool RuntimeStore::IsExternalKeyingConfigured() const
|
|
{
|
|
return mConfigStore.GetConfig().enableExternalKeying;
|
|
}
|
|
|
|
const std::string& RuntimeStore::GetConfiguredInputVideoFormat() const
|
|
{
|
|
return mConfigStore.GetConfig().inputVideoFormat;
|
|
}
|
|
|
|
const std::string& RuntimeStore::GetConfiguredInputFrameRate() const
|
|
{
|
|
return mConfigStore.GetConfig().inputFrameRate;
|
|
}
|
|
|
|
const std::string& RuntimeStore::GetConfiguredOutputVideoFormat() const
|
|
{
|
|
return mConfigStore.GetConfig().outputVideoFormat;
|
|
}
|
|
|
|
const std::string& RuntimeStore::GetConfiguredOutputFrameRate() const
|
|
{
|
|
return mConfigStore.GetConfig().outputFrameRate;
|
|
}
|
|
|
|
void RuntimeStore::SetBoundControlServerPort(unsigned short port)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
mServerPort = port;
|
|
mConfigStore.SetBoundControlServerPort(port);
|
|
}
|
|
|
|
void RuntimeStore::SetCompileStatus(bool succeeded, const std::string& message)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
mCompileSucceeded = succeeded;
|
|
mCompileMessage = message;
|
|
}
|
|
|
|
void RuntimeStore::ClearReloadRequest()
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
mReloadRequested = false;
|
|
}
|
|
|
|
bool RuntimeStore::LoadPersistentState(std::string& error)
|
|
{
|
|
if (!std::filesystem::exists(mConfigStore.GetRuntimeStatePath()))
|
|
return true;
|
|
|
|
std::string stateText = ReadTextFile(mConfigStore.GetRuntimeStatePath(), error);
|
|
if (stateText.empty())
|
|
return false;
|
|
|
|
JsonValue root;
|
|
if (!ParseJson(stateText, root, error))
|
|
return false;
|
|
|
|
return mCommittedLiveState.LoadPersistentStateValue(root);
|
|
}
|
|
|
|
bool RuntimeStore::SavePersistentState(std::string& error) const
|
|
{
|
|
return mPersistenceWriter.EnqueueSnapshot(BuildRuntimeStatePersistenceSnapshotLocked(PersistenceRequest::RuntimeStateRequest("SavePersistentState")), error);
|
|
}
|
|
|
|
PersistenceSnapshot RuntimeStore::BuildStackPresetPersistenceSnapshot(const std::string& presetName) const
|
|
{
|
|
const std::string safeStem = LayerStackStore::MakeSafePresetFileStem(presetName);
|
|
|
|
PersistenceSnapshot snapshot;
|
|
snapshot.targetKind = PersistenceTargetKind::StackPreset;
|
|
snapshot.targetPath = mConfigStore.GetPresetRoot() / (safeStem + ".json");
|
|
snapshot.contents = SerializeJson(mCommittedLiveState.BuildStackPresetValue(mShaderCatalog, presetName), true);
|
|
snapshot.reason = "SaveStackPreset";
|
|
snapshot.debounceKey = "stack-preset:" + safeStem;
|
|
snapshot.debounceAllowed = false;
|
|
snapshot.flushRequested = true;
|
|
snapshot.generation = 0;
|
|
return snapshot;
|
|
}
|
|
|
|
bool RuntimeStore::ScanShaderPackages(std::string& error)
|
|
{
|
|
if (!mShaderCatalog.Scan(mConfigStore.GetShaderRoot(), mConfigStore.GetConfig().maxTemporalHistoryFrames, error))
|
|
return false;
|
|
|
|
mCommittedLiveState.RemoveLayersWithMissingPackages(mShaderCatalog);
|
|
|
|
MarkRenderStateDirtyLocked();
|
|
return true;
|
|
}
|
|
|
|
std::string RuntimeStore::ReadTextFile(const std::filesystem::path& path, std::string& error) const
|
|
{
|
|
std::ifstream input(path, std::ios::binary);
|
|
if (!input)
|
|
{
|
|
error = "Could not open file: " + path.string();
|
|
return std::string();
|
|
}
|
|
|
|
std::ostringstream buffer;
|
|
buffer << input.rdbuf();
|
|
return buffer.str();
|
|
}
|
|
|
|
std::vector<std::string> RuntimeStore::GetStackPresetNamesLocked() const
|
|
{
|
|
std::vector<std::string> presetNames;
|
|
std::error_code fsError;
|
|
if (!std::filesystem::exists(mConfigStore.GetPresetRoot(), fsError))
|
|
return presetNames;
|
|
|
|
for (const auto& entry : std::filesystem::directory_iterator(mConfigStore.GetPresetRoot(), fsError))
|
|
{
|
|
if (!entry.is_regular_file())
|
|
continue;
|
|
if (ToLowerCopy(entry.path().extension().string()) != ".json")
|
|
continue;
|
|
presetNames.push_back(entry.path().stem().string());
|
|
}
|
|
|
|
std::sort(presetNames.begin(), presetNames.end());
|
|
return presetNames;
|
|
}
|
|
|
|
bool RuntimeStore::CopyShaderPackageForStoredLayer(const std::string& layerId, ShaderPackage& shaderPackage, std::string& error) const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
const RuntimeStore::LayerPersistentState* layer = mCommittedLiveState.FindLayerById(layerId);
|
|
if (!layer)
|
|
{
|
|
error = "Unknown layer id: " + layerId;
|
|
return false;
|
|
}
|
|
|
|
if (!mShaderCatalog.CopyPackage(layer->shaderId, shaderPackage))
|
|
{
|
|
error = "Unknown shader id: " + layer->shaderId;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ShaderCompilerInputs RuntimeStore::GetShaderCompilerInputs() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
ShaderCompilerInputs inputs;
|
|
inputs.repoRoot = mConfigStore.GetRepoRoot();
|
|
inputs.wrapperPath = mConfigStore.GetWrapperPath();
|
|
inputs.generatedGlslPath = mConfigStore.GetGeneratedGlslPath();
|
|
inputs.patchedGlslPath = mConfigStore.GetPatchedGlslPath();
|
|
inputs.maxTemporalHistoryFrames = mConfigStore.GetConfig().maxTemporalHistoryFrames;
|
|
return inputs;
|
|
}
|
|
|
|
CommittedLiveStateReadModel RuntimeStore::BuildCommittedLiveStateReadModel() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mCommittedLiveState.BuildReadModel(mShaderCatalog);
|
|
}
|
|
|
|
RenderSnapshotReadModel RuntimeStore::BuildRenderSnapshotReadModel() const
|
|
{
|
|
RenderSnapshotReadModel model;
|
|
model.signalStatus = mHealthTelemetry.GetSignalStatusSnapshot();
|
|
model.committedLiveState = BuildCommittedLiveStateReadModel();
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
model.timing.startTime = mStartTime;
|
|
model.timing.startupRandom = mStartupRandom;
|
|
return model;
|
|
}
|
|
|
|
std::vector<RuntimeStore::LayerPersistentState> RuntimeStore::CopyCommittedLiveLayerStates() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
return mCommittedLiveState.CopyLayerStates();
|
|
}
|
|
|
|
std::vector<RuntimeStore::LayerPersistentState> RuntimeStore::CopyLayerStates() const
|
|
{
|
|
return CopyCommittedLiveLayerStates();
|
|
}
|
|
|
|
RenderTimingSnapshot RuntimeStore::GetRenderTimingSnapshot() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
RenderTimingSnapshot snapshot;
|
|
snapshot.startTime = mStartTime;
|
|
snapshot.startupRandom = mStartupRandom;
|
|
return snapshot;
|
|
}
|
|
|
|
RuntimeStatePresentationReadModel RuntimeStore::BuildRuntimeStatePresentationReadModel() const
|
|
{
|
|
RuntimeStatePresentationReadModel model;
|
|
model.telemetry = mHealthTelemetry.GetSnapshot();
|
|
std::lock_guard<std::mutex> lock(mMutex);
|
|
model.config = mConfigStore.GetConfig();
|
|
model.layerStack = mCommittedLiveState.LayerStack();
|
|
model.shaderCatalog = mShaderCatalog.CaptureSnapshot();
|
|
model.packageStatuses = mShaderCatalog.PackageStatuses();
|
|
model.stackPresetNames = GetStackPresetNamesLocked();
|
|
model.serverPort = mServerPort;
|
|
model.autoReloadEnabled = mAutoReloadEnabled;
|
|
model.compileSucceeded = mCompileSucceeded;
|
|
model.compileMessage = mCompileMessage;
|
|
return model;
|
|
}
|
|
|
|
void RuntimeStore::MarkRenderStateDirtyLocked()
|
|
{
|
|
mRenderSnapshotBuilder.MarkRenderStateDirty();
|
|
}
|
|
|
|
void RuntimeStore::MarkParameterStateDirtyLocked()
|
|
{
|
|
mRenderSnapshotBuilder.MarkParameterStateDirty();
|
|
}
|