Files
workinf_Blender_Wasm/my-tools/diagnose_local_scene_strips.mjs
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

78 lines
3.6 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import createEngine from '../build_web_blender6/bin/web_engine.js';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const stages = [];
const engine = await createEngine({ wasmBinary: fs.readFileSync(path.join(root, 'build_web_blender6/bin/web_engine.wasm')) });
const handle = engine._web_engine_create();
const slots = engine._malloc(8);
const read = () => {
const pointer = engine.HEAPU32[slots / 4], length = engine.HEAPU32[slots / 4 + 1];
return JSON.parse(new TextDecoder().decode(engine.HEAPU8.slice(pointer, pointer + length)));
};
const snapshot = () => {
assert.equal(engine._web_engine_get_scene_snapshot(handle, slots, slots + 4), 0);
return read();
};
const apply = (sceneId, timeline, expected = true) => {
const start = performance.now();
const bytes = Buffer.from(JSON.stringify({ cmd: 'applyCommand', params: {
command: { type: 'setSequencerStrips', sceneId, timeline },
} }));
const pointer = engine._malloc(bytes.length);
try {
engine.HEAPU8.set(bytes, pointer);
assert.equal(engine._web_engine_call_json(handle, pointer, bytes.length, slots, slots + 4), 0);
const result = read();
assert.equal(result.ok, expected, result.error);
return result;
} finally {
engine._free(pointer);
stages.push({ stage: expected ? 'edit' : 'reject', seconds: (performance.now() - start) / 1000 });
}
};
try {
const start = performance.now();
const bytes = fs.readFileSync(path.join(root, 'tests/files/web/sequencer_scene_source.blend'));
const pointer = engine._malloc(bytes.length);
try {
engine.HEAPU8.set(bytes, pointer);
assert.equal(engine._web_engine_open_blend(handle, pointer, bytes.length), 0);
} finally { engine._free(pointer); }
stages.push({ stage: 'open', seconds: (performance.now() - start) / 1000 });
const initial = snapshot();
const scene = initial.scenes.find(scene => scene.name === 'SequencerScene');
const source = initial.scenes.find(scene => scene.name === 'SourceScene');
assert(scene && source);
const timeline = structuredClone(scene.sequencerTimeline);
timeline.strips.push({ id: 'strip:Web SCENE', name: 'Web SCENE', type: 'SCENE', sourceId: source.id,
frameStart: 1, frameEnd: 25, sourceStart: 0, sourceEnd: 24, channel: 5,
speed: 1, muted: false, locked: false });
apply(scene.id, timeline);
const accepted = snapshot();
const strips = accepted.scenes.find(item => item.id === scene.id).sequencerTimeline.strips;
assert.equal(strips.find(strip => strip.name === 'Web SCENE').sourceId, source.id);
assert.deepEqual(accepted.scenes.find(item => item.id === source.id), source);
for (const sourceId of [scene.id, 'scene:MissingLocalScene']) {
const invalid = structuredClone(timeline);
invalid.strips.at(-1).sourceId = sourceId;
const result = apply(scene.id, invalid, false);
assert.match(result.error, /own scene|missing scene/);
assert.deepEqual(snapshot().scenes, accepted.scenes);
}
apply(scene.id, scene.sequencerTimeline);
assert.deepEqual(snapshot().scenes.find(item => item.id === scene.id).sequencerTimeline.strips,
scene.sequencerTimeline.strips);
console.log(JSON.stringify({ status: 'PASS', stages }));
} catch (error) {
console.log(JSON.stringify({ status: 'FAIL', error: error.message, stages,
frames: String(error.stack).split('\n').filter(line => /wasm-function|wasm:/.test(line)).slice(0, 8) }));
process.exitCode = 1;
} finally {
engine._free(slots);
engine._web_engine_destroy(handle);
}