#include "RuntimeStateJson.h" #include "RuntimeParameterUtils.h" namespace { std::string ShaderParameterTypeToString(ShaderParameterType type) { switch (type) { case ShaderParameterType::Float: return "float"; case ShaderParameterType::Vec2: return "vec2"; case ShaderParameterType::Color: return "color"; case ShaderParameterType::Boolean: return "bool"; case ShaderParameterType::Enum: return "enum"; case ShaderParameterType::Text: return "text"; case ShaderParameterType::Trigger: return "trigger"; } return "unknown"; } } JsonValue RuntimeStateJson::SerializeLayerStack(const LayerStackStore& layerStack, const ShaderPackageCatalog& shaderCatalog) { std::map packagesById; for (const std::string& packageId : shaderCatalog.PackageOrder()) { ShaderPackage shaderPackage; if (shaderCatalog.CopyPackage(packageId, shaderPackage)) packagesById[packageId] = shaderPackage; } return SerializeLayerStack(layerStack.Layers(), packagesById); } JsonValue RuntimeStateJson::SerializeLayerStack(const std::vector& layerStates, const std::map& packagesById) { JsonValue layersValue = JsonValue::MakeArray(); for (const LayerStackStore::LayerPersistentState& layer : layerStates) { auto shaderIt = packagesById.find(layer.shaderId); if (shaderIt == packagesById.end()) continue; const ShaderPackage& shaderPackage = shaderIt->second; JsonValue layerValue = JsonValue::MakeObject(); layerValue.set("id", JsonValue(layer.id)); layerValue.set("shaderId", JsonValue(layer.shaderId)); layerValue.set("shaderName", JsonValue(shaderPackage.displayName)); layerValue.set("bypass", JsonValue(layer.bypass)); if (shaderPackage.temporal.enabled) { JsonValue temporal = JsonValue::MakeObject(); temporal.set("enabled", JsonValue(true)); temporal.set("historySource", JsonValue(TemporalHistorySourceToString(shaderPackage.temporal.historySource))); temporal.set("requestedHistoryLength", JsonValue(static_cast(shaderPackage.temporal.requestedHistoryLength))); temporal.set("effectiveHistoryLength", JsonValue(static_cast(shaderPackage.temporal.effectiveHistoryLength))); layerValue.set("temporal", temporal); } if (shaderPackage.feedback.enabled) { JsonValue feedback = JsonValue::MakeObject(); feedback.set("enabled", JsonValue(true)); feedback.set("writePass", JsonValue(shaderPackage.feedback.writePassId)); layerValue.set("feedback", feedback); } JsonValue parameters = JsonValue::MakeArray(); for (const ShaderParameterDefinition& definition : shaderPackage.parameters) { JsonValue parameter = JsonValue::MakeObject(); parameter.set("id", JsonValue(definition.id)); parameter.set("label", JsonValue(definition.label)); if (!definition.description.empty()) parameter.set("description", JsonValue(definition.description)); parameter.set("type", JsonValue(ShaderParameterTypeToString(definition.type))); parameter.set("defaultValue", SerializeParameterValue(definition, DefaultValueForDefinition(definition))); if (!definition.minNumbers.empty()) { JsonValue minValue = JsonValue::MakeArray(); for (double number : definition.minNumbers) minValue.pushBack(JsonValue(number)); parameter.set("min", minValue); } if (!definition.maxNumbers.empty()) { JsonValue maxValue = JsonValue::MakeArray(); for (double number : definition.maxNumbers) maxValue.pushBack(JsonValue(number)); parameter.set("max", maxValue); } if (!definition.stepNumbers.empty()) { JsonValue stepValue = JsonValue::MakeArray(); for (double number : definition.stepNumbers) stepValue.pushBack(JsonValue(number)); parameter.set("step", stepValue); } if (definition.type == ShaderParameterType::Enum) { JsonValue options = JsonValue::MakeArray(); for (const ShaderParameterOption& option : definition.enumOptions) { JsonValue optionValue = JsonValue::MakeObject(); optionValue.set("value", JsonValue(option.value)); optionValue.set("label", JsonValue(option.label)); options.pushBack(optionValue); } parameter.set("options", options); } if (definition.type == ShaderParameterType::Text) { parameter.set("maxLength", JsonValue(static_cast(definition.maxLength))); if (!definition.fontId.empty()) parameter.set("font", JsonValue(definition.fontId)); } ShaderParameterValue value = DefaultValueForDefinition(definition); auto valueIt = layer.parameterValues.find(definition.id); if (valueIt != layer.parameterValues.end()) value = valueIt->second; parameter.set("value", SerializeParameterValue(definition, value)); parameters.pushBack(parameter); } layerValue.set("parameters", parameters); layersValue.pushBack(layerValue); } return layersValue; } JsonValue RuntimeStateJson::SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value) { switch (definition.type) { case ShaderParameterType::Boolean: return JsonValue(value.booleanValue); case ShaderParameterType::Enum: return JsonValue(value.enumValue); case ShaderParameterType::Text: return JsonValue(value.textValue); case ShaderParameterType::Trigger: return JsonValue(value.numberValues.empty() ? 0.0 : value.numberValues.front()); case ShaderParameterType::Float: return JsonValue(value.numberValues.empty() ? 0.0 : value.numberValues.front()); case ShaderParameterType::Vec2: case ShaderParameterType::Color: { JsonValue array = JsonValue::MakeArray(); for (double number : value.numberValues) array.pushBack(JsonValue(number)); return array; } } return JsonValue(); } std::string RuntimeStateJson::TemporalHistorySourceToString(TemporalHistorySource source) { switch (source) { case TemporalHistorySource::Source: return "source"; case TemporalHistorySource::PreLayerInput: return "preLayerInput"; case TemporalHistorySource::None: default: return "none"; } }