Shader library: fingerprint without node positions, a drag no longer recompiles (#65)
game-maker / suite (push) Successful in 9m5s

shaderFingerprint(graph) covers node id/type/params/ports and edge endpoints only;
x/y, collapsed, folded and edge ids stay out. ShaderLibrary keys on it and counts
compiles (__gm.shaderCompiles()). Measured before: one compile per preview step of a
node drag (12 for a harness drag); after: 0, a param change exactly +1.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-13 18:00:48 +02:00
1 parent 016e83c9b5
commit 102a649a35
6 files changed
+82 -6

No files matched your search

+6 -3
View File
@@ -1,14 +1,16 @@
import type { ShaderAsset } from '../core/model/Asset';
import { findAssetOf, type Project } from '../core/model/Project';
import { compileShader, type ShaderBuild } from '../core/shader/compile';
import { compileShader, shaderFingerprint, type ShaderBuild } from '../core/shader/compile';
import type { ShaderSource } from './shaders';
/**
* Compiled shader graphs, one per asset, recompiled when the graph's content changes. A graph is
* edited in place, so the cache keys on its serialized form rather than on its identity.
* edited in place, so the cache keys on a fingerprint of what the fragment depends on.
*/
export class ShaderLibrary {
private readonly builds = new Map<string, { fingerprint: string; build: ShaderBuild }>();
/** How often a graph went through the compiler – what the checks read to prove a move did not. */
compiles = 0;
private readonly started = performance.now();
/** Set from the test hook: the clock stands at this second until released. */
private frozenAt: number | null = null;
@@ -23,9 +25,10 @@ export class ShaderLibrary {
}
buildFor(asset: ShaderAsset): ShaderBuild {
const fingerprint = JSON.stringify(asset.graph);
const fingerprint = shaderFingerprint(asset.graph);
const cached = this.builds.get(asset.id);
if (cached && cached.fingerprint === fingerprint) return cached.build;
this.compiles += 1;
const build = compileShader(asset.graph);
this.builds.set(asset.id, { fingerprint, build });
return build;