#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) { JsonValue layers = JsonValue::MakeArray(); for (const LayerStackStore::LayerPersistentState& layer : layerStack.Layers()) { const ShaderPackage* shaderPackage = shaderCatalog.FindPackage(layer.shaderId); if (!shaderPackage) continue; 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); layers.pushBack(layerValue); } return layers; } 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"; } }