refactor
Some checks failed
CI / Native Windows Build And Tests (push) Failing after 6s
CI / React UI Build (push) Successful in 10s

This commit is contained in:
2026-05-03 11:39:21 +10:00
parent 12dda9fc8c
commit 059032c234
11 changed files with 1163 additions and 209 deletions

View File

@@ -1,6 +1,8 @@
#include "stdafx.h"
#include "RuntimeHost.h"
#include "RuntimeParameterUtils.h"
#include "ShaderCompiler.h"
#include "ShaderPackageRegistry.h"
#include <algorithm>
#include <cmath>
@@ -1250,37 +1252,10 @@ bool RuntimeHost::ScanShaderPackages(std::string& error)
{
std::map<std::string, ShaderPackage> packagesById;
std::vector<std::string> packageOrder;
if (!std::filesystem::exists(mShaderRoot))
{
error = "Shader library directory does not exist: " + mShaderRoot.string();
ShaderPackageRegistry registry(mConfig.maxTemporalHistoryFrames);
if (!registry.Scan(mShaderRoot, packagesById, packageOrder, error))
return false;
}
for (const auto& entry : std::filesystem::directory_iterator(mShaderRoot))
{
if (!entry.is_directory())
continue;
std::filesystem::path manifestPath = entry.path() / "shader.json";
if (!std::filesystem::exists(manifestPath))
continue;
ShaderPackage shaderPackage;
if (!ParseShaderManifest(manifestPath, shaderPackage, error))
return false;
if (packagesById.find(shaderPackage.id) != packagesById.end())
{
error = "Duplicate shader id found: " + shaderPackage.id;
return false;
}
packageOrder.push_back(shaderPackage.id);
packagesById[shaderPackage.id] = shaderPackage;
}
std::sort(packageOrder.begin(), packageOrder.end());
mPackagesById.swap(packagesById);
mPackageOrder.swap(packageOrder);
@@ -1329,109 +1304,12 @@ bool RuntimeHost::ParseShaderManifest(const std::filesystem::path& manifestPath,
bool RuntimeHost::NormalizeAndValidateValue(const ShaderParameterDefinition& definition, const JsonValue& value, ShaderParameterValue& normalizedValue, std::string& error) const
{
normalizedValue = DefaultValueForDefinition(definition);
switch (definition.type)
{
case ShaderParameterType::Float:
{
if (!value.isNumber())
{
error = "Expected numeric value for float parameter '" + definition.id + "'.";
return false;
}
double number = value.asNumber();
if (!IsFiniteNumber(number))
{
error = "Float parameter '" + definition.id + "' must be finite.";
return false;
}
if (!definition.minNumbers.empty())
number = std::max(number, definition.minNumbers.front());
if (!definition.maxNumbers.empty())
number = std::min(number, definition.maxNumbers.front());
normalizedValue.numberValues = { number };
return true;
}
case ShaderParameterType::Vec2:
case ShaderParameterType::Color:
{
std::vector<double> numbers = JsonArrayToNumbers(value);
const std::size_t expectedSize = definition.type == ShaderParameterType::Vec2 ? 2 : 4;
if (numbers.size() != expectedSize)
{
error = "Expected array value of size " + std::to_string(expectedSize) + " for parameter '" + definition.id + "'.";
return false;
}
for (std::size_t index = 0; index < numbers.size(); ++index)
{
if (!IsFiniteNumber(numbers[index]))
{
error = "Parameter '" + definition.id + "' contains a non-finite value.";
return false;
}
if (index < definition.minNumbers.size())
numbers[index] = std::max(numbers[index], definition.minNumbers[index]);
if (index < definition.maxNumbers.size())
numbers[index] = std::min(numbers[index], definition.maxNumbers[index]);
}
normalizedValue.numberValues = numbers;
return true;
}
case ShaderParameterType::Boolean:
if (!value.isBoolean())
{
error = "Expected boolean value for parameter '" + definition.id + "'.";
return false;
}
normalizedValue.booleanValue = value.asBoolean();
return true;
case ShaderParameterType::Enum:
{
if (!value.isString())
{
error = "Expected string value for enum parameter '" + definition.id + "'.";
return false;
}
const std::string selectedValue = value.asString();
for (const ShaderParameterOption& option : definition.enumOptions)
{
if (option.value == selectedValue)
{
normalizedValue.enumValue = selectedValue;
return true;
}
}
error = "Enum parameter '" + definition.id + "' received unsupported option '" + selectedValue + "'.";
return false;
}
}
return false;
return NormalizeAndValidateParameterValue(definition, value, normalizedValue, error);
}
ShaderParameterValue RuntimeHost::DefaultValueForDefinition(const ShaderParameterDefinition& definition) const
{
ShaderParameterValue value;
switch (definition.type)
{
case ShaderParameterType::Float:
value.numberValues = definition.defaultNumbers.empty() ? std::vector<double>{ 0.0 } : definition.defaultNumbers;
break;
case ShaderParameterType::Vec2:
value.numberValues = definition.defaultNumbers.size() == 2 ? definition.defaultNumbers : std::vector<double>{ 0.0, 0.0 };
break;
case ShaderParameterType::Color:
value.numberValues = definition.defaultNumbers.size() == 4 ? definition.defaultNumbers : std::vector<double>{ 1.0, 1.0, 1.0, 1.0 };
break;
case ShaderParameterType::Boolean:
value.booleanValue = definition.defaultBoolean;
break;
case ShaderParameterType::Enum:
value.enumValue = definition.defaultEnumValue;
break;
}
return value;
return ::DefaultValueForDefinition(definition);
}
void RuntimeHost::EnsureLayerDefaultsLocked(LayerPersistentState& layerState, const ShaderPackage& shaderPackage) const
@@ -1737,26 +1615,7 @@ std::vector<std::string> RuntimeHost::GetStackPresetNamesLocked() const
std::string RuntimeHost::MakeSafePresetFileStem(const std::string& presetName) const
{
std::string trimmed = Trim(presetName);
std::string safe;
safe.reserve(trimmed.size());
for (unsigned char ch : trimmed)
{
if (std::isalnum(ch))
safe.push_back(static_cast<char>(std::tolower(ch)));
else if (ch == ' ' || ch == '-' || ch == '_')
{
if (safe.empty() || safe.back() == '-')
continue;
safe.push_back('-');
}
}
while (!safe.empty() && safe.back() == '-')
safe.pop_back();
return safe;
return ::MakeSafePresetFileStem(presetName);
}
JsonValue RuntimeHost::SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value) const