Fixed bindings
This commit is contained in:
@@ -77,6 +77,7 @@ bool ShaderPackageRegistry::Scan(
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> customUiTagOwners;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(shaderRoot))
|
||||
{
|
||||
if (!entry.is_directory())
|
||||
@@ -100,6 +101,21 @@ bool ShaderPackageRegistry::Scan(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shaderPackage.ui.enabled)
|
||||
{
|
||||
const auto tagOwnerIt = customUiTagOwners.find(shaderPackage.ui.customElementTag);
|
||||
if (tagOwnerIt != customUiTagOwners.end())
|
||||
{
|
||||
packageStatuses.push_back(BuildUnavailableStatus(
|
||||
manifestPath,
|
||||
shaderPackage,
|
||||
"Duplicate shader UI custom element tag '" + shaderPackage.ui.customElementTag +
|
||||
"' already used by shader '" + tagOwnerIt->second + "'."));
|
||||
continue;
|
||||
}
|
||||
customUiTagOwners[shaderPackage.ui.customElementTag] = shaderPackage.id;
|
||||
}
|
||||
|
||||
packageOrder.push_back(shaderPackage.id);
|
||||
packageStatuses.push_back(BuildAvailableStatus(shaderPackage));
|
||||
packagesById[shaderPackage.id] = shaderPackage;
|
||||
|
||||
@@ -138,6 +138,38 @@ void TestInvalidUiDefinition()
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestDuplicateCustomUiTags()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot();
|
||||
WriteFile(root / "a" / "ui" / "controls.js", "customElements.define('shared-controls', class extends HTMLElement {});\n");
|
||||
WriteFile(root / "b" / "ui" / "controls.js", "customElements.define('shared-controls', class extends HTMLElement {});\n");
|
||||
WriteShaderPackage(root, "a", R"({
|
||||
"id": "shader-a",
|
||||
"name": "Shader A",
|
||||
"ui": { "type": "webComponent", "entry": "ui/controls.js", "tag": "shared-controls" },
|
||||
"parameters": []
|
||||
})");
|
||||
WriteShaderPackage(root, "b", R"({
|
||||
"id": "shader-b",
|
||||
"name": "Shader B",
|
||||
"ui": { "type": "webComponent", "entry": "ui/controls.js", "tag": "shared-controls" },
|
||||
"parameters": []
|
||||
})");
|
||||
|
||||
ShaderPackageRegistry registry(4);
|
||||
std::map<std::string, ShaderPackage> packages;
|
||||
std::vector<std::string> order;
|
||||
std::vector<ShaderPackageStatus> statuses;
|
||||
std::string error;
|
||||
Expect(registry.Scan(root, packages, order, statuses, error), "duplicate custom UI tags do not fail the whole scan");
|
||||
Expect(packages.size() == 1, "only one duplicate custom UI tag owner remains available");
|
||||
Expect(std::any_of(statuses.begin(), statuses.end(), [](const ShaderPackageStatus& status) {
|
||||
return !status.available && status.error.find("Duplicate shader UI custom element tag") != std::string::npos;
|
||||
}), "duplicate custom UI tag is surfaced as an unavailable shader");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestExplicitPassManifest()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot();
|
||||
@@ -335,6 +367,7 @@ int main()
|
||||
TestValidManifest();
|
||||
TestExplicitPassManifest();
|
||||
TestInvalidUiDefinition();
|
||||
TestDuplicateCustomUiTags();
|
||||
TestMissingFontAsset();
|
||||
TestInvalidManifest();
|
||||
TestInvalidTemporalSettings();
|
||||
|
||||
@@ -140,7 +140,11 @@ export function ShaderCustomPanel({ layer, ui, onParameterChange, onResetParamet
|
||||
return;
|
||||
}
|
||||
if (element.parentNode !== node) {
|
||||
node.replaceChildren(element);
|
||||
try {
|
||||
node.replaceChildren(element);
|
||||
} catch (error) {
|
||||
setLoadError(error instanceof Error ? error.message : "Custom controls failed to mount.");
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user