feat: add render graph driven renderer architecture
Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { APPLICATION_COMPILED, APPLICATION_HEADLESS } from "../test/application.js";
|
||||
import { APPLICATION_VERSION } from "../examples/blender/nodes/application.js";
|
||||
|
||||
const ids = [...APPLICATION_COMPILED.nodes.keys()];
|
||||
if (ids.length !== 22 || new Set(ids).size !== ids.length)
|
||||
throw new Error(`Application composition must contain 22 unique nodes; found ${ids.length}`);
|
||||
if (APPLICATION_COMPILED.nodes.size !== ids.length)
|
||||
throw new Error("Compiled application composition coverage differs from source");
|
||||
if (APPLICATION_COMPILED.version !== APPLICATION_VERSION)
|
||||
throw new Error("Compiled application version differs from its declared version");
|
||||
for (const [index, id] of ids.entries())
|
||||
if (APPLICATION_HEADLESS.materializeNode(`check-${index}`, id).typeId !== id)
|
||||
throw new Error(`Could not materialize ${id}`);
|
||||
const root = new URL("..", import.meta.url).pathname,
|
||||
src = join(root, "src");
|
||||
if (existsSync(join(src, "catalog"))) throw new Error("Published source must not contain an application catalog");
|
||||
const productionFiles = readdirSync(src, { recursive: true })
|
||||
.map(String)
|
||||
.filter((file) => /\.(?:ts|tsx)$/.test(file));
|
||||
const productionText = productionFiles.map((file) => readFileSync(join(src, file), "utf8")).join("\n");
|
||||
for (const forbidden of [
|
||||
/fxnode\.(?:common|shader|geometry|compositor)\./,
|
||||
/\b(?:LEGACY_COMPOSITION|BUILTIN_DESCRIPTORS|DESCRIPTOR_REGISTRY|CATALOG_NODE_IDS|BLENDER_DARK_THEME|BuiltinNodeTypeId|RenderTheme)\b/,
|
||||
/from\s+["'][^"']*examples\//,
|
||||
])
|
||||
if (forbidden.test(productionText)) throw new Error(`Concrete application authority leaked into src: ${forbidden}`);
|
||||
const exampleRoot = join(root, "examples/blender");
|
||||
const nodeRoot = join(exampleRoot, "nodes");
|
||||
const categoryIndexes = existsSync(nodeRoot)
|
||||
? readdirSync(nodeRoot, { recursive: true })
|
||||
.map(String)
|
||||
.filter((file) => file.endsWith("/index.ts"))
|
||||
: [];
|
||||
if (categoryIndexes.length) throw new Error(`Category helper indexes are forbidden: ${categoryIndexes.join(", ")}`);
|
||||
if (existsSync(join(exampleRoot, "application-composition.ts")))
|
||||
throw new Error("Deleted application aggregate was restored");
|
||||
if (existsSync(join(exampleRoot, "application-runtime.ts")))
|
||||
throw new Error("Application runtime was restored under example");
|
||||
for (const browserFile of [
|
||||
"application-browser.ts",
|
||||
"control-test/main.ts",
|
||||
"link-tools-test/main.ts",
|
||||
"ramp-test/main.ts",
|
||||
]) {
|
||||
const text = readFileSync(join(exampleRoot, browserFile), "utf8");
|
||||
if (/test\/application/.test(text)) throw new Error(`${browserFile} imports the test-only application authority`);
|
||||
}
|
||||
for (const externalRoot of ["examples", "test", "tools"])
|
||||
for (const file of readdirSync(join(root, externalRoot), { recursive: true }).map(String)) {
|
||||
if (!/\.tsx?$/.test(file)) continue;
|
||||
const text = readFileSync(join(root, externalRoot, file), "utf8");
|
||||
if (/(?:from\s*|import\s*\()["'](?:\.\.\/)+src(?:\/|["'])/.test(text))
|
||||
throw new Error(`${externalRoot}/${file} must import library source through @lib/`);
|
||||
}
|
||||
for (const sibling of ["minimal", "color-balance", "live-composition"])
|
||||
for (const file of readdirSync(join(root, "examples", sibling), { recursive: true }).map(String)) {
|
||||
if (!/\.tsx?$/.test(file)) continue;
|
||||
const text = readFileSync(join(root, "examples", sibling, file), "utf8");
|
||||
if (/blender\/(?:application-browser|main)|test\/application/.test(text))
|
||||
throw new Error(`examples/${sibling}/${file} imports Blender or test application bootstrap`);
|
||||
}
|
||||
const authoringFiles = [
|
||||
join(root, "test/application.ts"),
|
||||
join(root, "examples/shared/nodes/color-balance.ts"),
|
||||
...(existsSync(nodeRoot)
|
||||
? readdirSync(nodeRoot, { recursive: true })
|
||||
.map(String)
|
||||
.filter((file) => file.endsWith(".ts"))
|
||||
.map((file) => join(nodeRoot, file))
|
||||
: []),
|
||||
];
|
||||
const source = authoringFiles.map((file) => readFileSync(file, "utf8")).join("\n");
|
||||
for (const forbidden of [
|
||||
/Object\.fromEntries/,
|
||||
/\.reduce\s*\(/,
|
||||
/defaultSize/,
|
||||
/src\/catalog/,
|
||||
/src\/render\/theme/,
|
||||
/BUILTIN_DESCRIPTORS/,
|
||||
/LEGACY_COMPOSITION/,
|
||||
/defineFxNodeComposition/,
|
||||
])
|
||||
if (forbidden.test(source))
|
||||
throw new Error(`Application composition is derived through a forbidden adapter: ${forbidden}`);
|
||||
structuredClone(APPLICATION_COMPILED.source);
|
||||
console.log(
|
||||
`application composition: ${ids.length} unique, materializable nodes (version ${APPLICATION_COMPILED.source.version})`,
|
||||
);
|
||||
Reference in New Issue
Block a user