fix:修复bug

This commit is contained in:
Daniel
2026-04-01 20:29:33 +08:00
parent afbcd99224
commit a80d2b8430
9 changed files with 477 additions and 179 deletions

View File

@@ -30,6 +30,90 @@ async function writeDb(list) {
await fs.writeFile(DB_PATH, JSON.stringify(list, null, 2), "utf8");
}
function extractFunctionSection(code) {
const endMarker = code.indexOf("void ANGLE__0_main");
const end = endMarker >= 0 ? endMarker : code.length;
const firstFn = code.search(
/(metal::float[234](x2)?|float|void)\s+[A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\)\s*\{/m
);
if (firstFn < 0 || firstFn >= end) return "";
return code.slice(firstFn, end);
}
function convertAngleMetalToGlsl(code) {
let section = extractFunctionSection(code);
if (!section || !section.includes("_umainImage")) return "";
section = section
.replace(
/void _umainImage\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*thread metal::float4\s*&\s*([A-Za-z0-9_]+)\s*,\s*metal::float2\s*([A-Za-z0-9_]+)\s*\)/g,
"void _umainImage(out vec4 $1, vec2 $2)"
)
.replace(
/float _umap\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*\)/g,
"float _umap(vec3 $1)"
)
.replace(
/metal::float4 _urm\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*\)/g,
"vec4 _urm(vec3 $1, vec3 $2)"
)
.replace(/_umap\s*\(\s*ANGLE_userUniforms\s*,/g, "_umap(")
.replace(/_urm\s*\(\s*ANGLE_userUniforms\s*,/g, "_urm(")
.replace(/ANGLE_userUniforms\._uiResolution/g, "iResolution")
.replace(/ANGLE_userUniforms\._uiTime/g, "iTime")
.replace(/metal::fast::normalize/g, "normalize")
.replace(/metal::/g, "")
.replace(/\bthread\b/g, "")
.replace(/\bconstant\b/g, "")
.replace(/\buint32_t\b/g, "uint")
.replace(/;\s*;/g, ";");
const cleaned = [
"void ANGLE_loopForwardProgress() {}",
section,
"void mainImage(out vec4 fragColor, in vec2 fragCoord) { _umainImage(fragColor, fragCoord); }",
].join("\n");
return cleaned;
}
function normalizeIncomingCode(code) {
if (!code || typeof code !== "string") return { error: "code 不能为空", normalized: "" };
if (code.includes("metal::") || code.includes("[[function_constant")) {
const converted = convertAngleMetalToGlsl(code);
if (!converted) {
return { error: "自动解构失败:请检查粘贴内容是否完整。", normalized: "" };
}
return { error: "", normalized: converted };
}
if (!code.includes("mainImage")) {
return { error: "code 必须包含 mainImage", normalized: "" };
}
return { error: "", normalized: code };
}
async function autoNormalizeStoredShaders() {
const shaders = await readDb();
let changed = false;
const next = shaders.map((item) => {
const code = String(item.code || "");
if (code.includes("metal::") || code.includes("[[function_constant")) {
const { error, normalized } = normalizeIncomingCode(code);
if (!error && normalized) {
changed = true;
return {
...item,
code: normalized,
updatedAt: new Date().toISOString(),
sourceFormat: "angle-metal-auto-converted",
};
}
}
return item;
});
if (changed) await writeDb(next);
}
app.get("/api/shaders", async (_req, res) => {
try {
const shaders = await readDb();
@@ -44,8 +128,9 @@ app.post("/api/shaders", async (req, res) => {
if (!name || typeof name !== "string") {
return res.status(400).json({ error: "name 必填" });
}
if (!code || typeof code !== "string" || !code.includes("mainImage")) {
return res.status(400).json({ error: "code 必须包含 mainImage" });
const { error: parseError, normalized } = normalizeIncomingCode(code);
if (parseError) {
return res.status(400).json({ error: parseError });
}
try {
@@ -54,10 +139,11 @@ app.post("/api/shaders", async (req, res) => {
id: crypto.randomUUID(),
name: name.trim(),
author: String(author || "unknown").trim() || "unknown",
code,
code: normalized,
views: Math.floor(3000 + Math.random() * 22000),
likes: Math.floor(40 + Math.random() * 700),
createdAt: new Date().toISOString(),
sourceFormat: code.includes("metal::") ? "angle-metal-auto-converted" : "glsl",
};
shaders.unshift(item);
await writeDb(shaders);
@@ -82,6 +168,7 @@ app.delete("/api/shaders/:id", async (req, res) => {
});
ensureDb().then(() => {
autoNormalizeStoredShaders().catch(() => {});
app.listen(PORT, () => {
console.log(`Server running: http://localhost:${PORT}`);
});