@multiplekex/shallot 0.1.0 → 0.1.1
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/package.json +8 -23
- package/src/standard/compute/index.ts +36 -0
- package/src/standard/render/camera.ts +1 -1
- package/dist/core/builder.d.ts +0 -25
- package/dist/core/builder.d.ts.map +0 -1
- package/dist/core/builder.js +0 -88
- package/dist/core/builder.js.map +0 -1
- package/dist/core/component.d.ts +0 -29
- package/dist/core/component.d.ts.map +0 -1
- package/dist/core/component.js +0 -36
- package/dist/core/component.js.map +0 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/math.d.ts +0 -32
- package/dist/core/math.d.ts.map +0 -1
- package/dist/core/math.js +0 -39
- package/dist/core/math.js.map +0 -1
- package/dist/core/relation.d.ts +0 -16
- package/dist/core/relation.d.ts.map +0 -1
- package/dist/core/relation.js +0 -32
- package/dist/core/relation.js.map +0 -1
- package/dist/core/resource.d.ts +0 -9
- package/dist/core/resource.d.ts.map +0 -1
- package/dist/core/resource.js +0 -12
- package/dist/core/resource.js.map +0 -1
- package/dist/core/runtime.d.ts +0 -13
- package/dist/core/runtime.d.ts.map +0 -1
- package/dist/core/runtime.js +0 -118
- package/dist/core/runtime.js.map +0 -1
- package/dist/core/scheduler.d.ts +0 -47
- package/dist/core/scheduler.d.ts.map +0 -1
- package/dist/core/scheduler.js +0 -138
- package/dist/core/scheduler.js.map +0 -1
- package/dist/core/state.d.ts +0 -62
- package/dist/core/state.d.ts.map +0 -1
- package/dist/core/state.js +0 -185
- package/dist/core/state.js.map +0 -1
- package/dist/core/strings.d.ts +0 -3
- package/dist/core/strings.d.ts.map +0 -1
- package/dist/core/strings.js +0 -11
- package/dist/core/strings.js.map +0 -1
- package/dist/core/types.d.ts +0 -33
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/xml.d.ts +0 -42
- package/dist/core/xml.d.ts.map +0 -1
- package/dist/core/xml.js +0 -349
- package/dist/core/xml.js.map +0 -1
- package/dist/extras/arrows/index.d.ts +0 -33
- package/dist/extras/arrows/index.d.ts.map +0 -1
- package/dist/extras/arrows/index.js +0 -288
- package/dist/extras/arrows/index.js.map +0 -1
- package/dist/extras/index.d.ts +0 -5
- package/dist/extras/index.d.ts.map +0 -1
- package/dist/extras/index.js +0 -31
- package/dist/extras/index.js.map +0 -1
- package/dist/extras/lines/index.d.ts +0 -36
- package/dist/extras/lines/index.d.ts.map +0 -1
- package/dist/extras/lines/index.js +0 -288
- package/dist/extras/lines/index.js.map +0 -1
- package/dist/extras/orbit/index.d.ts +0 -20
- package/dist/extras/orbit/index.d.ts.map +0 -1
- package/dist/extras/orbit/index.js +0 -93
- package/dist/extras/orbit/index.js.map +0 -1
- package/dist/extras/text/index.d.ts +0 -64
- package/dist/extras/text/index.d.ts.map +0 -1
- package/dist/extras/text/index.js +0 -423
- package/dist/extras/text/index.js.map +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -187
- package/dist/index.js.map +0 -1
- package/dist/rust/transforms/pkg/shallot_transforms.js +0 -107
- package/dist/rust/transforms/pkg/shallot_transforms.js.map +0 -1
- package/dist/standard/compute/graph.d.ts +0 -37
- package/dist/standard/compute/graph.d.ts.map +0 -1
- package/dist/standard/compute/graph.js +0 -85
- package/dist/standard/compute/graph.js.map +0 -1
- package/dist/standard/compute/index.d.ts +0 -21
- package/dist/standard/compute/index.d.ts.map +0 -1
- package/dist/standard/compute/index.js +0 -81
- package/dist/standard/compute/index.js.map +0 -1
- package/dist/standard/defaults.d.ts +0 -3
- package/dist/standard/defaults.d.ts.map +0 -1
- package/dist/standard/defaults.js +0 -18
- package/dist/standard/defaults.js.map +0 -1
- package/dist/standard/index.d.ts +0 -8
- package/dist/standard/index.d.ts.map +0 -1
- package/dist/standard/input/index.d.ts +0 -5
- package/dist/standard/input/index.d.ts.map +0 -1
- package/dist/standard/input/index.js +0 -70
- package/dist/standard/input/index.js.map +0 -1
- package/dist/standard/loading/index.d.ts +0 -7
- package/dist/standard/loading/index.d.ts.map +0 -1
- package/dist/standard/loading/index.js +0 -91
- package/dist/standard/loading/index.js.map +0 -1
- package/dist/standard/render/camera.d.ts +0 -36
- package/dist/standard/render/camera.d.ts.map +0 -1
- package/dist/standard/render/camera.js +0 -71
- package/dist/standard/render/camera.js.map +0 -1
- package/dist/standard/render/forward.d.ts +0 -30
- package/dist/standard/render/forward.d.ts.map +0 -1
- package/dist/standard/render/forward.js +0 -158
- package/dist/standard/render/forward.js.map +0 -1
- package/dist/standard/render/index.d.ts +0 -22
- package/dist/standard/render/index.d.ts.map +0 -1
- package/dist/standard/render/index.js +0 -153
- package/dist/standard/render/index.js.map +0 -1
- package/dist/standard/render/light.d.ts +0 -25
- package/dist/standard/render/light.d.ts.map +0 -1
- package/dist/standard/render/light.js +0 -48
- package/dist/standard/render/light.js.map +0 -1
- package/dist/standard/render/mesh/box.d.ts +0 -3
- package/dist/standard/render/mesh/box.d.ts.map +0 -1
- package/dist/standard/render/mesh/box.js +0 -190
- package/dist/standard/render/mesh/box.js.map +0 -1
- package/dist/standard/render/mesh/index.d.ts +0 -52
- package/dist/standard/render/mesh/index.d.ts.map +0 -1
- package/dist/standard/render/mesh/index.js +0 -158
- package/dist/standard/render/mesh/index.js.map +0 -1
- package/dist/standard/render/mesh/plane.d.ts +0 -3
- package/dist/standard/render/mesh/plane.d.ts.map +0 -1
- package/dist/standard/render/mesh/plane.js +0 -33
- package/dist/standard/render/mesh/plane.js.map +0 -1
- package/dist/standard/render/mesh/sphere.d.ts +0 -3
- package/dist/standard/render/mesh/sphere.d.ts.map +0 -1
- package/dist/standard/render/mesh/sphere.js +0 -25
- package/dist/standard/render/mesh/sphere.js.map +0 -1
- package/dist/standard/render/postprocess.d.ts +0 -11
- package/dist/standard/render/postprocess.d.ts.map +0 -1
- package/dist/standard/render/postprocess.js +0 -190
- package/dist/standard/render/postprocess.js.map +0 -1
- package/dist/standard/render/scene.d.ts +0 -8
- package/dist/standard/render/scene.d.ts.map +0 -1
- package/dist/standard/render/scene.js +0 -67
- package/dist/standard/render/scene.js.map +0 -1
- package/dist/standard/transforms/index.d.ts +0 -27
- package/dist/standard/transforms/index.d.ts.map +0 -1
- package/dist/standard/transforms/index.js +0 -122
- package/dist/standard/transforms/index.js.map +0 -1
- package/dist/standard/transforms/wasm.d.ts +0 -17
- package/dist/standard/transforms/wasm.d.ts.map +0 -1
- package/dist/standard/transforms/wasm.js +0 -31
- package/dist/standard/transforms/wasm.js.map +0 -1
- package/dist/standard/tween/easing.d.ts +0 -5
- package/dist/standard/tween/easing.d.ts.map +0 -1
- package/dist/standard/tween/easing.js +0 -80
- package/dist/standard/tween/easing.js.map +0 -1
- package/dist/standard/tween/index.d.ts +0 -4
- package/dist/standard/tween/index.d.ts.map +0 -1
- package/dist/standard/tween/sequence.d.ts +0 -20
- package/dist/standard/tween/sequence.d.ts.map +0 -1
- package/dist/standard/tween/sequence.js +0 -95
- package/dist/standard/tween/sequence.js.map +0 -1
- package/dist/standard/tween/tween.d.ts +0 -28
- package/dist/standard/tween/tween.d.ts.map +0 -1
- package/dist/standard/tween/tween.js +0 -136
- package/dist/standard/tween/tween.js.map +0 -1
- package/src/vite-env.d.ts +0 -6
package/dist/core/types.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { System } from './scheduler';
|
|
2
|
-
import { ComponentData } from './component';
|
|
3
|
-
import { RelationDef } from './relation';
|
|
4
|
-
import { State } from './state';
|
|
5
|
-
export interface Plugin {
|
|
6
|
-
readonly systems?: readonly System[];
|
|
7
|
-
readonly components?: Record<string, ComponentData>;
|
|
8
|
-
readonly relations?: readonly RelationDef[];
|
|
9
|
-
readonly dependencies?: readonly Plugin[];
|
|
10
|
-
readonly initialize?: (state: State) => void | Promise<void>;
|
|
11
|
-
}
|
|
12
|
-
export interface Loading {
|
|
13
|
-
show(): (() => void) | void;
|
|
14
|
-
update(progress: number): void;
|
|
15
|
-
}
|
|
16
|
-
export interface MouseState {
|
|
17
|
-
deltaX: number;
|
|
18
|
-
deltaY: number;
|
|
19
|
-
scrollDelta: number;
|
|
20
|
-
left: boolean;
|
|
21
|
-
right: boolean;
|
|
22
|
-
middle: boolean;
|
|
23
|
-
}
|
|
24
|
-
export interface InputState {
|
|
25
|
-
readonly mouse: Readonly<MouseState>;
|
|
26
|
-
isKeyDown(code: string): boolean;
|
|
27
|
-
isKeyPressed(code: string): boolean;
|
|
28
|
-
isKeyReleased(code: string): boolean;
|
|
29
|
-
}
|
|
30
|
-
export interface RenderContext {
|
|
31
|
-
readonly gpu: unknown;
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,WAAW,MAAM;IACnB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,OAAO;IACpB,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACrC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACzB"}
|
package/dist/core/xml.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { State } from './state';
|
|
2
|
-
import { ParseContext, RegisteredComponent } from './component';
|
|
3
|
-
export interface ParsedElement {
|
|
4
|
-
readonly tag: string;
|
|
5
|
-
readonly attrs: Readonly<Record<string, string>>;
|
|
6
|
-
readonly children: readonly ParsedElement[];
|
|
7
|
-
}
|
|
8
|
-
export interface EntityRef {
|
|
9
|
-
readonly attrName: string;
|
|
10
|
-
readonly targetName: string;
|
|
11
|
-
}
|
|
12
|
-
export interface EntityDef {
|
|
13
|
-
readonly id?: string;
|
|
14
|
-
readonly components: readonly ComponentDef[];
|
|
15
|
-
readonly children: readonly EntityDef[];
|
|
16
|
-
readonly entityRefs: readonly EntityRef[];
|
|
17
|
-
}
|
|
18
|
-
export interface ComponentDef {
|
|
19
|
-
readonly def: RegisteredComponent;
|
|
20
|
-
readonly attrs: Record<string, string>;
|
|
21
|
-
}
|
|
22
|
-
export interface ParseResult {
|
|
23
|
-
readonly entities: readonly EntityDef[];
|
|
24
|
-
readonly errors: readonly ParseError[];
|
|
25
|
-
readonly warnings: readonly string[];
|
|
26
|
-
}
|
|
27
|
-
export interface ParseError {
|
|
28
|
-
readonly message: string;
|
|
29
|
-
readonly path?: string;
|
|
30
|
-
}
|
|
31
|
-
export declare function parseXml(xml: string): ParseResult;
|
|
32
|
-
export interface LoadResult {
|
|
33
|
-
readonly entities: Map<string, number>;
|
|
34
|
-
readonly roots: readonly number[];
|
|
35
|
-
readonly errors: readonly ParseError[];
|
|
36
|
-
}
|
|
37
|
-
export type PostLoadHook = (state: State, context: ParseContext) => void;
|
|
38
|
-
export declare function registerPostLoadHook(hook: PostLoadHook): void;
|
|
39
|
-
export declare function unregisterPostLoadHook(hook: PostLoadHook): void;
|
|
40
|
-
export declare function loadScene(state: State, xml: string): LoadResult;
|
|
41
|
-
export declare function loadSceneFile(state: State, path: string, readFile: (path: string) => Promise<string>): Promise<LoadResult>;
|
|
42
|
-
//# sourceMappingURL=xml.d.ts.map
|
package/dist/core/xml.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/core/xml.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAEH,KAAK,YAAY,EAEjB,KAAK,mBAAmB,EAC3B,MAAM,aAAa,CAAC;AA4DrB,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,GAAG,EAAE,mBAAmB,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAyCjD;AAiID,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;AAIzE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAE7D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAG/D;AA2BD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAG/D;AAED,wBAAsB,aAAa,CAC/B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAC5C,OAAO,CAAC,UAAU,CAAC,CAGrB"}
|
package/dist/core/xml.js
DELETED
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
import { XMLParser as N } from "fast-xml-parser";
|
|
2
|
-
import { addComponent as A, Pair as I } from "bitecs";
|
|
3
|
-
import { getRegisteredComponent as V } from "./component.js";
|
|
4
|
-
import { ChildOf as X, getRelationDef as k } from "./relation.js";
|
|
5
|
-
import { toCamelCase as E, toKebabCase as $ } from "./strings.js";
|
|
6
|
-
function L(t, n) {
|
|
7
|
-
if (t.length === 0) return n.length;
|
|
8
|
-
if (n.length === 0) return t.length;
|
|
9
|
-
const s = [];
|
|
10
|
-
for (let e = 0; e <= n.length; e++)
|
|
11
|
-
s[e] = [e];
|
|
12
|
-
for (let e = 0; e <= t.length; e++)
|
|
13
|
-
s[0][e] = e;
|
|
14
|
-
for (let e = 1; e <= n.length; e++)
|
|
15
|
-
for (let r = 1; r <= t.length; r++) {
|
|
16
|
-
const c = t[r - 1] === n[e - 1] ? 0 : 1;
|
|
17
|
-
s[e][r] = Math.min(
|
|
18
|
-
s[e - 1][r] + 1,
|
|
19
|
-
s[e][r - 1] + 1,
|
|
20
|
-
s[e - 1][r - 1] + c
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
return s[n.length][t.length];
|
|
24
|
-
}
|
|
25
|
-
function M(t, n) {
|
|
26
|
-
const s = $(t);
|
|
27
|
-
let e = null, r = 1 / 0;
|
|
28
|
-
for (const c of n) {
|
|
29
|
-
const i = $(c);
|
|
30
|
-
if (s === i || s.endsWith(i) || s.endsWith("-" + i))
|
|
31
|
-
return c;
|
|
32
|
-
const l = L(s, i), a = Math.max(s.length, i.length), u = Math.ceil(a * 0.5);
|
|
33
|
-
l < r && l <= u && (r = l, e = c);
|
|
34
|
-
}
|
|
35
|
-
return e;
|
|
36
|
-
}
|
|
37
|
-
function W(t) {
|
|
38
|
-
const n = [], s = [], e = new N({
|
|
39
|
-
ignoreAttributes: !1,
|
|
40
|
-
attributeNamePrefix: "",
|
|
41
|
-
preserveOrder: !0,
|
|
42
|
-
trimValues: !0,
|
|
43
|
-
allowBooleanAttributes: !0
|
|
44
|
-
});
|
|
45
|
-
let r;
|
|
46
|
-
try {
|
|
47
|
-
r = e.parse(t, { allowBooleanAttributes: !0 });
|
|
48
|
-
} catch (l) {
|
|
49
|
-
return {
|
|
50
|
-
entities: [],
|
|
51
|
-
errors: [{ message: `xml parse error: ${l.message}` }],
|
|
52
|
-
warnings: []
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
const c = x(r), i = [];
|
|
56
|
-
for (const l of c)
|
|
57
|
-
if (l.tag === "scene")
|
|
58
|
-
for (const a of l.children) {
|
|
59
|
-
const u = y(a, n, s);
|
|
60
|
-
u && i.push(u);
|
|
61
|
-
}
|
|
62
|
-
else if (l.tag === "a") {
|
|
63
|
-
const a = y(l, n, s);
|
|
64
|
-
a && i.push(a);
|
|
65
|
-
} else (l.tag.toLowerCase() === "scene" || l.tag.toLowerCase() === "world") && n.push({ message: `Invalid tag "${l.tag}". Use lowercase <scene>` });
|
|
66
|
-
return { entities: i, errors: n, warnings: s };
|
|
67
|
-
}
|
|
68
|
-
function R(t) {
|
|
69
|
-
return t.startsWith("@") && t.length > 1;
|
|
70
|
-
}
|
|
71
|
-
function y(t, n, s) {
|
|
72
|
-
if (t.tag !== "a")
|
|
73
|
-
return t.tag.toLowerCase() === "a" && n.push({ message: `Invalid tag "${t.tag}". Use lowercase <a>` }), null;
|
|
74
|
-
const e = [], r = [], c = [], i = [];
|
|
75
|
-
let l;
|
|
76
|
-
for (const [a, u] of Object.entries(t.attrs)) {
|
|
77
|
-
if (a === "id") {
|
|
78
|
-
l = u;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (typeof u == "string" && R(u)) {
|
|
82
|
-
c.push({
|
|
83
|
-
attrName: a,
|
|
84
|
-
targetName: u.slice(1)
|
|
85
|
-
});
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const f = V(a);
|
|
89
|
-
if (f) {
|
|
90
|
-
const h = {};
|
|
91
|
-
typeof u == "string" && u !== "" && (h._value = u), e.push({ def: f, attrs: h });
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
typeof u == "string" && u !== "" && i.push({ name: a, value: u });
|
|
95
|
-
}
|
|
96
|
-
for (const { name: a, value: u } of i) {
|
|
97
|
-
const f = E(a);
|
|
98
|
-
let h = !1;
|
|
99
|
-
for (const o of e) {
|
|
100
|
-
const d = o.def.component;
|
|
101
|
-
(f in d || `${f}X` in d) && (h = !0, o.attrs._value || (o.attrs[a] = u));
|
|
102
|
-
}
|
|
103
|
-
if (!h) {
|
|
104
|
-
const o = l ? ` (${l})` : "";
|
|
105
|
-
s.push(`shorthand "${a}" matches no declared component${o}`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
for (const a of t.children)
|
|
109
|
-
if (a.tag === "a") {
|
|
110
|
-
const u = y(a, n, s);
|
|
111
|
-
u && r.push(u);
|
|
112
|
-
} else a.tag.toLowerCase() === "a" ? n.push({ message: `Invalid tag "${a.tag}". Use lowercase <a>` }) : n.push({ message: `Only <a> children allowed, found <${a.tag}>` });
|
|
113
|
-
return { id: l, components: e, children: r, entityRefs: c };
|
|
114
|
-
}
|
|
115
|
-
function x(t) {
|
|
116
|
-
if (!Array.isArray(t)) return [];
|
|
117
|
-
const n = [];
|
|
118
|
-
for (const s of t)
|
|
119
|
-
if (!(typeof s != "object" || s === null))
|
|
120
|
-
for (const [e, r] of Object.entries(s)) {
|
|
121
|
-
if (e === ":@") continue;
|
|
122
|
-
const c = s[":@"] ?? {}, i = {};
|
|
123
|
-
for (const [a, u] of Object.entries(c))
|
|
124
|
-
typeof u == "string" ? i[a] = u : (u === !0 || u === "") && (i[a] = "");
|
|
125
|
-
const l = x(r);
|
|
126
|
-
n.push({
|
|
127
|
-
tag: e,
|
|
128
|
-
attrs: i,
|
|
129
|
-
children: l
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
return n;
|
|
133
|
-
}
|
|
134
|
-
const p = [];
|
|
135
|
-
function J(t) {
|
|
136
|
-
p.push(t);
|
|
137
|
-
}
|
|
138
|
-
function Q(t) {
|
|
139
|
-
const n = p.indexOf(t);
|
|
140
|
-
n !== -1 && p.splice(n, 1);
|
|
141
|
-
}
|
|
142
|
-
class S {
|
|
143
|
-
nameToEntity = /* @__PURE__ */ new Map();
|
|
144
|
-
_currentEid = 0;
|
|
145
|
-
get currentEid() {
|
|
146
|
-
return this._currentEid;
|
|
147
|
-
}
|
|
148
|
-
setCurrentEid(n) {
|
|
149
|
-
this._currentEid = n;
|
|
150
|
-
}
|
|
151
|
-
getEntityByName(n) {
|
|
152
|
-
return this.nameToEntity.get(n) ?? null;
|
|
153
|
-
}
|
|
154
|
-
setName(n, s) {
|
|
155
|
-
this.nameToEntity.set(n, s);
|
|
156
|
-
}
|
|
157
|
-
getEntityMap() {
|
|
158
|
-
return new Map(this.nameToEntity);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
function _(t, n) {
|
|
162
|
-
const s = W(n);
|
|
163
|
-
return P(t, s.entities, s.errors);
|
|
164
|
-
}
|
|
165
|
-
async function tt(t, n, s) {
|
|
166
|
-
const e = await s(n);
|
|
167
|
-
return _(t, e);
|
|
168
|
-
}
|
|
169
|
-
function P(t, n, s) {
|
|
170
|
-
const e = new S(), r = [...s], c = [], i = [];
|
|
171
|
-
for (const l of n) {
|
|
172
|
-
const a = b(t, l, e, void 0, c);
|
|
173
|
-
i.push(a);
|
|
174
|
-
}
|
|
175
|
-
for (const { def: l, eid: a, parent: u } of c) {
|
|
176
|
-
u !== void 0 && A(t.world, a, I(X.relation, u));
|
|
177
|
-
for (const f of l.entityRefs)
|
|
178
|
-
Y(t, a, f, e, r);
|
|
179
|
-
for (const f of l.components)
|
|
180
|
-
B(t, a, f, e, r);
|
|
181
|
-
}
|
|
182
|
-
for (const l of p)
|
|
183
|
-
l(t, e);
|
|
184
|
-
return {
|
|
185
|
-
entities: e.getEntityMap(),
|
|
186
|
-
roots: i,
|
|
187
|
-
errors: r
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
function b(t, n, s, e, r) {
|
|
191
|
-
const c = t.addEntity();
|
|
192
|
-
n.id && s.setName(n.id, c), r.push({ def: n, eid: c, parent: e });
|
|
193
|
-
for (const i of n.children)
|
|
194
|
-
b(t, i, s, c, r);
|
|
195
|
-
return c;
|
|
196
|
-
}
|
|
197
|
-
function Y(t, n, s, e, r) {
|
|
198
|
-
const c = k(s.attrName);
|
|
199
|
-
if (!c) {
|
|
200
|
-
r.push({ message: `Unknown relation: "${s.attrName}"` });
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const i = e.getEntityByName(s.targetName);
|
|
204
|
-
if (i === null) {
|
|
205
|
-
r.push({ message: `Unknown entity: "@${s.targetName}"` });
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
t.addRelation(n, c, i);
|
|
209
|
-
}
|
|
210
|
-
function B(t, n, s, e, r) {
|
|
211
|
-
const { def: c, attrs: i } = s, { component: l, name: a, traits: u } = c;
|
|
212
|
-
t.addComponent(n, l);
|
|
213
|
-
const f = u?.defaults?.() ?? {};
|
|
214
|
-
for (const [o, d] of Object.entries(f))
|
|
215
|
-
w(l, o, n, d);
|
|
216
|
-
let h;
|
|
217
|
-
if (e.setCurrentEid(n), u?.adapter)
|
|
218
|
-
h = u.adapter(i, t, e);
|
|
219
|
-
else {
|
|
220
|
-
const o = D(c, i);
|
|
221
|
-
h = o.values;
|
|
222
|
-
for (const d of o.errors)
|
|
223
|
-
r.push({ message: `<${a}> ${d}` });
|
|
224
|
-
}
|
|
225
|
-
for (const [o, d] of Object.entries(h))
|
|
226
|
-
w(l, o, n, d);
|
|
227
|
-
}
|
|
228
|
-
function D(t, n) {
|
|
229
|
-
const s = {}, e = [];
|
|
230
|
-
if (n._value && v(n._value)) {
|
|
231
|
-
const r = m(t.name, n._value, t.component);
|
|
232
|
-
Object.assign(s, r.values), e.push(...r.errors);
|
|
233
|
-
}
|
|
234
|
-
for (const [r, c] of Object.entries(n))
|
|
235
|
-
if (r !== "_value" && c)
|
|
236
|
-
if (v(c)) {
|
|
237
|
-
const i = m(t.name, c, t.component);
|
|
238
|
-
Object.assign(s, i.values), e.push(...i.errors);
|
|
239
|
-
} else {
|
|
240
|
-
const i = m(
|
|
241
|
-
t.name,
|
|
242
|
-
`${r}: ${c}`,
|
|
243
|
-
t.component
|
|
244
|
-
);
|
|
245
|
-
Object.assign(s, i.values), e.push(...i.errors);
|
|
246
|
-
}
|
|
247
|
-
return { values: s, errors: e };
|
|
248
|
-
}
|
|
249
|
-
function w(t, n, s, e) {
|
|
250
|
-
const r = t[n];
|
|
251
|
-
r != null && (ArrayBuffer.isView(r) || Array.isArray(r)) && (r[s] = e);
|
|
252
|
-
}
|
|
253
|
-
function C(t, n) {
|
|
254
|
-
return `${n}X` in t && `${n}Y` in t;
|
|
255
|
-
}
|
|
256
|
-
function O(t, n) {
|
|
257
|
-
return C(t, n) && `${n}Z` in t;
|
|
258
|
-
}
|
|
259
|
-
function F(t, n) {
|
|
260
|
-
return O(t, n) && `${n}W` in t;
|
|
261
|
-
}
|
|
262
|
-
function T(t) {
|
|
263
|
-
if (t = t.trim(), t.startsWith("0x") || t.startsWith("0X"))
|
|
264
|
-
return parseInt(t, 16);
|
|
265
|
-
if (t.startsWith("#"))
|
|
266
|
-
return parseInt(t.slice(1), 16);
|
|
267
|
-
if (t === "true") return 1;
|
|
268
|
-
if (t === "false") return 0;
|
|
269
|
-
const n = parseFloat(t);
|
|
270
|
-
return isNaN(n) ? null : n;
|
|
271
|
-
}
|
|
272
|
-
function U(t) {
|
|
273
|
-
const n = [], s = t.trim();
|
|
274
|
-
let e = 0;
|
|
275
|
-
for (let r = 0; r <= s.length; r++) {
|
|
276
|
-
const c = r < s.length && /\s/.test(s[r]), i = r === s.length;
|
|
277
|
-
(c || i) && (e < r && n.push(T(s.slice(e, r))), e = r + 1);
|
|
278
|
-
}
|
|
279
|
-
return n;
|
|
280
|
-
}
|
|
281
|
-
function Z(t) {
|
|
282
|
-
const n = [];
|
|
283
|
-
let s = 0;
|
|
284
|
-
for (let e = 0; e <= t.length; e++)
|
|
285
|
-
if (e === t.length || t[e] === ";") {
|
|
286
|
-
const r = t.slice(s, e).trim();
|
|
287
|
-
r && n.push(r), s = e + 1;
|
|
288
|
-
}
|
|
289
|
-
return n;
|
|
290
|
-
}
|
|
291
|
-
function m(t, n, s) {
|
|
292
|
-
const e = {}, r = [], c = Z(n);
|
|
293
|
-
for (const i of c) {
|
|
294
|
-
const l = i.indexOf(":");
|
|
295
|
-
if (l === -1) {
|
|
296
|
-
r.push(`Invalid syntax: "${i}" (expected "field: value")`);
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
const a = i.slice(0, l).trim(), u = i.slice(l + 1).trim();
|
|
300
|
-
if (!a || !u) {
|
|
301
|
-
r.push(`Invalid syntax: "${i}" (empty field or value)`);
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
const f = E(a), h = U(u);
|
|
305
|
-
if (h.some((j) => j === null)) {
|
|
306
|
-
r.push(`Invalid number in "${i}"`);
|
|
307
|
-
continue;
|
|
308
|
-
}
|
|
309
|
-
const o = h;
|
|
310
|
-
if (F(s, f)) {
|
|
311
|
-
o.length === 4 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[1], e[`${f}Z`] = o[2], e[`${f}W`] = o[3]) : o.length === 1 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[0], e[`${f}Z`] = o[0], e[`${f}W`] = o[0]) : r.push(
|
|
312
|
-
`${t}.${a}: expected 1 or 4 values, got ${o.length}`
|
|
313
|
-
);
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
if (O(s, f)) {
|
|
317
|
-
o.length === 3 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[1], e[`${f}Z`] = o[2]) : o.length === 1 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[0], e[`${f}Z`] = o[0]) : r.push(
|
|
318
|
-
`${t}.${a}: expected 1 or 3 values, got ${o.length}`
|
|
319
|
-
);
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
if (C(s, f)) {
|
|
323
|
-
o.length === 2 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[1]) : o.length === 1 ? (e[`${f}X`] = o[0], e[`${f}Y`] = o[0]) : r.push(
|
|
324
|
-
`${t}.${a}: expected 1 or 2 values, got ${o.length}`
|
|
325
|
-
);
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
if (f in s) {
|
|
329
|
-
o.length === 1 ? e[f] = o[0] : r.push(`${t}.${a}: expected 1 value, got ${o.length}`);
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
const d = Object.keys(s), g = M(a, d);
|
|
333
|
-
g ? r.push(
|
|
334
|
-
`${t}: unknown field "${a}", did you mean "${$(g)}"?`
|
|
335
|
-
) : r.push(`${t}: unknown field "${a}"`);
|
|
336
|
-
}
|
|
337
|
-
return { values: e, errors: r };
|
|
338
|
-
}
|
|
339
|
-
function v(t) {
|
|
340
|
-
return t.includes(":") && (t.includes(";") || /^[\w-]+\s*:/.test(t));
|
|
341
|
-
}
|
|
342
|
-
export {
|
|
343
|
-
_ as loadScene,
|
|
344
|
-
tt as loadSceneFile,
|
|
345
|
-
W as parseXml,
|
|
346
|
-
J as registerPostLoadHook,
|
|
347
|
-
Q as unregisterPostLoadHook
|
|
348
|
-
};
|
|
349
|
-
//# sourceMappingURL=xml.js.map
|
package/dist/core/xml.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xml.js","sources":["../../src/core/xml.ts"],"sourcesContent":["import { XMLParser } from \"fast-xml-parser\";\nimport { addComponent, Pair } from \"bitecs\";\nimport type { State } from \"./state\";\nimport {\n getRegisteredComponent,\n type ParseContext,\n type ComponentData,\n type RegisteredComponent,\n} from \"./component\";\nimport { getRelationDef, ChildOf } from \"./relation\";\nimport { toKebabCase, toCamelCase } from \"./strings\";\n\nfunction levenshtein(a: string, b: string): number {\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n const matrix: number[][] = [];\n for (let i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= a.length; j++) {\n matrix[0][j] = j;\n }\n\n for (let i = 1; i <= b.length; i++) {\n for (let j = 1; j <= a.length; j++) {\n const cost = a[j - 1] === b[i - 1] ? 0 : 1;\n matrix[i][j] = Math.min(\n matrix[i - 1][j] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j - 1] + cost\n );\n }\n }\n\n return matrix[b.length][a.length];\n}\n\nfunction findClosestMatch(input: string, candidates: string[]): string | null {\n const inputKebab = toKebabCase(input);\n\n let bestMatch: string | null = null;\n let bestScore = Infinity;\n\n for (const candidate of candidates) {\n const candidateKebab = toKebabCase(candidate);\n\n if (inputKebab === candidateKebab) {\n return candidate;\n }\n\n if (inputKebab.endsWith(candidateKebab) || inputKebab.endsWith(\"-\" + candidateKebab)) {\n return candidate;\n }\n\n const distance = levenshtein(inputKebab, candidateKebab);\n const maxLen = Math.max(inputKebab.length, candidateKebab.length);\n const threshold = Math.ceil(maxLen * 0.5);\n\n if (distance < bestScore && distance <= threshold) {\n bestScore = distance;\n bestMatch = candidate;\n }\n }\n\n return bestMatch;\n}\n\nexport interface ParsedElement {\n readonly tag: string;\n readonly attrs: Readonly<Record<string, string>>;\n readonly children: readonly ParsedElement[];\n}\n\nexport interface EntityRef {\n readonly attrName: string;\n readonly targetName: string;\n}\n\nexport interface EntityDef {\n readonly id?: string;\n readonly components: readonly ComponentDef[];\n readonly children: readonly EntityDef[];\n readonly entityRefs: readonly EntityRef[];\n}\n\nexport interface ComponentDef {\n readonly def: RegisteredComponent;\n readonly attrs: Record<string, string>;\n}\n\nexport interface ParseResult {\n readonly entities: readonly EntityDef[];\n readonly errors: readonly ParseError[];\n readonly warnings: readonly string[];\n}\n\nexport interface ParseError {\n readonly message: string;\n readonly path?: string;\n}\n\nexport function parseXml(xml: string): ParseResult {\n const errors: ParseError[] = [];\n const warnings: string[] = [];\n\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"\",\n preserveOrder: true,\n trimValues: true,\n allowBooleanAttributes: true,\n });\n\n let raw: unknown;\n try {\n raw = parser.parse(xml, { allowBooleanAttributes: true });\n } catch (e) {\n return {\n entities: [],\n errors: [{ message: `xml parse error: ${(e as Error).message}` }],\n warnings: [],\n };\n }\n\n const elements = normalizeRaw(raw);\n const entities: EntityDef[] = [];\n\n for (const el of elements) {\n if (el.tag === \"scene\") {\n for (const child of el.children) {\n const result = parseEntityElement(child, errors, warnings);\n if (result) entities.push(result);\n }\n } else if (el.tag === \"a\") {\n const result = parseEntityElement(el, errors, warnings);\n if (result) entities.push(result);\n } else if (el.tag.toLowerCase() === \"scene\" || el.tag.toLowerCase() === \"world\") {\n errors.push({ message: `Invalid tag \"${el.tag}\". Use lowercase <scene>` });\n }\n }\n\n return { entities, errors, warnings };\n}\n\nfunction isEntityRef(value: string): boolean {\n return value.startsWith(\"@\") && value.length > 1;\n}\n\nfunction parseEntityElement(\n el: ParsedElement,\n errors: ParseError[],\n warnings: string[]\n): EntityDef | null {\n if (el.tag !== \"a\") {\n if (el.tag.toLowerCase() === \"a\") {\n errors.push({ message: `Invalid tag \"${el.tag}\". Use lowercase <a>` });\n }\n return null;\n }\n\n const components: ComponentDef[] = [];\n const children: EntityDef[] = [];\n const entityRefs: EntityRef[] = [];\n const shorthands: Array<{ name: string; value: string }> = [];\n let entityId: string | undefined;\n\n for (const [attrName, attrValue] of Object.entries(el.attrs)) {\n if (attrName === \"id\") {\n entityId = attrValue;\n continue;\n }\n\n if (typeof attrValue === \"string\" && isEntityRef(attrValue)) {\n entityRefs.push({\n attrName,\n targetName: attrValue.slice(1),\n });\n continue;\n }\n\n const registered = getRegisteredComponent(attrName);\n if (registered) {\n const attrs: Record<string, string> = {};\n if (typeof attrValue === \"string\" && attrValue !== \"\") {\n attrs[\"_value\"] = attrValue;\n }\n components.push({ def: registered, attrs });\n continue;\n }\n\n if (typeof attrValue === \"string\" && attrValue !== \"\") {\n shorthands.push({ name: attrName, value: attrValue });\n }\n }\n\n for (const { name, value } of shorthands) {\n const camel = toCamelCase(name);\n let matched = false;\n\n for (const comp of components) {\n const component = comp.def.component;\n const hasField = camel in component || `${camel}X` in component;\n\n if (hasField) {\n matched = true;\n if (!comp.attrs._value) {\n comp.attrs[name] = value;\n }\n }\n }\n\n if (!matched) {\n const id = entityId ? ` (${entityId})` : \"\";\n warnings.push(`shorthand \"${name}\" matches no declared component${id}`);\n }\n }\n\n for (const child of el.children) {\n if (child.tag === \"a\") {\n const childEntity = parseEntityElement(child, errors, warnings);\n if (childEntity) children.push(childEntity);\n } else if (child.tag.toLowerCase() === \"a\") {\n errors.push({ message: `Invalid tag \"${child.tag}\". Use lowercase <a>` });\n } else {\n errors.push({ message: `Only <a> children allowed, found <${child.tag}>` });\n }\n }\n\n return { id: entityId, components, children, entityRefs };\n}\n\ninterface RawElement {\n [key: string]: unknown;\n \":@\"?: Record<string, string>;\n}\n\nfunction normalizeRaw(raw: unknown): ParsedElement[] {\n if (!Array.isArray(raw)) return [];\n\n const result: ParsedElement[] = [];\n\n for (const item of raw as RawElement[]) {\n if (typeof item !== \"object\" || item === null) continue;\n\n for (const [key, value] of Object.entries(item)) {\n if (key === \":@\") continue;\n\n const rawAttrs = item[\":@\"] ?? {};\n const attrs: Record<string, string> = {};\n\n for (const [attrKey, attrVal] of Object.entries(rawAttrs)) {\n if (typeof attrVal === \"string\") {\n attrs[attrKey] = attrVal;\n } else if (attrVal === true || attrVal === \"\") {\n attrs[attrKey] = \"\";\n }\n }\n\n const children = normalizeRaw(value as unknown);\n\n result.push({\n tag: key,\n attrs,\n children,\n });\n }\n }\n\n return result;\n}\n\nexport interface LoadResult {\n readonly entities: Map<string, number>;\n readonly roots: readonly number[];\n readonly errors: readonly ParseError[];\n}\n\nexport type PostLoadHook = (state: State, context: ParseContext) => void;\n\nconst postLoadHooks: PostLoadHook[] = [];\n\nexport function registerPostLoadHook(hook: PostLoadHook): void {\n postLoadHooks.push(hook);\n}\n\nexport function unregisterPostLoadHook(hook: PostLoadHook): void {\n const idx = postLoadHooks.indexOf(hook);\n if (idx !== -1) postLoadHooks.splice(idx, 1);\n}\n\nclass LoadParseContext implements ParseContext {\n private readonly nameToEntity = new Map<string, number>();\n private _currentEid = 0;\n\n get currentEid(): number {\n return this._currentEid;\n }\n\n setCurrentEid(eid: number): void {\n this._currentEid = eid;\n }\n\n getEntityByName(name: string): number | null {\n return this.nameToEntity.get(name) ?? null;\n }\n\n setName(name: string, eid: number): void {\n this.nameToEntity.set(name, eid);\n }\n\n getEntityMap(): Map<string, number> {\n return new Map(this.nameToEntity);\n }\n}\n\nexport function loadScene(state: State, xml: string): LoadResult {\n const parseResult = parseXml(xml);\n return instantiateScene(state, parseResult.entities, parseResult.errors);\n}\n\nexport async function loadSceneFile(\n state: State,\n path: string,\n readFile: (path: string) => Promise<string>\n): Promise<LoadResult> {\n const xml = await readFile(path);\n return loadScene(state, xml);\n}\n\ninterface QueuedEntity {\n readonly def: EntityDef;\n readonly eid: number;\n readonly parent?: number;\n}\n\nfunction instantiateScene(\n state: State,\n entityDefs: readonly EntityDef[],\n parseErrors: readonly ParseError[]\n): LoadResult {\n const context = new LoadParseContext();\n const errors: ParseError[] = [...parseErrors];\n const queue: QueuedEntity[] = [];\n const roots: number[] = [];\n\n for (const entityDef of entityDefs) {\n const eid = createEntityTree(state, entityDef, context, undefined, queue);\n roots.push(eid);\n }\n\n for (const { def, eid, parent } of queue) {\n if (parent !== undefined) {\n addComponent(state.world, eid, Pair(ChildOf.relation, parent));\n }\n\n for (const ref of def.entityRefs) {\n applyRelation(state, eid, ref, context, errors);\n }\n\n for (const compDef of def.components) {\n applyComponent(state, eid, compDef, context, errors);\n }\n }\n\n for (const hook of postLoadHooks) {\n hook(state, context);\n }\n\n return {\n entities: context.getEntityMap(),\n roots,\n errors,\n };\n}\n\nfunction createEntityTree(\n state: State,\n def: EntityDef,\n context: LoadParseContext,\n parent: number | undefined,\n queue: QueuedEntity[]\n): number {\n const eid = state.addEntity();\n\n if (def.id) {\n context.setName(def.id, eid);\n }\n\n queue.push({ def, eid, parent });\n\n for (const childDef of def.children) {\n createEntityTree(state, childDef, context, eid, queue);\n }\n\n return eid;\n}\n\nfunction applyRelation(\n state: State,\n eid: number,\n ref: EntityRef,\n context: LoadParseContext,\n errors: ParseError[]\n): void {\n const relationDef = getRelationDef(ref.attrName);\n if (!relationDef) {\n errors.push({ message: `Unknown relation: \"${ref.attrName}\"` });\n return;\n }\n\n const targetEid = context.getEntityByName(ref.targetName);\n if (targetEid === null) {\n errors.push({ message: `Unknown entity: \"@${ref.targetName}\"` });\n return;\n }\n\n state.addRelation(eid, relationDef, targetEid);\n}\n\nfunction applyComponent(\n state: State,\n eid: number,\n compDef: ComponentDef,\n context: LoadParseContext,\n errors: ParseError[]\n): void {\n const { def, attrs } = compDef;\n const { component, name, traits } = def;\n\n state.addComponent(eid, component as never);\n\n const defaults = traits?.defaults?.() ?? {};\n for (const [field, value] of Object.entries(defaults)) {\n setFieldValue(component, field, eid, value as number);\n }\n\n let values: Record<string, number>;\n\n context.setCurrentEid(eid);\n if (traits?.adapter) {\n values = traits.adapter(attrs, state, context) as Record<string, number>;\n } else {\n const result = parseAttrs(def, attrs);\n values = result.values;\n for (const err of result.errors) {\n errors.push({ message: `<${name}> ${err}` });\n }\n }\n\n for (const [field, value] of Object.entries(values)) {\n setFieldValue(component, field, eid, value);\n }\n}\n\nfunction parseAttrs(\n def: RegisteredComponent,\n attrs: Record<string, string>\n): { values: Record<string, number>; errors: string[] } {\n const allValues: Record<string, number> = {};\n const allErrors: string[] = [];\n\n if (attrs._value) {\n if (isCSSAttrSyntax(attrs._value)) {\n const result = parsePropertyString(def.name, attrs._value, def.component);\n Object.assign(allValues, result.values);\n allErrors.push(...result.errors);\n }\n }\n\n for (const [attrName, attrValue] of Object.entries(attrs)) {\n if (attrName === \"_value\") continue;\n if (!attrValue) continue;\n\n if (isCSSAttrSyntax(attrValue)) {\n const result = parsePropertyString(def.name, attrValue, def.component);\n Object.assign(allValues, result.values);\n allErrors.push(...result.errors);\n } else {\n const result = parsePropertyString(\n def.name,\n `${attrName}: ${attrValue}`,\n def.component\n );\n Object.assign(allValues, result.values);\n allErrors.push(...result.errors);\n }\n }\n\n return { values: allValues, errors: allErrors };\n}\n\nfunction setFieldValue(component: ComponentData, field: string, eid: number, value: number): void {\n const arr = component[field];\n if (arr != null && (ArrayBuffer.isView(arr) || Array.isArray(arr))) {\n arr[eid] = value;\n }\n}\n\ninterface PropertyParseResult {\n readonly values: Record<string, number>;\n readonly errors: readonly string[];\n}\n\nfunction detectVec2(component: ComponentData, base: string): boolean {\n return `${base}X` in component && `${base}Y` in component;\n}\n\nfunction detectVec3(component: ComponentData, base: string): boolean {\n return detectVec2(component, base) && `${base}Z` in component;\n}\n\nfunction detectVec4(component: ComponentData, base: string): boolean {\n return detectVec3(component, base) && `${base}W` in component;\n}\n\nfunction parseNumber(value: string): number | null {\n value = value.trim();\n\n if (value.startsWith(\"0x\") || value.startsWith(\"0X\")) {\n return parseInt(value, 16);\n }\n\n if (value.startsWith(\"#\")) {\n return parseInt(value.slice(1), 16);\n }\n\n if (value === \"true\") return 1;\n if (value === \"false\") return 0;\n\n const num = parseFloat(value);\n return isNaN(num) ? null : num;\n}\n\nfunction parseValues(valueStr: string): (number | null)[] {\n const result: (number | null)[] = [];\n const trimmed = valueStr.trim();\n let start = 0;\n for (let i = 0; i <= trimmed.length; i++) {\n const isWhitespace = i < trimmed.length && /\\s/.test(trimmed[i]);\n const isEnd = i === trimmed.length;\n if (isWhitespace || isEnd) {\n if (start < i) {\n result.push(parseNumber(trimmed.slice(start, i)));\n }\n start = i + 1;\n }\n }\n return result;\n}\n\nfunction splitProperties(str: string): string[] {\n const result: string[] = [];\n let start = 0;\n for (let i = 0; i <= str.length; i++) {\n if (i === str.length || str[i] === \";\") {\n const prop = str.slice(start, i).trim();\n if (prop) result.push(prop);\n start = i + 1;\n }\n }\n return result;\n}\n\nfunction parsePropertyString(\n componentName: string,\n propertyString: string,\n component: ComponentData\n): PropertyParseResult {\n const values: Record<string, number> = {};\n const errors: string[] = [];\n\n const properties = splitProperties(propertyString);\n\n for (const prop of properties) {\n const colonIdx = prop.indexOf(\":\");\n if (colonIdx === -1) {\n errors.push(`Invalid syntax: \"${prop}\" (expected \"field: value\")`);\n continue;\n }\n\n const rawName = prop.slice(0, colonIdx).trim();\n const valueStr = prop.slice(colonIdx + 1).trim();\n\n if (!rawName || !valueStr) {\n errors.push(`Invalid syntax: \"${prop}\" (empty field or value)`);\n continue;\n }\n\n const name = toCamelCase(rawName);\n const parsed = parseValues(valueStr);\n\n if (parsed.some((v) => v === null)) {\n errors.push(`Invalid number in \"${prop}\"`);\n continue;\n }\n\n const nums = parsed as number[];\n\n if (detectVec4(component, name)) {\n if (nums.length === 4) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[1];\n values[`${name}Z`] = nums[2];\n values[`${name}W`] = nums[3];\n } else if (nums.length === 1) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[0];\n values[`${name}Z`] = nums[0];\n values[`${name}W`] = nums[0];\n } else {\n errors.push(\n `${componentName}.${rawName}: expected 1 or 4 values, got ${nums.length}`\n );\n }\n continue;\n }\n\n if (detectVec3(component, name)) {\n if (nums.length === 3) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[1];\n values[`${name}Z`] = nums[2];\n } else if (nums.length === 1) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[0];\n values[`${name}Z`] = nums[0];\n } else {\n errors.push(\n `${componentName}.${rawName}: expected 1 or 3 values, got ${nums.length}`\n );\n }\n continue;\n }\n\n if (detectVec2(component, name)) {\n if (nums.length === 2) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[1];\n } else if (nums.length === 1) {\n values[`${name}X`] = nums[0];\n values[`${name}Y`] = nums[0];\n } else {\n errors.push(\n `${componentName}.${rawName}: expected 1 or 2 values, got ${nums.length}`\n );\n }\n continue;\n }\n\n if (name in component) {\n if (nums.length === 1) {\n values[name] = nums[0];\n } else {\n errors.push(`${componentName}.${rawName}: expected 1 value, got ${nums.length}`);\n }\n continue;\n }\n\n const fieldNames = Object.keys(component);\n const suggestion = findClosestMatch(rawName, fieldNames);\n if (suggestion) {\n errors.push(\n `${componentName}: unknown field \"${rawName}\", did you mean \"${toKebabCase(suggestion)}\"?`\n );\n } else {\n errors.push(`${componentName}: unknown field \"${rawName}\"`);\n }\n }\n\n return { values, errors };\n}\n\nfunction isCSSAttrSyntax(value: string): boolean {\n return value.includes(\":\") && (value.includes(\";\") || /^[\\w-]+\\s*:/.test(value));\n}\n"],"names":["levenshtein","a","b","matrix","i","j","cost","findClosestMatch","input","candidates","inputKebab","toKebabCase","bestMatch","bestScore","candidate","candidateKebab","distance","maxLen","threshold","parseXml","xml","errors","warnings","parser","XMLParser","raw","e","elements","normalizeRaw","entities","el","child","result","parseEntityElement","isEntityRef","value","components","children","entityRefs","shorthands","entityId","attrName","attrValue","registered","getRegisteredComponent","attrs","name","camel","toCamelCase","matched","comp","component","id","childEntity","item","key","rawAttrs","attrKey","attrVal","postLoadHooks","registerPostLoadHook","hook","unregisterPostLoadHook","idx","LoadParseContext","eid","loadScene","state","parseResult","instantiateScene","loadSceneFile","path","readFile","entityDefs","parseErrors","context","queue","roots","entityDef","createEntityTree","def","parent","addComponent","Pair","ChildOf","ref","applyRelation","compDef","applyComponent","childDef","relationDef","getRelationDef","targetEid","traits","defaults","field","setFieldValue","values","parseAttrs","err","allValues","allErrors","isCSSAttrSyntax","parsePropertyString","arr","detectVec2","base","detectVec3","detectVec4","parseNumber","num","parseValues","valueStr","trimmed","start","isWhitespace","isEnd","splitProperties","str","prop","componentName","propertyString","properties","colonIdx","rawName","parsed","v","nums","fieldNames","suggestion"],"mappings":"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"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Plugin } from '../../core';
|
|
2
|
-
import { FieldAccessor } from '../../core/component';
|
|
3
|
-
import { ComputeNode } from '../../standard/compute';
|
|
4
|
-
export declare const ArrowData: {
|
|
5
|
-
data: Float32Array<ArrayBuffer>;
|
|
6
|
-
};
|
|
7
|
-
interface ArrowProxy extends Array<number>, FieldAccessor {
|
|
8
|
-
}
|
|
9
|
-
export declare const Arrow: {
|
|
10
|
-
start: ArrowProxy;
|
|
11
|
-
end: ArrowProxy;
|
|
12
|
-
size: ArrowProxy;
|
|
13
|
-
};
|
|
14
|
-
export interface ArrowsConfig {
|
|
15
|
-
scene: GPUBuffer;
|
|
16
|
-
arrows: GPUBuffer;
|
|
17
|
-
lines: GPUBuffer;
|
|
18
|
-
matrices: GPUBuffer;
|
|
19
|
-
entityIds: GPUBuffer;
|
|
20
|
-
getCount: () => number;
|
|
21
|
-
}
|
|
22
|
-
export declare const arrowShader = "\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec4<f32>,\n}\n\nstruct Scene {\n viewProj: mat4x4<f32>,\n cameraWorld: mat4x4<f32>,\n}\n\nstruct ArrowData {\n start: f32,\n end: f32,\n size: f32,\n _pad: f32,\n}\n\nstruct LineData {\n offset: vec3<f32>,\n thickness: f32,\n visible: f32,\n _pad1: f32,\n _pad2: f32,\n opacity: f32,\n color: vec4<f32>,\n}\n\nconst END_FLAG: u32 = 0x80000000u;\n\n@group(0) @binding(0) var<uniform> scene: Scene;\n@group(0) @binding(1) var<storage, read> entityIds: array<u32>;\n@group(0) @binding(2) var<storage, read> arrows: array<ArrowData>;\n@group(0) @binding(3) var<storage, read> lines: array<LineData>;\n@group(0) @binding(4) var<storage, read> matrices: array<mat4x4<f32>>;\n\n@vertex\nfn vs(@builtin(vertex_index) vid: u32, @builtin(instance_index) iid: u32) -> VertexOutput {\n let packed = entityIds[iid];\n let isEnd = (packed & END_FLAG) != 0u;\n let eid = packed & ~END_FLAG;\n\n let arrow = arrows[eid];\n let line = lines[eid];\n let transform = matrices[eid];\n\n let start = transform[3].xyz;\n let rotation = mat3x3<f32>(transform[0].xyz, transform[1].xyz, transform[2].xyz);\n let end = start + rotation * line.offset;\n\n // Project both points to clip space\n let startClip = scene.viewProj * vec4(start, 1.0);\n let endClip = scene.viewProj * vec4(end, 1.0);\n\n // Convert to NDC\n let startNDC = startClip.xy / startClip.w;\n let endNDC = endClip.xy / endClip.w;\n\n // Direction in screen space\n let dir = endNDC - startNDC;\n let len = length(dir);\n let normDir = select(vec2(1.0, 0.0), dir / len, len > 0.0001);\n\n // Perpendicular in screen space (this naturally faces camera)\n let perp = vec2(-normDir.y, normDir.x);\n\n // Arrow size scales with sqrt of line thickness and world-space distance to camera\n let cameraPos = scene.cameraWorld[3].xyz;\n let midpoint = (start + end) * 0.5;\n let distToCamera = length(cameraPos - midpoint);\n let refDist = 15.0;\n let rawScale = distToCamera / refDist;\n let maxScale = 3.0;\n let zoomScale = max(1.0, rawScale / (1.0 + rawScale / maxScale));\n let baseSize = sqrt(line.thickness) * 0.008 * zoomScale;\n let arrowLength = arrow.size * baseSize * 3.0;\n let arrowWidth = arrow.size * baseSize * 1.5;\n\n // Pick anchor position and direction based on which end\n var anchorNDC: vec2<f32>;\n var anchorDepth: f32;\n var arrowDir: vec2<f32>;\n\n if isEnd {\n anchorNDC = endNDC;\n anchorDepth = endClip.z / endClip.w;\n arrowDir = normDir;\n } else {\n anchorNDC = startNDC;\n anchorDepth = startClip.z / startClip.w;\n arrowDir = -normDir;\n }\n\n // Build triangle centered on anchor (tip extends forward, base extends back)\n let halfLen = arrowLength * 0.5;\n var pos: vec2<f32>;\n switch vid {\n case 0u: { pos = anchorNDC + arrowDir * halfLen; }\n case 1u: { pos = anchorNDC - arrowDir * halfLen + perp * arrowWidth; }\n case 2u: { pos = anchorNDC - arrowDir * halfLen - perp * arrowWidth; }\n default: { pos = anchorNDC; }\n }\n\n var out: VertexOutput;\n out.position = vec4(pos, anchorDepth, 1.0);\n out.color = vec4(line.color.rgb, line.color.a * line.opacity);\n return out;\n}\n\n@fragment\nfn fs(input: VertexOutput) -> @location(0) vec4<f32> {\n return input.color;\n}\n";
|
|
23
|
-
export declare function createArrowsPipeline(device: GPUDevice, format: GPUTextureFormat): GPURenderPipeline;
|
|
24
|
-
export declare function createArrowsNode(config: ArrowsConfig): ComputeNode;
|
|
25
|
-
export interface ArrowsState {
|
|
26
|
-
buffer: GPUBuffer;
|
|
27
|
-
entityIds: GPUBuffer;
|
|
28
|
-
count: number;
|
|
29
|
-
}
|
|
30
|
-
export declare const Arrows: import('../..').ResourceKey<ArrowsState>;
|
|
31
|
-
export declare const ArrowsPlugin: Plugin;
|
|
32
|
-
export {};
|
|
33
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extras/arrows/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,MAAM,EAA2B,MAAM,YAAY,CAAC;AAC1F,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAIH,KAAK,WAAW,EAEnB,MAAM,wBAAwB,CAAC;AAKhC,eAAO,MAAM,SAAS;;CAErB,CAAC;AAEF,UAAU,UAAW,SAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,aAAa;CAAG;AA8B5D,eAAO,MAAM,KAAK,EAAE;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAKpB,CAAC;AAeF,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,MAAM,CAAC;CAC1B;AAID,eAAO,MAAM,WAAW,i7GAiHvB,CAAC;AAEF,wBAAgB,oBAAoB,CAChC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,gBAAgB,GACzB,iBAAiB,CAkCnB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CAkDlE;AAED,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,MAAM,0CAAkC,CAAC;AAiCtD,eAAO,MAAM,YAAY,EAAE,MAoC1B,CAAC"}
|