runtime read of json layer state
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cctype>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
@@ -35,6 +37,38 @@ JsonValue ParameterValueToJson(const ShaderParameterDefinition& definition, cons
|
||||
}
|
||||
return JsonValue();
|
||||
}
|
||||
|
||||
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::InitializeSingleLayer(const SupportedShaderCatalog& shaderCatalog, const std::string& shaderId, std::string& error)
|
||||
@@ -227,6 +261,89 @@ bool RuntimeLayerModel::ResetParameters(const std::string& layerId, std::string&
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool RuntimeLayerModel::ReloadFromCatalog(const SupportedShaderCatalog& shaderCatalog, std::vector<std::pair<std::string, std::string>>& buildsToStart, std::string& error)
|
||||
{
|
||||
buildsToStart.clear();
|
||||
@@ -392,6 +509,17 @@ std::string RuntimeLayerModel::FirstLayerId() const
|
||||
return mLayers.empty() ? std::string() : mLayers.front().id;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> RuntimeLayerModel::PendingLayerBuilds() const
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> builds;
|
||||
for (const Layer& layer : mLayers)
|
||||
{
|
||||
if (layer.buildState == RuntimeLayerBuildState::Pending)
|
||||
builds.push_back({ layer.id, layer.shaderId });
|
||||
}
|
||||
return builds;
|
||||
}
|
||||
|
||||
RuntimeLayerModel::Layer* RuntimeLayerModel::FindLayer(const std::string& layerId)
|
||||
{
|
||||
for (Layer& layer : mLayers)
|
||||
|
||||
Reference in New Issue
Block a user