Files
video-shader-toys/src/runtime/layers/RuntimeLayerStateRestore.cpp
Aiden 0b6a2300ea
Some checks failed
CI / React UI Build (push) Successful in 38s
CI / Native Windows Build And Tests (push) Failing after 3m0s
CI / Windows Release Package (push) Has been skipped
Fixes
2026-05-22 14:43:03 +10:00

130 lines
3.7 KiB
C++

#include "RuntimeLayerModel.h"
#include "RuntimeParameterUtils.h"
#include <cctype>
#include <cstdint>
#include <set>
#include <utility>
namespace RenderCadenceCompositor
{
namespace
{
bool ParseRuntimeLayerNumber(const std::string& layerId, uint64_t& number)
{
const std::string prefix = "runtime-layer-";
if (layerId.compare(0, prefix.size(), prefix) != 0)
return false;
const std::string suffix = layerId.substr(prefix.size());
if (suffix.empty())
return false;
uint64_t parsed = 0;
for (char character : suffix)
{
if (!std::isdigit(static_cast<unsigned char>(character)))
return false;
parsed = parsed * 10 + static_cast<uint64_t>(character - '0');
}
number = parsed;
return true;
}
std::string AllocateRestoredLayerId(std::set<std::string>& usedLayerIds, uint64_t& nextLayerNumber)
{
for (;;)
{
std::string candidate = "runtime-layer-" + std::to_string(nextLayerNumber++);
if (usedLayerIds.insert(candidate).second)
return candidate;
}
}
}
bool RuntimeLayerModel::InitializeFromRuntimeState(const SupportedShaderCatalog& shaderCatalog, const JsonValue& runtimeState, std::string& error)
{
if (!runtimeState.isObject())
{
error = "Runtime state root must be a JSON object.";
return false;
}
const JsonValue* layersValue = runtimeState.find("layers");
if (!layersValue || !layersValue->isArray())
{
error = "Runtime state must contain a layers array.";
return false;
}
std::vector<Layer> restoredLayers;
std::set<std::string> usedLayerIds;
uint64_t nextLayerNumber = 1;
for (const JsonValue& layerValue : layersValue->asArray())
{
if (!layerValue.isObject())
continue;
const JsonValue* shaderIdValue = layerValue.find("shaderId");
if (!shaderIdValue || !shaderIdValue->isString() || shaderIdValue->asString().empty())
continue;
const ShaderPackage* shaderPackage = shaderCatalog.FindPackage(shaderIdValue->asString());
if (!shaderPackage)
continue;
Layer layer;
const JsonValue* layerIdValue = layerValue.find("id");
if (layerIdValue && layerIdValue->isString() && !layerIdValue->asString().empty() && usedLayerIds.insert(layerIdValue->asString()).second)
layer.id = layerIdValue->asString();
else
layer.id = AllocateRestoredLayerId(usedLayerIds, nextLayerNumber);
uint64_t restoredLayerNumber = 0;
if (ParseRuntimeLayerNumber(layer.id, restoredLayerNumber) && restoredLayerNumber >= nextLayerNumber)
nextLayerNumber = restoredLayerNumber + 1;
layer.shaderId = shaderPackage->id;
layer.packageFingerprint = ShaderPackageFingerprint(*shaderPackage);
layer.shaderName = shaderPackage->displayName.empty() ? shaderPackage->id : shaderPackage->displayName;
const JsonValue* bypassValue = layerValue.find("bypass");
layer.bypass = bypassValue && bypassValue->isBoolean() ? bypassValue->asBoolean() : false;
layer.buildState = RuntimeLayerBuildState::Pending;
layer.message = "Runtime Slang build is waiting to start.";
InitializeDefaultParameterValues(layer, *shaderPackage);
const JsonValue* parameterValues = layerValue.find("parameterValues");
if (parameterValues && parameterValues->isObject())
{
for (const ShaderParameterDefinition& definition : layer.parameterDefinitions)
{
const JsonValue* value = parameterValues->find(definition.id);
if (!value)
continue;
ShaderParameterValue normalizedValue;
std::string normalizeError;
if (NormalizeAndValidateParameterValue(definition, *value, normalizedValue, normalizeError))
layer.parameterValues[definition.id] = normalizedValue;
}
}
restoredLayers.push_back(std::move(layer));
}
if (restoredLayers.empty())
{
error = "Runtime state did not contain any supported layers.";
return false;
}
mLayers = std::move(restoredLayers);
mNextLayerNumber = nextLayerNumber;
error.clear();
return true;
}
}