@faicad/faijs 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/api-namespace.d.ts +7 -0
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +23 -22
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +26 -8
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +4 -1
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/generated/cad/script-face.d.ts +1 -1
- package/dist/api/generated/cad/script-face.d.ts.map +1 -1
- package/dist/api/generated/cad/script-face.js +1 -2
- package/dist/api/generated/cad/script-face.js.map +1 -1
- package/dist/api/generated/operations.js +16 -16
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js +0 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/script-face.d.ts +1 -4
- package/dist/api/generated/script-face.d.ts.map +1 -1
- package/dist/api/generated/script-face.js +2 -3
- package/dist/api/generated/script-face.js.map +1 -1
- package/dist/api/generated/sketching.js +1 -1
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/topology.d.ts +0 -8
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +19 -26
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/index.d.ts +1 -10
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +10 -18
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-projection.d.ts +3 -1
- package/dist/api/internal/compat-projection.d.ts.map +1 -1
- package/dist/api/internal/compat-projection.js +8 -5
- package/dist/api/internal/compat-projection.js.map +1 -1
- package/dist/api/internal/replica-role-table.d.ts +36 -0
- package/dist/api/internal/replica-role-table.d.ts.map +1 -0
- package/dist/api/internal/replica-role-table.js +73 -0
- package/dist/api/internal/replica-role-table.js.map +1 -0
- package/dist/api/internal/result-unwrap.d.ts +3 -1
- package/dist/api/internal/result-unwrap.d.ts.map +1 -1
- package/dist/api/internal/result-unwrap.js +2 -2
- package/dist/api/internal/result-unwrap.js.map +1 -1
- package/dist/api/occt-kernel-bridge.d.ts +105 -27
- package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
- package/dist/api/occt-kernel-bridge.js +255 -41
- package/dist/api/occt-kernel-bridge.js.map +1 -1
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +25 -61
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/replicate.d.ts +145 -0
- package/dist/api/replicate.d.ts.map +1 -0
- package/dist/api/replicate.js +351 -0
- package/dist/api/replicate.js.map +1 -0
- package/dist/api/revolve.d.ts +36 -0
- package/dist/api/revolve.d.ts.map +1 -0
- package/dist/api/revolve.js +165 -0
- package/dist/api/revolve.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +8 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +37 -36
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/surface/projection-overrides.d.ts.map +1 -1
- package/dist/api/surface/projection-overrides.js +6 -0
- package/dist/api/surface/projection-overrides.js.map +1 -1
- package/dist/boolean/deriveNormals.d.ts +5 -4
- package/dist/boolean/deriveNormals.d.ts.map +1 -1
- package/dist/boolean/deriveNormals.js +24 -7
- package/dist/boolean/deriveNormals.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +58 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +39 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +1 -5
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +232 -18
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +79 -0
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/types.d.ts +18 -1
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +81 -11
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/browser.d.ts +6 -28
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +6 -17
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +13 -18
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +25 -18
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +4 -2
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +2 -0
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +4 -6
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +4 -9
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +0 -7
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +1 -3
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +13 -18
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/env-agnostic.d.ts +38 -0
- package/dist/env-agnostic.d.ts.map +1 -0
- package/dist/env-agnostic.js +29 -0
- package/dist/env-agnostic.js.map +1 -0
- package/dist/fcstd/codegen.d.ts.map +1 -1
- package/dist/fcstd/codegen.js +8 -1
- package/dist/fcstd/codegen.js.map +1 -1
- package/dist/fcstd/expressions.d.ts +24 -0
- package/dist/fcstd/expressions.d.ts.map +1 -1
- package/dist/fcstd/expressions.js +91 -0
- package/dist/fcstd/expressions.js.map +1 -1
- package/dist/fcstd/feature-translate.d.ts.map +1 -1
- package/dist/fcstd/feature-translate.js +16 -2
- package/dist/fcstd/feature-translate.js.map +1 -1
- package/dist/fcstd/structural-types.d.ts.map +1 -1
- package/dist/fcstd/structural-types.js +5 -0
- package/dist/fcstd/structural-types.js.map +1 -1
- package/dist/index.d.ts +7 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -16
- package/dist/index.js.map +1 -1
- package/dist/lang/determinism-scanner.d.ts +9 -0
- package/dist/lang/determinism-scanner.d.ts.map +1 -1
- package/dist/lang/determinism-scanner.js +7 -1
- package/dist/lang/determinism-scanner.js.map +1 -1
- package/dist/lang/symbol-table.d.ts +31 -0
- package/dist/lang/symbol-table.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +6 -16
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +6 -16
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/lang/symbol-table.js +50 -1
- package/dist/lang/symbol-table.js.map +1 -1
- package/dist/mesh/creased-normals.d.ts +50 -0
- package/dist/mesh/creased-normals.d.ts.map +1 -0
- package/dist/mesh/creased-normals.js +114 -0
- package/dist/mesh/creased-normals.js.map +1 -0
- package/dist/mesh/decoration-provider.d.ts +53 -0
- package/dist/mesh/decoration-provider.d.ts.map +1 -0
- package/dist/mesh/decoration-provider.js +21 -0
- package/dist/mesh/decoration-provider.js.map +1 -0
- package/dist/mesh/engrave.d.ts +4 -0
- package/dist/mesh/engrave.d.ts.map +1 -1
- package/dist/mesh/engrave.js +22 -31
- package/dist/mesh/engrave.js.map +1 -1
- package/dist/mesh/index.d.ts +5 -14
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +7 -19
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/io.d.ts +2 -1
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +5 -7
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/primitives.d.ts +5 -18
- package/dist/mesh/primitives.d.ts.map +1 -1
- package/dist/mesh/primitives.js +4 -48
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/stl-loader.d.ts +23 -0
- package/dist/mesh/stl-loader.d.ts.map +1 -0
- package/dist/mesh/stl-loader.js +139 -0
- package/dist/mesh/stl-loader.js.map +1 -0
- package/dist/module-resolver/parse-imports.d.ts +37 -0
- package/dist/module-resolver/parse-imports.d.ts.map +1 -0
- package/dist/module-resolver/parse-imports.js +39 -0
- package/dist/module-resolver/parse-imports.js.map +1 -0
- package/dist/module-resolver/resolver.d.ts +1 -1
- package/dist/module-resolver/resolver.js +2 -2
- package/dist/module-resolver/resolver.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +1 -22
- package/dist/node-host/cli.js.map +1 -1
- package/dist/primitives/text/cjk-font.d.ts +42 -0
- package/dist/primitives/text/cjk-font.d.ts.map +1 -0
- package/dist/primitives/text/cjk-font.js +86 -0
- package/dist/primitives/text/cjk-font.js.map +1 -0
- package/dist/sdk.d.ts +2 -2
- package/dist/sdk.js +2 -2
- package/dist/sdk.js.map +1 -1
- package/dist/symbol-table.d.ts +15 -0
- package/dist/symbol-table.d.ts.map +1 -0
- package/dist/symbol-table.js +14 -0
- package/dist/symbol-table.js.map +1 -0
- package/dist/topology/naming/lineage-resolve.js +1 -1
- package/dist/topology/naming/lineage-resolve.js.map +1 -1
- package/dist/vendored/brepjs/kernel/index.d.ts +5 -0
- package/dist/vendored/brepjs/kernel/index.d.ts.map +1 -1
- package/dist/vendored/brepjs/kernel/index.js +11 -0
- package/dist/vendored/brepjs/kernel/index.js.map +1 -1
- package/dist/weapp.d.ts +3 -3
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +6 -3
- package/dist/weapp.js.map +1 -1
- package/package.json +16 -14
- package/dist/api/compat/index.d.ts +0 -173
- package/dist/api/compat/index.d.ts.map +0 -1
- package/dist/api/compat/index.js +0 -222
- package/dist/api/compat/index.js.map +0 -1
- package/dist/api/compound.d.ts +0 -110
- package/dist/api/compound.d.ts.map +0 -1
- package/dist/api/compound.js +0 -164
- package/dist/api/compound.js.map +0 -1
- package/dist/api/copy.d.ts +0 -40
- package/dist/api/copy.d.ts.map +0 -1
- package/dist/api/copy.js +0 -83
- package/dist/api/copy.js.map +0 -1
- package/dist/api/fai_drill.d.ts +0 -46
- package/dist/api/fai_drill.d.ts.map +0 -1
- package/dist/api/fai_drill.js +0 -243
- package/dist/api/fai_drill.js.map +0 -1
- package/dist/api/fai_extrude.d.ts +0 -36
- package/dist/api/fai_extrude.d.ts.map +0 -1
- package/dist/api/fai_extrude.js +0 -79
- package/dist/api/fai_extrude.js.map +0 -1
- package/dist/api/fai_split.d.ts +0 -46
- package/dist/api/fai_split.d.ts.map +0 -1
- package/dist/api/fai_split.js +0 -254
- package/dist/api/fai_split.js.map +0 -1
- package/dist/api/load.d.ts +0 -41
- package/dist/api/load.d.ts.map +0 -1
- package/dist/api/load.js +0 -84
- package/dist/api/load.js.map +0 -1
- package/dist/api/svgExtrude.d.ts +0 -32
- package/dist/api/svgExtrude.d.ts.map +0 -1
- package/dist/api/svgExtrude.js +0 -74
- package/dist/api/svgExtrude.js.map +0 -1
- package/dist/api/text.d.ts +0 -34
- package/dist/api/text.d.ts.map +0 -1
- package/dist/api/text.js +0 -101
- package/dist/api/text.js.map +0 -1
- package/dist/brep/text/fontTestHelper.d.ts +0 -30
- package/dist/brep/text/fontTestHelper.d.ts.map +0 -1
- package/dist/brep/text/fontTestHelper.js +0 -57
- package/dist/brep/text/fontTestHelper.js.map +0 -1
- package/dist/cad-runtime/module-executor.d.ts +0 -271
- package/dist/cad-runtime/module-executor.d.ts.map +0 -1
- package/dist/cad-runtime/module-executor.js +0 -630
- package/dist/cad-runtime/module-executor.js.map +0 -1
- package/dist/cad-runtime/terminal-dag.d.ts +0 -65
- package/dist/cad-runtime/terminal-dag.d.ts.map +0 -1
- package/dist/cad-runtime/terminal-dag.js +0 -167
- package/dist/cad-runtime/terminal-dag.js.map +0 -1
- package/dist/faqts/browser.d.ts +0 -16
- package/dist/faqts/browser.d.ts.map +0 -1
- package/dist/faqts/browser.js +0 -13
- package/dist/faqts/browser.js.map +0 -1
- package/dist/faqts/exec-blob.d.ts +0 -14
- package/dist/faqts/exec-blob.d.ts.map +0 -1
- package/dist/faqts/exec-blob.js +0 -22
- package/dist/faqts/exec-blob.js.map +0 -1
- package/dist/faqts/exec-node.d.ts +0 -15
- package/dist/faqts/exec-node.d.ts.map +0 -1
- package/dist/faqts/exec-node.js +0 -29
- package/dist/faqts/exec-node.js.map +0 -1
- package/dist/faqts/imports.d.ts +0 -74
- package/dist/faqts/imports.d.ts.map +0 -1
- package/dist/faqts/imports.js +0 -95
- package/dist/faqts/imports.js.map +0 -1
- package/dist/faqts/index.d.ts +0 -22
- package/dist/faqts/index.d.ts.map +0 -1
- package/dist/faqts/index.js +0 -21
- package/dist/faqts/index.js.map +0 -1
- package/dist/faqts/node.d.ts +0 -23
- package/dist/faqts/node.d.ts.map +0 -1
- package/dist/faqts/node.js +0 -23
- package/dist/faqts/node.js.map +0 -1
- package/dist/faqts/run.d.ts +0 -62
- package/dist/faqts/run.d.ts.map +0 -1
- package/dist/faqts/run.js +0 -62
- package/dist/faqts/run.js.map +0 -1
- package/dist/faqts/transform.d.ts +0 -43
- package/dist/faqts/transform.d.ts.map +0 -1
- package/dist/faqts/transform.js +0 -35
- package/dist/faqts/transform.js.map +0 -1
- package/dist/lang/compile.d.ts +0 -50
- package/dist/lang/compile.d.ts.map +0 -1
- package/dist/lang/compile.js +0 -368
- package/dist/lang/compile.js.map +0 -1
- package/dist/lang/keep.d.ts +0 -109
- package/dist/lang/keep.d.ts.map +0 -1
- package/dist/lang/keep.js +0 -226
- package/dist/lang/keep.js.map +0 -1
- package/dist/lang/parser.d.ts +0 -91
- package/dist/lang/parser.d.ts.map +0 -1
- package/dist/lang/parser.js +0 -1594
- package/dist/lang/parser.js.map +0 -1
- package/dist/mesh/drill-hole/DrillHoleCore.d.ts +0 -90
- package/dist/mesh/drill-hole/DrillHoleCore.d.ts.map +0 -1
- package/dist/mesh/drill-hole/DrillHoleCore.js +0 -287
- package/dist/mesh/drill-hole/DrillHoleCore.js.map +0 -1
- package/dist/mesh/drill-hole/drill-types.d.ts +0 -34
- package/dist/mesh/drill-hole/drill-types.d.ts.map +0 -1
- package/dist/mesh/drill-hole/drill-types.js +0 -7
- package/dist/mesh/drill-hole/drill-types.js.map +0 -1
- package/dist/mesh/fai_drill.d.ts +0 -21
- package/dist/mesh/fai_drill.d.ts.map +0 -1
- package/dist/mesh/fai_drill.js +0 -92
- package/dist/mesh/fai_drill.js.map +0 -1
- package/dist/mesh/fai_extrude.d.ts +0 -24
- package/dist/mesh/fai_extrude.d.ts.map +0 -1
- package/dist/mesh/fai_extrude.js +0 -42
- package/dist/mesh/fai_extrude.js.map +0 -1
- package/dist/mesh/fai_split.d.ts +0 -164
- package/dist/mesh/fai_split.d.ts.map +0 -1
- package/dist/mesh/fai_split.js +0 -269
- package/dist/mesh/fai_split.js.map +0 -1
- package/dist/primitives/svg-extrude.d.ts +0 -43
- package/dist/primitives/svg-extrude.d.ts.map +0 -1
- package/dist/primitives/svg-extrude.js +0 -78
- package/dist/primitives/svg-extrude.js.map +0 -1
- package/dist/primitives/text/cjk.d.ts +0 -61
- package/dist/primitives/text/cjk.d.ts.map +0 -1
- package/dist/primitives/text/cjk.js +0 -215
- package/dist/primitives/text/cjk.js.map +0 -1
- package/dist/primitives/text-geometry.d.ts +0 -47
- package/dist/primitives/text-geometry.d.ts.map +0 -1
- package/dist/primitives/text-geometry.js +0 -127
- package/dist/primitives/text-geometry.js.map +0 -1
- package/dist/test-helpers.d.ts +0 -31
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js +0 -55
- package/dist/test-helpers.js.map +0 -1
- package/dist/vendored/brepjs/core/kernelReentrancy.d.ts +0 -41
- package/dist/vendored/brepjs/core/kernelReentrancy.d.ts.map +0 -1
- package/dist/vendored/brepjs/core/kernelReentrancy.js +0 -68
- package/dist/vendored/brepjs/core/kernelReentrancy.js.map +0 -1
|
@@ -1,630 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* module-executor — JS VM 模块加载与增量调度(VM 执行方案 Phase 1)
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* ModuleExecutor 是 VM 执行的核心:
|
|
6
|
-
* - `ctx` 持久变量容器(跨 execute/append/update 存活)
|
|
7
|
-
* - `load(code)` 用 data:/Blob URL 动态 import 编译产物(零 import,两平台同构)
|
|
8
|
-
* - `executeAll/executeIds/executeFrom` 按 deps 拓扑序调度
|
|
9
|
-
* - `reconcileCtx` 回收"定义语句已不在脚本中"的变量并释放其内核资源
|
|
10
|
-
* - `cache` 记录每语句 statementKey + outputContentKey(plan 增量判定)
|
|
11
|
-
*/
|
|
12
|
-
import { isVarRef, isExprRef, statementInputs } from '../lang/types.js';
|
|
13
|
-
import { withoutKeepDirectives, withoutKeepDirectivesFromPositional } from '../lang/keep.js';
|
|
14
|
-
import { OpError } from '../api/internal/result-unwrap.js';
|
|
15
|
-
import { asPartName } from '../identity.js';
|
|
16
|
-
import { computeContentKey } from './content-key.js';
|
|
17
|
-
import { getSlot, hasBrep, brepOf, ensureSlot, isCompoundLike } from '../shape.js';
|
|
18
|
-
import { setCurrentStmt, setName, getBackends, takePendingAssemblyTransforms, enterFunctionBrep, exitFunctionBrep, takeFunctionBrepDomain } from '../runtime-state.js';
|
|
19
|
-
import { applyTransform } from '../mesh/rigid-transform.js';
|
|
20
|
-
import { applyTransformBrep } from '../brep/brep-ops.js';
|
|
21
|
-
/** 动态 import 编译产物(Node: data: URL;浏览器: Blob URL)。 */
|
|
22
|
-
async function importModule(code) {
|
|
23
|
-
const isNode = typeof process !== 'undefined' && !!process.versions?.node;
|
|
24
|
-
if (isNode) {
|
|
25
|
-
const url = `data:text/javascript;base64,${Buffer.from(code).toString('base64')}`;
|
|
26
|
-
return import(/* @vite-ignore */ url);
|
|
27
|
-
}
|
|
28
|
-
const blob = new Blob([code], { type: 'text/javascript' });
|
|
29
|
-
const url = URL.createObjectURL(blob);
|
|
30
|
-
try {
|
|
31
|
-
return await import(/* @vite-ignore */ url);
|
|
32
|
-
}
|
|
33
|
-
finally {
|
|
34
|
-
URL.revokeObjectURL(url);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 收集一个值可到达的全部 BREP 句柄(函数返回值 keep 集,§5.6):
|
|
39
|
-
* shape → 身份槽 solid;compound → children 递归;数组 / 普通对象 → 递归。
|
|
40
|
-
*/
|
|
41
|
-
function collectBrepHandles(v, out) {
|
|
42
|
-
if (v === null || v === undefined)
|
|
43
|
-
return;
|
|
44
|
-
if (typeof v !== 'object')
|
|
45
|
-
return;
|
|
46
|
-
if (v instanceof Set || v instanceof Map)
|
|
47
|
-
return;
|
|
48
|
-
// shape:身份槽持 OCCT 句柄
|
|
49
|
-
const slot = getSlot(v);
|
|
50
|
-
if (slot?.solid)
|
|
51
|
-
out.add(slot.solid);
|
|
52
|
-
// compound children / 数组 / 对象递归
|
|
53
|
-
if (Array.isArray(v)) {
|
|
54
|
-
for (const item of v)
|
|
55
|
-
collectBrepHandles(item, out);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (isCompoundLike(v)) {
|
|
59
|
-
for (const child of v.children)
|
|
60
|
-
collectBrepHandles(child, out);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
for (const k of Object.keys(v)) {
|
|
64
|
-
// 跳过内部元数据字段(positions/indices/kind 等 mesh 数据不含句柄,无需遍历)
|
|
65
|
-
if (k === 'positions' || k === 'indices' || k === 'kind')
|
|
66
|
-
continue;
|
|
67
|
-
collectBrepHandles(v[k], out);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* ModuleExecutor loads JS VM modules and schedules incremental execution.
|
|
72
|
-
*
|
|
73
|
-
* It is the heart of the VM execution approach: it keeps the persistent `ctx`
|
|
74
|
-
* variable container alive across execute/append/update calls, dynamically
|
|
75
|
-
* imports compiled modules from data:/Blob URLs (zero imports, isomorphic on
|
|
76
|
-
* both platforms), schedules all/selected/from statements in dependency
|
|
77
|
-
* topological order, reclaims variables whose defining statements have left the
|
|
78
|
-
* script, and caches each statement's key + output content key for incremental
|
|
79
|
-
* planning.
|
|
80
|
-
*/
|
|
81
|
-
export class ModuleExecutor {
|
|
82
|
-
/** Persistent variable container across incremental executions. */
|
|
83
|
-
ctx = {};
|
|
84
|
-
stmts = new Map();
|
|
85
|
-
/** statementKey 缓存(增量判定;key = op|JSON(args)|deps 的 outputContentKey) */
|
|
86
|
-
cache = new Map();
|
|
87
|
-
/**
|
|
88
|
-
* 函数体 keep 登记(keep-syntax 设计 §2.2):
|
|
89
|
-
* stmtId → { kept, hidden }。语句执行前清空本条记录,执行中累加;
|
|
90
|
-
* 本轮未执行(缓存命中)→ 保留上一轮记录(keep 零重算的前提)。
|
|
91
|
-
*/
|
|
92
|
-
internalKeep = new Map();
|
|
93
|
-
sourceById = new Map();
|
|
94
|
-
metaById = new Map();
|
|
95
|
-
script = { params: [], statements: [] };
|
|
96
|
-
lastCode = '';
|
|
97
|
-
/**
|
|
98
|
-
* 默认命名空间绑定名(U10/R2):与 runtime 的 registerLib(…, {default: true}) 声明同步;
|
|
99
|
-
* statementKey/computeKey 中 namespace 缺省(undefined)的语句按该绑定名计 key。
|
|
100
|
-
*/
|
|
101
|
-
defaultNsName = 'cad';
|
|
102
|
-
/**
|
|
103
|
-
* Sync the default namespace binding name (called by runtime.registerLib with {default:true}).
|
|
104
|
-
* @param name - the namespace binding name to use as default.
|
|
105
|
-
*/
|
|
106
|
-
setDefaultNsName(name) {
|
|
107
|
-
this.defaultNsName = name;
|
|
108
|
-
}
|
|
109
|
-
namespaces;
|
|
110
|
-
/** 库内容身份表(binding → content hash;增量 key 版控,B2 §7.3) */
|
|
111
|
-
libIds = new Map();
|
|
112
|
-
/** 本机函数调用嵌套深度(§5.5):> 0 表示当前在函数体内执行——keep 登记被抑制。 */
|
|
113
|
-
userFunctionDepth = 0;
|
|
114
|
-
releaseSolid;
|
|
115
|
-
getSolid;
|
|
116
|
-
releaseHandle;
|
|
117
|
-
setSolid;
|
|
118
|
-
setFaceEvolution;
|
|
119
|
-
setRoleTable;
|
|
120
|
-
constructor(namespaces, options) {
|
|
121
|
-
this.namespaces = namespaces;
|
|
122
|
-
this.releaseSolid = options?.releaseSolid;
|
|
123
|
-
this.getSolid = options?.getSolid;
|
|
124
|
-
this.releaseHandle = options?.releaseHandle;
|
|
125
|
-
this.setSolid = options?.setSolid;
|
|
126
|
-
this.setFaceEvolution = options?.setFaceEvolution;
|
|
127
|
-
this.setRoleTable = options?.setRoleTable;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Hot-update the assembled namespace set (after registerLib mounts a new
|
|
131
|
-
* library).
|
|
132
|
-
* @param namespaces - the new assembled namespaces.
|
|
133
|
-
* @param libIds - the library content-identity table (binding → libId), used
|
|
134
|
-
* to version library-branch statement keys (B2, §7.3).
|
|
135
|
-
*/
|
|
136
|
-
setNamespaces(namespaces, libIds = new Map()) {
|
|
137
|
-
this.namespaces = namespaces;
|
|
138
|
-
this.libIds = libIds;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Update the script and its compiled metadata (ctx stays alive).
|
|
142
|
-
* @param script - the parsed ScriptIR.
|
|
143
|
-
* @param compiled - the compiled statement metadata.
|
|
144
|
-
*/
|
|
145
|
-
setCompiled(script, compiled) {
|
|
146
|
-
this.script = script;
|
|
147
|
-
this.metaById = new Map(compiled.map((m) => [m.id, m]));
|
|
148
|
-
this.sourceById = new Map();
|
|
149
|
-
for (const meta of compiled) {
|
|
150
|
-
if (meta.sourceIndex !== undefined) {
|
|
151
|
-
this.sourceById.set(meta.id, script.statements[meta.sourceIndex]);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Load the compiled module, skipping a reload when the code is unchanged
|
|
157
|
-
* (compiled-product cache).
|
|
158
|
-
* @param code - the compiled module source.
|
|
159
|
-
*/
|
|
160
|
-
async load(code) {
|
|
161
|
-
if (code === this.lastCode)
|
|
162
|
-
return;
|
|
163
|
-
const mod = await importModule(code);
|
|
164
|
-
this.stmts = new Map(mod.statements.map((s) => [s.id, s]));
|
|
165
|
-
this.lastCode = code;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Execute every statement in dependency topological order (i.e. statement
|
|
169
|
-
* table order).
|
|
170
|
-
* @param exec - the execution bookkeeping.
|
|
171
|
-
*/
|
|
172
|
-
async executeAll(exec) {
|
|
173
|
-
await this.executeIds([...this.stmts.keys()], exec);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Execute only the given statements (append: the prefix is already in the
|
|
177
|
-
* persistent ctx). As in the old interpreter, beforeStatement fires only for
|
|
178
|
-
* new_shape statements; void/same_shape statements (do_assemble/add_constraint)
|
|
179
|
-
* do not trigger it (do_assemble's fn delegates internally).
|
|
180
|
-
* @param ids - the compiled statement ids to execute.
|
|
181
|
-
* @param exec - the execution bookkeeping.
|
|
182
|
-
*/
|
|
183
|
-
async executeIds(ids, exec) {
|
|
184
|
-
for (const id of ids) {
|
|
185
|
-
const compiled = this.stmts.get(id);
|
|
186
|
-
if (!compiled)
|
|
187
|
-
throw new Error(`[ModuleExecutor] unknown statement "${id}"`);
|
|
188
|
-
const source = this.sourceById.get(id);
|
|
189
|
-
const meta = this.metaById.get(id);
|
|
190
|
-
// 顶替释放预捕获:fn 前捕获本语句写键({id} ∪ outputs)的旧 handle;
|
|
191
|
-
// 必须在 fn 之前捕获——op 执行时已用 solidCache.set 覆盖条目,事后拿不到旧引用。
|
|
192
|
-
const oldHandles = (meta?.writes ?? [])
|
|
193
|
-
.map((w) => this.getSolid?.(asPartName(w)))
|
|
194
|
-
.filter((h) => !!h);
|
|
195
|
-
// P6:changed 由引擎比对推导(替代旧的 touch 声明机制)
|
|
196
|
-
const oldWrites = new Map();
|
|
197
|
-
for (const w of meta?.writes ?? [])
|
|
198
|
-
oldWrites.set(w, this.ctx[w]);
|
|
199
|
-
setCurrentStmt(source); // P5:新 keep() 归属当前语句
|
|
200
|
-
// keep 登记先清空本条记录:重执行的语句重新登记(执行中累加,设计 §2.2)
|
|
201
|
-
this.internalKeep.delete(id);
|
|
202
|
-
if (source && source.hasAssignment) {
|
|
203
|
-
exec.beforeStatement?.(String(source.id), this.script.statements.indexOf(source));
|
|
204
|
-
}
|
|
205
|
-
// 本机函数调用(local):进入函数 BREP 域(§5.6),提升 userFunctionDepth(keep 隔离,§5.5)。
|
|
206
|
-
// 函数体执行期间:内部 keep 登记被抑制(registerKeep no-op);体内瞬态句柄登记到域,
|
|
207
|
-
// 结束后释放除返回值可到达句柄外的全部(finally 保证异常路径同样释放)。
|
|
208
|
-
const isLocal = source?.local === true;
|
|
209
|
-
if (isLocal) {
|
|
210
|
-
this.userFunctionDepth++;
|
|
211
|
-
enterFunctionBrep();
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
await compiled.fn(this.ctx, this.namespaces);
|
|
215
|
-
}
|
|
216
|
-
catch (err) {
|
|
217
|
-
// D4(true-JS-subset §4.3.2):表达式求值失败(编译产物内标记的
|
|
218
|
-
// __FaiExprEvalError)包装为 OpError(E_EXPR) 重抛,由 runWithFailureHandling
|
|
219
|
-
// 归并为 ExecutionResult.failedAt(语句归属经 setCurrentStmt 已定位)。
|
|
220
|
-
// 其余异常原样抛穿:Brep/MeshUnsupported → failedAt;op 实现的普通异常
|
|
221
|
-
//(= bug,Result 体系契约)不在此处改变语义。
|
|
222
|
-
if (err instanceof Error && err.isExprEvalError === true) {
|
|
223
|
-
throw new OpError(source?.callee ?? String(id), 'E_EXPR', err.message);
|
|
224
|
-
}
|
|
225
|
-
throw err;
|
|
226
|
-
}
|
|
227
|
-
finally {
|
|
228
|
-
if (isLocal) {
|
|
229
|
-
this.releaseFunctionBrepDomain(compiled, meta);
|
|
230
|
-
exitFunctionBrep();
|
|
231
|
-
this.userFunctionDepth--;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
await this.afterStatement(compiled, exec);
|
|
235
|
-
for (const [w, old] of oldWrites) {
|
|
236
|
-
if (old !== this.ctx[w])
|
|
237
|
-
exec.changed.add(asPartName(w));
|
|
238
|
-
}
|
|
239
|
-
// 顶替释放:执行成功后才释放旧 handle(失败时缓存保持执行前状态,天然回滚)
|
|
240
|
-
for (const old of oldHandles) {
|
|
241
|
-
this.releaseHandle?.(old);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Re-execute from the change points on (update: plan derives the stale set).
|
|
247
|
-
* The stale set is closed over deps (a statement depending on a stale one is
|
|
248
|
-
* itself stale) and runs in topological order.
|
|
249
|
-
* @param staleIds - the set of stale statement ids to recompute.
|
|
250
|
-
* @param exec - the execution bookkeeping.
|
|
251
|
-
*/
|
|
252
|
-
async executeFrom(staleIds, exec) {
|
|
253
|
-
const ordered = [];
|
|
254
|
-
const visited = new Set();
|
|
255
|
-
const visit = (id) => {
|
|
256
|
-
if (visited.has(id))
|
|
257
|
-
return;
|
|
258
|
-
visited.add(id);
|
|
259
|
-
const meta = this.metaById.get(id);
|
|
260
|
-
if (meta) {
|
|
261
|
-
for (const dep of meta.deps) {
|
|
262
|
-
if (staleIds.has(dep))
|
|
263
|
-
visit(dep);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
ordered.push(id);
|
|
267
|
-
};
|
|
268
|
-
for (const id of staleIds)
|
|
269
|
-
visit(id);
|
|
270
|
-
await this.executeIds(ordered, exec);
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Reclaim ctx variables whose defining statement is no longer in the script
|
|
274
|
-
* and release their kernel resources (a required action after undoing a
|
|
275
|
-
* statement deletion). Variables in `referencedVars` are kept even when not
|
|
276
|
-
* written by an active statement (cross-file references to other files'
|
|
277
|
-
* parts).
|
|
278
|
-
* @param activeStmtIds - the ids of statements still considered active.
|
|
279
|
-
* @param writeSets - mapping of statement id to the variable names it writes.
|
|
280
|
-
* @param referencedVars - variable names still referenced by the active
|
|
281
|
-
* script; these survive reclaim.
|
|
282
|
-
*/
|
|
283
|
-
reconcileCtx(activeStmtIds, writeSets, referencedVars) {
|
|
284
|
-
const activeWrites = new Set();
|
|
285
|
-
for (const [id, writes] of writeSets) {
|
|
286
|
-
if (activeStmtIds.has(id)) {
|
|
287
|
-
for (const w of writes)
|
|
288
|
-
activeWrites.add(w);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
for (const key of Object.keys(this.ctx)) {
|
|
292
|
-
if (!activeWrites.has(key) && !(referencedVars?.has(key) ?? false)) {
|
|
293
|
-
this.releaseSolid?.(asPartName(key));
|
|
294
|
-
delete this.ctx[key];
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// keep 登记同步修剪:语句已不在脚本中(undo 删除)→ 其 keep 声明失效
|
|
298
|
-
for (const id of [...this.internalKeep.keys()]) {
|
|
299
|
-
if (!activeStmtIds.has(id))
|
|
300
|
-
this.internalKeep.delete(id);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
// ── 缓存访问(plan / collectResult 用) ──
|
|
304
|
-
/** 清除所有缓存(key 缓存 + ctx 变量)。测试用:CadRuntime.clearStatementCache 调用。 */
|
|
305
|
-
clearCache() {
|
|
306
|
-
for (const key of Object.keys(this.ctx)) {
|
|
307
|
-
this.releaseSolid?.(asPartName(key));
|
|
308
|
-
delete this.ctx[key];
|
|
309
|
-
}
|
|
310
|
-
this.cache.clear();
|
|
311
|
-
this.script = { params: [], statements: [] };
|
|
312
|
-
this.metaById.clear();
|
|
313
|
-
this.stmts.clear();
|
|
314
|
-
this.sourceById.clear();
|
|
315
|
-
this.internalKeep.clear();
|
|
316
|
-
this.lastCode = '';
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Read a statement's statementKey cache entry.
|
|
320
|
-
* @param id - the compiled statement id.
|
|
321
|
-
* @returns the cached key and output content key, or undefined.
|
|
322
|
-
*/
|
|
323
|
-
getCachedKey(id) {
|
|
324
|
-
return this.cache.get(id);
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Read a statement's function-body keep registration (used by the terminal-dag
|
|
328
|
-
* C1 check); undefined when none exists.
|
|
329
|
-
* @param id - the compiled statement id.
|
|
330
|
-
* @returns the internal keep record, or undefined.
|
|
331
|
-
*/
|
|
332
|
-
getInternalKeep(id) {
|
|
333
|
-
return this.internalKeep.get(id);
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Register a function-body keep entry into ModuleExecutor.internalKeep,
|
|
337
|
-
* accumulating during execution.
|
|
338
|
-
* @param id - the compiled statement id.
|
|
339
|
-
* @param names - the kept variable names.
|
|
340
|
-
* @param hidden - whether the kept variables are hidden.
|
|
341
|
-
*/
|
|
342
|
-
registerKeep(id, names, hidden) {
|
|
343
|
-
// 函数 BREP 域 / keep 隔离(§5.5 / D5):本机函数体内嵌套 cad.* 的库内部
|
|
344
|
-
// keep 登记一律抑制——保留语义由调用点 keep 表达,函数体不向顶层传播保留。
|
|
345
|
-
if (this.userFunctionDepth > 0)
|
|
346
|
-
return;
|
|
347
|
-
let rec = this.internalKeep.get(id);
|
|
348
|
-
if (!rec) {
|
|
349
|
-
rec = { kept: new Set(), hidden: new Map() };
|
|
350
|
-
this.internalKeep.set(id, rec);
|
|
351
|
-
}
|
|
352
|
-
for (const n of names) {
|
|
353
|
-
rec.kept.add(n);
|
|
354
|
-
rec.hidden.set(n, hidden);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* 函数 BREP 域释放(§5.6 / D13):取走当前域的句柄登记表,收集本语句输出
|
|
359
|
-
* (返回值)可到达的全部句柄为 keep 集,释放登记域内除 keep 集外的全部句柄。
|
|
360
|
-
* 函数体内中间体的瞬态句柄在此一次性释放——单次调用内存有界,不逐轮释放。
|
|
361
|
-
*/
|
|
362
|
-
releaseFunctionBrepDomain(compiled, meta) {
|
|
363
|
-
const domain = takeFunctionBrepDomain();
|
|
364
|
-
if (domain.length === 0)
|
|
365
|
-
return;
|
|
366
|
-
// keep 集:返回值(语句 writes 的 ctx 值,可能是 shape / compound / 数组 / 对象)可到达的句柄
|
|
367
|
-
const kept = new Set();
|
|
368
|
-
for (const w of meta?.writes ?? []) {
|
|
369
|
-
const v = this.ctx[w];
|
|
370
|
-
collectBrepHandles(v, kept);
|
|
371
|
-
}
|
|
372
|
-
for (const h of domain) {
|
|
373
|
-
if (kept.has(h))
|
|
374
|
-
continue;
|
|
375
|
-
try {
|
|
376
|
-
this.releaseHandle?.(h);
|
|
377
|
-
}
|
|
378
|
-
catch { /* 已释放 */ }
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Read a ctx variable.
|
|
383
|
-
* @param name - the variable name.
|
|
384
|
-
* @returns the variable value.
|
|
385
|
-
*/
|
|
386
|
-
getCtxVar(name) {
|
|
387
|
-
return this.ctx[name];
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Write a ctx variable (used to sync assembly transforms from outputCache
|
|
391
|
-
* back into ctx).
|
|
392
|
-
* @param name - the variable name.
|
|
393
|
-
* @param value - the value to store.
|
|
394
|
-
*/
|
|
395
|
-
setCtxVar(name, value) {
|
|
396
|
-
this.ctx[name] = value;
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* All variable names currently held in the persistent ctx (covers parts
|
|
400
|
-
* executed by previous execute/append/update calls).
|
|
401
|
-
* @returns the ctx variable names.
|
|
402
|
-
*/
|
|
403
|
-
listCtxKeys() {
|
|
404
|
-
return Object.keys(this.ctx);
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Returns the compiled metadata in params + statements order.
|
|
408
|
-
* @returns the compiled statement metadata array.
|
|
409
|
-
*/
|
|
410
|
-
getMetas() {
|
|
411
|
-
return [...this.metaById.values()];
|
|
412
|
-
}
|
|
413
|
-
/** 清空 ctx 与 statementKey 缓存(CadRuntime.dispose 用)。 */
|
|
414
|
-
clear() {
|
|
415
|
-
for (const key of Object.keys(this.ctx))
|
|
416
|
-
delete this.ctx[key];
|
|
417
|
-
this.cache.clear();
|
|
418
|
-
this.internalKeep.clear();
|
|
419
|
-
this.stmts.clear();
|
|
420
|
-
this.lastCode = '';
|
|
421
|
-
}
|
|
422
|
-
// ── 内部 ──
|
|
423
|
-
/** 语句执行后:ctx → outputCache 同步 + 身份槽 → solidCache/faceEvolutionCache 同步 + statementKey 缓存 + 装配传播。 */
|
|
424
|
-
async afterStatement(compiled, exec) {
|
|
425
|
-
const source = this.sourceById.get(compiled.id);
|
|
426
|
-
const meta = this.metaById.get(compiled.id);
|
|
427
|
-
const writes = meta?.writes ?? [];
|
|
428
|
-
for (const w of writes) {
|
|
429
|
-
const v = this.ctx[w];
|
|
430
|
-
if (v !== undefined) {
|
|
431
|
-
if (typeof v === 'object' && v !== null) {
|
|
432
|
-
setName(v, asPartName(w)); // P3:新 keep() 反查走 runtime-state 映射(P5 删 exec 侧)
|
|
433
|
-
// 身份槽 → PartName 键控缓存同步(runtime 的 brepSolids/顶替释放/buildBrepTopology 依赖)
|
|
434
|
-
const slot = getSlot(v);
|
|
435
|
-
if (slot?.solid)
|
|
436
|
-
this.setSolid?.(asPartName(w), slot.solid);
|
|
437
|
-
if (slot?.faceEvolution)
|
|
438
|
-
this.setFaceEvolution?.(asPartName(w), slot.faceEvolution);
|
|
439
|
-
if (slot?.roleTable)
|
|
440
|
-
this.setRoleTable?.(asPartName(w), slot.roleTable);
|
|
441
|
-
}
|
|
442
|
-
exec.outputCache.set(asPartName(w), v);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
const key = meta ? this.computeKey(meta, source) : '';
|
|
446
|
-
const outputContentKey = this.computeOutputContentKey(compiled);
|
|
447
|
-
this.cache.set(compiled.id, { key, outputContentKey });
|
|
448
|
-
// P4:引擎统一发 part-brep-lost(F1:库不再读 currentStmt / 不再 emit)
|
|
449
|
-
// 语义:上游在 BREP 链上,但本语句产物不在链上 → BREP 链在此断开
|
|
450
|
-
this.emitBrepLost(compiled.id, source);
|
|
451
|
-
// P6:装配传播(求解在库,应用与失效在引擎)
|
|
452
|
-
await this.applyPendingAssemblyTransforms(exec);
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* P6:装配传播——取走全部待应用变换,引擎应用到成员(mesh 原地 + BREP 槽 + solidCache),
|
|
456
|
-
* 记录 changed,并让依赖成员的下游语句失效重算(DAG 重放,替代 exec.dependentsOf 图遍历)。
|
|
457
|
-
*/
|
|
458
|
-
async applyPendingAssemblyTransforms(exec) {
|
|
459
|
-
const pending = takePendingAssemblyTransforms();
|
|
460
|
-
if (pending.length === 0)
|
|
461
|
-
return;
|
|
462
|
-
const kernel = getBackends().kernel.brep;
|
|
463
|
-
for (const { compound, transforms } of pending) {
|
|
464
|
-
const behavior = getSlot(compound)?.behavior;
|
|
465
|
-
if (!behavior?.memberNames)
|
|
466
|
-
continue;
|
|
467
|
-
const children = compound.children ?? [];
|
|
468
|
-
const memberNames = behavior.memberNames;
|
|
469
|
-
for (const t of transforms) {
|
|
470
|
-
const member = children[t.index];
|
|
471
|
-
const name = memberNames[t.index];
|
|
472
|
-
if (!member || typeof member !== 'object')
|
|
473
|
-
continue;
|
|
474
|
-
// mesh 原地变换(保留同一对象引用,ctx 与 compound.children 同步看到变更)
|
|
475
|
-
Object.assign(member, applyTransform(member, t.quaternion, t.pivot, t.translation, t.rotationMatrix));
|
|
476
|
-
// BREP 刚体变换(可选):新 solid 写身份槽 + solidCache(替代旧 T6.5 反同步循环)
|
|
477
|
-
const solid = brepOf(member);
|
|
478
|
-
if (kernel && solid) {
|
|
479
|
-
const transformed = applyTransformBrep(kernel, solid, t.quaternion, t.pivot, t.translation);
|
|
480
|
-
try {
|
|
481
|
-
kernel.release(solid);
|
|
482
|
-
}
|
|
483
|
-
catch { /* 已释放 */ }
|
|
484
|
-
ensureSlot(member).solid = transformed;
|
|
485
|
-
if (name)
|
|
486
|
-
this.setSolid?.(asPartName(name), transformed);
|
|
487
|
-
}
|
|
488
|
-
if (name)
|
|
489
|
-
exec.changed.add(asPartName(name));
|
|
490
|
-
}
|
|
491
|
-
// 下游失效重算:依赖成员名的语句(拓扑序由 executeFrom 按 deps 保证)
|
|
492
|
-
const stale = this.computeDownstream(memberNames);
|
|
493
|
-
if (stale.size > 0)
|
|
494
|
-
await this.executeFrom(stale, exec);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
/** 找出依赖给定变量名的语句(装配成员 → 消费它的下游)。 */
|
|
498
|
-
computeDownstream(memberNames) {
|
|
499
|
-
const names = new Set(memberNames);
|
|
500
|
-
const stale = new Set();
|
|
501
|
-
for (const [id, source] of this.sourceById) {
|
|
502
|
-
if (statementInputs(source).some((n) => names.has(String(n))))
|
|
503
|
-
stale.add(id);
|
|
504
|
-
}
|
|
505
|
-
return stale;
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* 判定并发 part-brep-lost 事件。
|
|
509
|
-
*
|
|
510
|
-
* 判据:语句有几何输入且**全部**输入都在 BREP 链上,但输出**不在**链上
|
|
511
|
-
* → BREP 链在此断开(mesh-only 函数或 fallthrough)。
|
|
512
|
-
*
|
|
513
|
-
* true-JS-subset §4.4.2:几何输入 = positional 中的 VarRefIR + ExprIR.refs
|
|
514
|
-
* (表达式实参引用的 Shape 变量同样喂进本语句;CallRef 嵌套调用是只读查询不计)。
|
|
515
|
-
*/
|
|
516
|
-
emitBrepLost(id, source) {
|
|
517
|
-
if (!source)
|
|
518
|
-
return;
|
|
519
|
-
const inputNames = new Set();
|
|
520
|
-
const scanPositional = (arg) => {
|
|
521
|
-
if (arg === null || typeof arg !== 'object')
|
|
522
|
-
return;
|
|
523
|
-
if (isVarRef(arg)) {
|
|
524
|
-
inputNames.add(String(arg.$ref));
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (isExprRef(arg)) {
|
|
528
|
-
for (const r of arg.$expr.refs)
|
|
529
|
-
inputNames.add(r);
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
for (const arg of source.positional ?? [])
|
|
534
|
-
scanPositional(arg);
|
|
535
|
-
if (inputNames.size === 0)
|
|
536
|
-
return;
|
|
537
|
-
const sink = getBackends().events;
|
|
538
|
-
if (!sink)
|
|
539
|
-
return;
|
|
540
|
-
const inputsOnChain = [...inputNames]
|
|
541
|
-
.map((n) => this.ctx[n])
|
|
542
|
-
.filter((v) => !!v && typeof v === 'object');
|
|
543
|
-
if (inputsOnChain.length === 0)
|
|
544
|
-
return;
|
|
545
|
-
if (!inputsOnChain.every(hasBrep))
|
|
546
|
-
return; // 上游本就不在链上 → 非断开
|
|
547
|
-
const out = this.ctx[this.metaById.get(id)?.writes[0] ?? ''];
|
|
548
|
-
if (out && typeof out === 'object' && hasBrep(out))
|
|
549
|
-
return; // 输出仍在链上
|
|
550
|
-
sink.emit('part-brep-lost', {
|
|
551
|
-
partName: asPartName(String(source.outputs[0] ?? '')),
|
|
552
|
-
callee: source.callee,
|
|
553
|
-
reason: `${source.callee} has no BREP implementation`,
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Compute a statementKey = op | JSON(positional + args without keep) | each
|
|
558
|
-
* dependency's output content key (parameter statements use the parameter
|
|
559
|
-
* value). The keep/keepHidden keys are excluded so toggling retain/hide state
|
|
560
|
-
* triggers no geometric recompute. plan() uses this with the current cache to
|
|
561
|
-
* compute the expected key for incremental decisions.
|
|
562
|
-
*
|
|
563
|
-
* true-JS-subset §4.4.1:位置实参槽入 key——ExprIR 可 JSON 化
|
|
564
|
-
* (text + refs + params),表达式文本变化即触发重算;表达式引用的上游变量
|
|
565
|
-
* 变化经 deps 的 outputContentKey 传递。
|
|
566
|
-
*
|
|
567
|
-
* 本机函数调用(local):key 前缀 `local.<callee>#<bodyHash>`(§6.2 / P4 内容寻址)——
|
|
568
|
-
* 编辑函数体文本 → 所有调用该函数的语句 key 变化 → 下游失效重算;不改函数体零重算。
|
|
569
|
-
* @param meta - the compiled statement metadata.
|
|
570
|
-
* @param source - the source statement, or undefined for parameter statements.
|
|
571
|
-
* @returns the computed statement key string.
|
|
572
|
-
*/
|
|
573
|
-
computeKey(meta, source) {
|
|
574
|
-
const primary = meta.writes[0];
|
|
575
|
-
if (!source) {
|
|
576
|
-
const p = this.script.params.find((pp) => pp.name === primary);
|
|
577
|
-
return `param|${JSON.stringify(p?.value)}`;
|
|
578
|
-
}
|
|
579
|
-
const parts = [
|
|
580
|
-
source.local
|
|
581
|
-
? `local.${source.callee}#${this.bodyHashOf(source.callee)}`
|
|
582
|
-
: `${source.namespace ?? this.defaultNsName}.${source.callee}#${this.libIdOf(source.namespace ?? this.defaultNsName)}`,
|
|
583
|
-
];
|
|
584
|
-
parts.push(JSON.stringify({
|
|
585
|
-
positional: withoutKeepDirectivesFromPositional(source.positional ?? []),
|
|
586
|
-
args: withoutKeepDirectives(source.args),
|
|
587
|
-
}));
|
|
588
|
-
for (const dep of meta.deps) {
|
|
589
|
-
const ck = this.cache.get(dep)?.outputContentKey;
|
|
590
|
-
parts.push(ck ?? 'missing');
|
|
591
|
-
}
|
|
592
|
-
return parts.join('|');
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* 按函数名查 bodyHash(setCompiled 已存 script;查不到 → 'missing',增量会失效重算)。
|
|
596
|
-
* @internal runtime.planUpdateStale 的 ownKey/oldKey 对比(§6.2 / P4)复用。
|
|
597
|
-
* @param name 本机函数名。
|
|
598
|
-
* @returns 函数体的内容哈希;`'missing'` 表示未知函数。
|
|
599
|
-
*/
|
|
600
|
-
bodyHashOf(name) {
|
|
601
|
-
return this.script.functions?.find((f) => f.name === name)?.bodyHash ?? 'missing';
|
|
602
|
-
}
|
|
603
|
-
/**
|
|
604
|
-
* 按绑定名查 libId(setNamespaces 已存表;本机函数不含——只适用于库分支 key)。
|
|
605
|
-
* 库未登记或表缺失 → 'missing',增量会自动失效重算。
|
|
606
|
-
* @param binding 命名空间绑定名。
|
|
607
|
-
* @returns 库的内容身份;`'missing'` 表示该绑定无登记身份。
|
|
608
|
-
*/
|
|
609
|
-
libIdOf(binding) {
|
|
610
|
-
return this.libIds.get(binding) ?? 'missing';
|
|
611
|
-
}
|
|
612
|
-
/** outputContentKey:shape 语句 = mesh 内容哈希;参数语句 = 参数值。 */
|
|
613
|
-
computeOutputContentKey(compiled) {
|
|
614
|
-
const primary = this.metaById.get(compiled.id)?.writes[0];
|
|
615
|
-
if (primary !== undefined) {
|
|
616
|
-
const v = this.ctx[primary];
|
|
617
|
-
if (v && typeof v === 'object' && 'positions' in v && 'indices' in v) {
|
|
618
|
-
const shape = v;
|
|
619
|
-
return computeContentKey(shape.positions, shape.indices);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
const source = this.sourceById.get(compiled.id);
|
|
623
|
-
if (!source) {
|
|
624
|
-
const p = this.script.params.find((pp) => pp.name === primary);
|
|
625
|
-
return `param:${JSON.stringify(p?.value)}`;
|
|
626
|
-
}
|
|
627
|
-
return '';
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
//# sourceMappingURL=module-executor.js.map
|