pixifact 0.3.0 → 0.4.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/README.md +14 -0
- package/dist/compiler/compileScenes.d.ts +1 -0
- package/dist/compiler/compileScenes.js +8 -9
- package/dist/compiler/index.d.ts +0 -4
- package/dist/compiler/index.js +0 -4
- package/dist/compiler/spec.d.ts +1 -1
- package/dist/compiler/typescriptCompiler.js +52 -43
- package/dist/compiler-node/vite.d.ts +2 -1
- package/dist/compiler-node/vite.js +29 -2
- package/dist/platform/wechat/adapter.d.ts +316 -0
- package/dist/platform/wechat/adapter.js +26 -0
- package/dist/platform/wechat/application.d.ts +32 -0
- package/dist/platform/wechat/application.js +79 -0
- package/dist/platform/wechat/fetch.d.ts +1 -0
- package/dist/platform/wechat/fetch.js +145 -0
- package/dist/platform/wechat/index.d.ts +4 -0
- package/dist/platform/wechat/index.js +3 -0
- package/dist/platform/wechat/input.d.ts +12 -0
- package/dist/platform/wechat/input.js +93 -0
- package/dist/platform/wechat/lifecycle.d.ts +14 -0
- package/dist/platform/wechat/lifecycle.js +42 -0
- package/dist/platform/wechat/runtime.d.ts +49 -0
- package/dist/platform/wechat/runtime.js +189 -0
- package/dist/platform/wechat/subpackage.d.ts +1 -0
- package/dist/platform/wechat/subpackage.js +27 -0
- package/dist/platform/wechat/types.d.ts +105 -0
- package/dist/platform/wechat/types.js +3 -0
- package/dist/project/index.d.ts +23 -0
- package/dist/project/index.js +69 -0
- package/dist/{compiler → scene}/decorators.d.ts +1 -1
- package/dist/scene/index.d.ts +5 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/sceneAssetRuntime.d.ts +11 -0
- package/dist/scene/sceneAssetRuntime.js +43 -0
- package/dist/{compiler → scene}/sceneRuntime.d.ts +7 -0
- package/dist/scene/sceneRuntime.js +85 -0
- package/package.json +11 -1
- package/dist/compiler/sceneRuntime.js +0 -22
- /package/dist/{compiler → scene}/decorators.js +0 -0
- /package/dist/{compiler → scene}/eventRuntime.d.ts +0 -0
- /package/dist/{compiler → scene}/eventRuntime.js +0 -0
- /package/dist/{compiler → scene}/slotRuntime.d.ts +0 -0
- /package/dist/{compiler → scene}/slotRuntime.js +0 -0
package/README.md
CHANGED
|
@@ -15,8 +15,12 @@ bun add pixifact pixi.js
|
|
|
15
15
|
```ts
|
|
16
16
|
import { parseSceneTemplate } from 'pixifact/compiler';
|
|
17
17
|
import { Group } from 'pixifact/runtime';
|
|
18
|
+
import { prepareSceneClass, scene } from 'pixifact/scene';
|
|
19
|
+
import { createWechatPixiApplication } from 'pixifact/platform/wechat';
|
|
18
20
|
```
|
|
19
21
|
|
|
22
|
+
`pixifact/compiler` 只包含解析、校验和生成 API。游戏运行时使用 `pixifact/runtime`、`pixifact/scene` 和具体平台入口,不要从 compiler 入口导入 Scene decorator 或运行时加载 API。
|
|
23
|
+
|
|
20
24
|
Compiler Scene 项目通常还会安装 CLI:
|
|
21
25
|
|
|
22
26
|
```bash
|
|
@@ -30,6 +34,16 @@ pixifact scene validate --all
|
|
|
30
34
|
pixifact compile-scenes
|
|
31
35
|
```
|
|
32
36
|
|
|
37
|
+
声明 `targets.wechat` 后,可校验和构建微信小游戏:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pixifact validate --target wechat
|
|
41
|
+
pixifact build --target wechat
|
|
42
|
+
pixifact dev --target wechat
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
完整配置见仓库文档 [微信小游戏构建](https://github.com/hxg2050/pixifact/blob/main/docs/zh/wechat-minigame.md)。
|
|
46
|
+
|
|
33
47
|
## Scene 工作流
|
|
34
48
|
|
|
35
49
|
Pixifact 把项目相对 `.scene` 文件作为 source of truth。外部 Agent 直接编辑 `.scene` 源文件,然后运行校验和编译。
|
|
@@ -3,6 +3,7 @@ export interface CompileScenesOptions {
|
|
|
3
3
|
sourceRoots?: string[];
|
|
4
4
|
generatedDir?: string;
|
|
5
5
|
}
|
|
6
|
+
export declare const generatedSceneAssetsFileName = "scene-assets.generated.json";
|
|
6
7
|
export declare class CompileSceneError extends Error {
|
|
7
8
|
readonly scene: string;
|
|
8
9
|
readonly source?: string | undefined;
|
|
@@ -9,6 +9,7 @@ import { findMissingScenePartReferences } from './scenePartValidation.js';
|
|
|
9
9
|
import { parseSceneTemplate } from './templateParser.js';
|
|
10
10
|
import { compileSceneTemplateToTs } from './typescriptCompiler.js';
|
|
11
11
|
import { parsePixifactProjectConfig, pixifactProjectConfigFileName, } from '../project/index.js';
|
|
12
|
+
export const generatedSceneAssetsFileName = 'scene-assets.generated.json';
|
|
12
13
|
export class CompileSceneError extends Error {
|
|
13
14
|
scene;
|
|
14
15
|
source;
|
|
@@ -65,6 +66,7 @@ export async function compileScenes(options) {
|
|
|
65
66
|
}
|
|
66
67
|
const projectRegistryImports = [];
|
|
67
68
|
const builtinRegistryImports = [];
|
|
69
|
+
const projectAssets = new Set();
|
|
68
70
|
for (const record of sceneRecords) {
|
|
69
71
|
const { scenePath } = record;
|
|
70
72
|
const template = templates.get(scenePath);
|
|
@@ -84,9 +86,12 @@ export async function compileScenes(options) {
|
|
|
84
86
|
},
|
|
85
87
|
sceneImports: sceneImportsFor(template, templates, projectRoot, generatedFileDir),
|
|
86
88
|
sceneClassAliases: sceneClassAliasesFor(template),
|
|
89
|
+
sceneDependencies: [...collectSceneInstancePaths(template.children)].sort(),
|
|
87
90
|
sceneInterfaces: sceneInterfacesFor(template, templates),
|
|
88
|
-
textureImports: textureImportsFor(template, projectRoot, generatedFileDir),
|
|
89
91
|
});
|
|
92
|
+
if (record.kind === 'project') {
|
|
93
|
+
collectTemplateTextures(template, projectAssets);
|
|
94
|
+
}
|
|
90
95
|
await mkdir(path.dirname(generatedFile), { recursive: true });
|
|
91
96
|
await writeFile(generatedFile, code);
|
|
92
97
|
if (record.kind === 'project') {
|
|
@@ -100,6 +105,7 @@ export async function compileScenes(options) {
|
|
|
100
105
|
...builtinRegistryImports,
|
|
101
106
|
...projectRegistryImports,
|
|
102
107
|
].join('\n')}\n`);
|
|
108
|
+
await writeFile(path.join(generatedDir, generatedSceneAssetsFileName), `${JSON.stringify([...projectAssets].sort(), null, 2)}\n`);
|
|
103
109
|
}
|
|
104
110
|
async function readProjectConfig(projectRoot) {
|
|
105
111
|
const configPath = path.join(projectRoot, pixifactProjectConfigFileName);
|
|
@@ -294,17 +300,10 @@ function importSourceFor(sourcePath, generatedFileDir) {
|
|
|
294
300
|
const source = path.relative(generatedFileDir, sourcePath).replaceAll(path.sep, '/').replace(/\.ts$/, '');
|
|
295
301
|
return source.startsWith('.') ? source : `./${source}`;
|
|
296
302
|
}
|
|
297
|
-
function
|
|
298
|
-
const textures = new Set();
|
|
303
|
+
function collectTemplateTextures(template, textures) {
|
|
299
304
|
for (const child of template.children) {
|
|
300
305
|
collectTextureReferences(child, textures);
|
|
301
306
|
}
|
|
302
|
-
return Object.fromEntries([...textures].map((texture) => {
|
|
303
|
-
const normalized = texture.replace(/^\.\/+/, '').replace(/^\/+/, '');
|
|
304
|
-
const assetPath = path.resolve(projectRoot, normalized);
|
|
305
|
-
const source = path.relative(generatedFileDir, assetPath).replaceAll(path.sep, '/');
|
|
306
|
-
return [texture, `${source.startsWith('.') ? source : `./${source}`}?url`];
|
|
307
|
-
}));
|
|
308
307
|
}
|
|
309
308
|
function collectSceneInstancePaths(nodes, scenePaths = new Set()) {
|
|
310
309
|
for (const node of nodes) {
|
package/dist/compiler/index.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
export * from './commands/index.js';
|
|
2
2
|
export * from './builtinScenes.js';
|
|
3
|
-
export * from './decorators.js';
|
|
4
|
-
export * from './eventRuntime.js';
|
|
5
3
|
export * from './pixiNodeSchema.js';
|
|
6
4
|
export * from './spec.js';
|
|
7
5
|
export * from './scriptInterfaceExtractor.js';
|
|
8
|
-
export * from './sceneRuntime.js';
|
|
9
6
|
export * from './sceneAssetPair.js';
|
|
10
7
|
export * from './scenePartValidation.js';
|
|
11
8
|
export * from './sceneValidation.js';
|
|
12
|
-
export * from './slotRuntime.js';
|
|
13
9
|
export * from './templateParser.js';
|
|
14
10
|
export * from './templateSerializer.js';
|
|
15
11
|
export * from './typescriptCompiler.js';
|
package/dist/compiler/index.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
export * from './commands/index.js';
|
|
2
2
|
export * from './builtinScenes.js';
|
|
3
|
-
export * from './decorators.js';
|
|
4
|
-
export * from './eventRuntime.js';
|
|
5
3
|
export * from './pixiNodeSchema.js';
|
|
6
4
|
export * from './spec.js';
|
|
7
5
|
export * from './scriptInterfaceExtractor.js';
|
|
8
|
-
export * from './sceneRuntime.js';
|
|
9
6
|
export * from './sceneAssetPair.js';
|
|
10
7
|
export * from './scenePartValidation.js';
|
|
11
8
|
export * from './sceneValidation.js';
|
|
12
|
-
export * from './slotRuntime.js';
|
|
13
9
|
export * from './templateParser.js';
|
|
14
10
|
export * from './templateSerializer.js';
|
|
15
11
|
export * from './typescriptCompiler.js';
|
package/dist/compiler/spec.d.ts
CHANGED
|
@@ -73,8 +73,8 @@ export interface CompileSceneTemplateOptions {
|
|
|
73
73
|
scriptImport?: SceneTemplateScriptImport;
|
|
74
74
|
sceneImports?: SceneTemplateScriptImport[];
|
|
75
75
|
sceneClassAliases?: Record<string, string>;
|
|
76
|
+
sceneDependencies?: string[];
|
|
76
77
|
sceneInterfaces?: Record<string, SceneTemplateInterface>;
|
|
77
|
-
textureImports?: Record<string, string>;
|
|
78
78
|
}
|
|
79
79
|
export interface SceneScriptInterface {
|
|
80
80
|
scene: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pixiSceneDisplayProps, pixiSceneGraphicsProps, pixiSceneLayoutProps, pixiSceneRectProps, pixiSceneSpriteLikeProps, pixiSceneTextStyleProps, pixiSceneTransformProps, } from './pixiNodeSchema.js';
|
|
2
|
+
import { compilerSceneNodeLocator } from './commands/index.js';
|
|
2
3
|
const transformProps = new Set(pixiSceneTransformProps);
|
|
3
4
|
const layoutProps = new Set(pixiSceneLayoutProps);
|
|
4
5
|
const pixiProps = new Set(pixiSceneDisplayProps);
|
|
@@ -37,16 +38,18 @@ class CompileContext {
|
|
|
37
38
|
const functionName = this.options.functionName || `mount${this.template.name}Scene`;
|
|
38
39
|
const actionsParameter = this.options.actionsParameter || 'actions';
|
|
39
40
|
const partsType = this.#formatPartsType();
|
|
40
|
-
const
|
|
41
|
+
const texturePreparation = this.#formatTexturePreparation();
|
|
41
42
|
this.#lines.push(`export function ${functionName}(root: Group${this.#hasEvents() ? `, ${actionsParameter}: Record<string, () => void> = {}` : ''}) {`);
|
|
43
|
+
this.#lines.push(' const __pixifactNodes: Record<string, Container> = {};');
|
|
42
44
|
this.#lines.push(' const __pixifactSlots: Record<string, Container> = {};');
|
|
43
45
|
this.#applyRootProps();
|
|
44
|
-
for (const child of this.template.children) {
|
|
45
|
-
this.#compileNode(child, 'root', actionsParameter);
|
|
46
|
+
for (const [index, child] of this.template.children.entries()) {
|
|
47
|
+
this.#compileNode(child, 'root', actionsParameter, String(index));
|
|
46
48
|
}
|
|
47
49
|
this.#lines.push(' return {');
|
|
48
50
|
this.#lines.push(' root,');
|
|
49
51
|
this.#lines.push(` parts: { ${this.#parts.map((part) => part.id).join(', ')} },`);
|
|
52
|
+
this.#lines.push(' nodes: __pixifactNodes,');
|
|
50
53
|
this.#lines.push(' slots: __pixifactSlots,');
|
|
51
54
|
this.#lines.push(' };');
|
|
52
55
|
this.#lines.push('}');
|
|
@@ -57,7 +60,10 @@ class CompileContext {
|
|
|
57
60
|
}
|
|
58
61
|
this.#lines.push('');
|
|
59
62
|
this.#lines.push(`registerScene(${JSON.stringify(this.options.registrationPath)}, {`);
|
|
63
|
+
this.#lines.push(` assets: ${JSON.stringify([...this.#textures.keys()])},`);
|
|
64
|
+
this.#lines.push(` dependencies: ${JSON.stringify(this.options.sceneDependencies ?? [])},`);
|
|
60
65
|
this.#lines.push(` mount: ${functionName},`);
|
|
66
|
+
this.#lines.push(` prepare: ${this.#prepareFunctionName()},`);
|
|
61
67
|
this.#lines.push('});');
|
|
62
68
|
if (this.options.scriptImport) {
|
|
63
69
|
this.#lines.push(`registerSceneClass(${this.options.scriptImport.localName}, ${JSON.stringify(this.options.registrationPath)});`);
|
|
@@ -66,7 +72,7 @@ class CompileContext {
|
|
|
66
72
|
const imports = this.#formatImports();
|
|
67
73
|
return [
|
|
68
74
|
imports,
|
|
69
|
-
|
|
75
|
+
texturePreparation,
|
|
70
76
|
partsType,
|
|
71
77
|
this.#lines.join('\n'),
|
|
72
78
|
].filter(Boolean).join('\n\n') + '\n';
|
|
@@ -79,9 +85,6 @@ class CompileContext {
|
|
|
79
85
|
])];
|
|
80
86
|
const runtimeImports = [...new Set(['Group', ...[...this.#pixiRuntimeImports].sort()])];
|
|
81
87
|
const lines = [`import { ${imports.join(', ')} } from 'pixi.js';`, `import { ${runtimeImports.join(', ')} } from 'pixifact/runtime';`];
|
|
82
|
-
for (const [texture, variable] of this.#textureImportEntries()) {
|
|
83
|
-
lines.push(`import ${variable} from ${JSON.stringify(this.options.textureImports?.[texture])};`);
|
|
84
|
-
}
|
|
85
88
|
for (const sceneImport of this.options.sceneImports ?? []) {
|
|
86
89
|
const classImport = sceneImport.exportName === sceneImport.localName
|
|
87
90
|
? sceneImport.exportName
|
|
@@ -98,7 +101,7 @@ class CompileContext {
|
|
|
98
101
|
lines.push(`import { ${this.options.scriptImport.exportName} as ${this.options.scriptImport.localName} } from ${JSON.stringify(this.options.scriptImport.source)};`);
|
|
99
102
|
}
|
|
100
103
|
if (this.#runtimeImports.size > 0) {
|
|
101
|
-
lines.push(`import { ${[...this.#runtimeImports].sort().join(', ')} } from 'pixifact/
|
|
104
|
+
lines.push(`import { ${[...this.#runtimeImports].sort().join(', ')} } from 'pixifact/scene';`);
|
|
102
105
|
}
|
|
103
106
|
return lines.join('\n');
|
|
104
107
|
}
|
|
@@ -109,6 +112,7 @@ class CompileContext {
|
|
|
109
112
|
lines.push(` ${part.id}: ${part.type};`);
|
|
110
113
|
}
|
|
111
114
|
lines.push(' };');
|
|
115
|
+
lines.push(' nodes: Record<string, Container>;');
|
|
112
116
|
lines.push(' slots: Record<string, Container>;');
|
|
113
117
|
lines.push('};');
|
|
114
118
|
return lines.join('\n');
|
|
@@ -174,16 +178,27 @@ class CompileContext {
|
|
|
174
178
|
}
|
|
175
179
|
}
|
|
176
180
|
}
|
|
177
|
-
#
|
|
181
|
+
#formatTexturePreparation() {
|
|
178
182
|
if (this.#textures.size === 0) {
|
|
179
|
-
return
|
|
183
|
+
return `export async function ${this.#prepareFunctionName()}() {}`;
|
|
180
184
|
}
|
|
181
|
-
this.#pixiImports.add('
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
this.#pixiImports.add('Texture');
|
|
186
|
+
this.#runtimeImports.add('loadSceneTexture');
|
|
187
|
+
const entries = [...this.#textures.entries()];
|
|
188
|
+
return [
|
|
189
|
+
...entries.map(([, variable]) => `let ${variable}: Texture;`),
|
|
190
|
+
'',
|
|
191
|
+
`export async function ${this.#prepareFunctionName()}() {`,
|
|
192
|
+
` [${entries.map(([, variable]) => variable).join(', ')}] = await Promise.all([`,
|
|
193
|
+
...entries.map(([texture]) => ` loadSceneTexture(${JSON.stringify(texture)}),`),
|
|
194
|
+
' ]);',
|
|
195
|
+
'}',
|
|
196
|
+
].join('\n');
|
|
197
|
+
}
|
|
198
|
+
#prepareFunctionName() {
|
|
199
|
+
return `prepare${this.template.name}Scene`;
|
|
200
|
+
}
|
|
201
|
+
#compileNode(node, parent, actionsParameter, path) {
|
|
187
202
|
if (node.kind === 'slotOutlet') {
|
|
188
203
|
this.#runtimeImports.add('registerSlot');
|
|
189
204
|
this.#lines.push(` __pixifactSlots[${JSON.stringify(node.name)}] = ${parent};`);
|
|
@@ -191,24 +206,27 @@ class CompileContext {
|
|
|
191
206
|
return;
|
|
192
207
|
}
|
|
193
208
|
if (node.kind === 'sceneInstance') {
|
|
194
|
-
this.#compileSceneInstance(node, parent, actionsParameter);
|
|
209
|
+
this.#compileSceneInstance(node, parent, actionsParameter, path);
|
|
195
210
|
return;
|
|
196
211
|
}
|
|
197
|
-
this.#compilePixiNode(node, parent, actionsParameter);
|
|
212
|
+
this.#compilePixiNode(node, parent, actionsParameter, path);
|
|
198
213
|
}
|
|
199
|
-
#compilePixiNode(node, parent, actionsParameter) {
|
|
214
|
+
#compilePixiNode(node, parent, actionsParameter, path) {
|
|
200
215
|
const variable = node.id || this.#anonymousName(node.type);
|
|
216
|
+
const locator = compilerSceneNodeLocator(node, path);
|
|
201
217
|
this.#lines.push(` const ${variable} = ${this.#constructPixiNode(node)};`);
|
|
202
218
|
this.#applyNodeId(variable, node.id);
|
|
203
219
|
this.#applyPixiProps(variable, node.props, false, undefined, node.type);
|
|
204
220
|
this.#applyParentSorting(parent, node.props);
|
|
205
221
|
this.#lines.push(` ${parent}.addChild(${variable});`);
|
|
206
|
-
|
|
207
|
-
|
|
222
|
+
this.#lines.push(` __pixifactNodes[${JSON.stringify(locator)}] = ${variable};`);
|
|
223
|
+
for (const [index, child] of node.children.entries()) {
|
|
224
|
+
this.#compileNode(child, variable, actionsParameter, `${locator}/${index}`);
|
|
208
225
|
}
|
|
209
226
|
}
|
|
210
|
-
#compileSceneInstance(node, parent, actionsParameter) {
|
|
227
|
+
#compileSceneInstance(node, parent, actionsParameter, path) {
|
|
211
228
|
const variable = node.id || this.#anonymousName(node.type);
|
|
229
|
+
const locator = compilerSceneNodeLocator(node, path);
|
|
212
230
|
const constructorName = this.#sceneConstructorName(node);
|
|
213
231
|
this.#lines.push(` const ${variable} = new ${constructorName}();`);
|
|
214
232
|
this.#applyPixiProps(variable, node.props, true, node);
|
|
@@ -218,20 +236,22 @@ class CompileContext {
|
|
|
218
236
|
}
|
|
219
237
|
this.#applyParentSorting(parent, node.props);
|
|
220
238
|
this.#lines.push(` ${parent}.addChild(${variable});`);
|
|
239
|
+
this.#lines.push(` __pixifactNodes[${JSON.stringify(locator)}] = ${variable};`);
|
|
221
240
|
for (const [slot, children] of Object.entries(node.slots)) {
|
|
222
|
-
for (const child of children) {
|
|
223
|
-
const childVariable = this.#compileSlottedNode(child, variable, actionsParameter);
|
|
241
|
+
for (const [index, child] of children.entries()) {
|
|
242
|
+
const childVariable = this.#compileSlottedNode(child, variable, actionsParameter, `${locator}/slot:${slot}/${index}`);
|
|
224
243
|
this.#runtimeImports.add('mount');
|
|
225
244
|
this.#lines.push(` mount(${variable}, ${childVariable}, ${JSON.stringify(slot)});`);
|
|
226
245
|
}
|
|
227
246
|
}
|
|
228
247
|
}
|
|
229
|
-
#compileSlottedNode(node, slotTarget, actionsParameter) {
|
|
248
|
+
#compileSlottedNode(node, slotTarget, actionsParameter, path) {
|
|
230
249
|
if (node.kind === 'slotOutlet') {
|
|
231
250
|
throw new Error(`Cannot place <slot> inside ${slotTarget}.`);
|
|
232
251
|
}
|
|
233
252
|
if (node.kind === 'sceneInstance') {
|
|
234
253
|
const variable = node.id || this.#anonymousName(node.type);
|
|
254
|
+
const locator = compilerSceneNodeLocator(node, path);
|
|
235
255
|
const constructorName = this.#sceneConstructorName(node);
|
|
236
256
|
this.#lines.push(` const ${variable} = new ${constructorName}();`);
|
|
237
257
|
this.#applyPixiProps(variable, node.props, true, node);
|
|
@@ -239,9 +259,10 @@ class CompileContext {
|
|
|
239
259
|
this.#runtimeImports.add('connectSceneEvent');
|
|
240
260
|
this.#lines.push(` connectSceneEvent(${variable}.${name}, ${JSON.stringify(action)}, root, ${actionsParameter});`);
|
|
241
261
|
}
|
|
262
|
+
this.#lines.push(` __pixifactNodes[${JSON.stringify(locator)}] = ${variable};`);
|
|
242
263
|
for (const [slot, children] of Object.entries(node.slots)) {
|
|
243
|
-
for (const child of children) {
|
|
244
|
-
const childVariable = this.#compileSlottedNode(child, variable, actionsParameter);
|
|
264
|
+
for (const [index, child] of children.entries()) {
|
|
265
|
+
const childVariable = this.#compileSlottedNode(child, variable, actionsParameter, `${locator}/slot:${slot}/${index}`);
|
|
245
266
|
this.#runtimeImports.add('mount');
|
|
246
267
|
this.#lines.push(` mount(${variable}, ${childVariable}, ${JSON.stringify(slot)});`);
|
|
247
268
|
}
|
|
@@ -249,11 +270,13 @@ class CompileContext {
|
|
|
249
270
|
return variable;
|
|
250
271
|
}
|
|
251
272
|
const variable = node.id || this.#anonymousName(node.type);
|
|
273
|
+
const locator = compilerSceneNodeLocator(node, path);
|
|
252
274
|
this.#lines.push(` const ${variable} = ${this.#constructPixiNode(node)};`);
|
|
253
275
|
this.#applyNodeId(variable, node.id);
|
|
254
276
|
this.#applyPixiProps(variable, node.props, false, undefined, node.type);
|
|
255
|
-
|
|
256
|
-
|
|
277
|
+
this.#lines.push(` __pixifactNodes[${JSON.stringify(locator)}] = ${variable};`);
|
|
278
|
+
for (const [index, child] of node.children.entries()) {
|
|
279
|
+
this.#compileNode(child, variable, actionsParameter, `${locator}/${index}`);
|
|
257
280
|
}
|
|
258
281
|
return variable;
|
|
259
282
|
}
|
|
@@ -578,20 +601,6 @@ class CompileContext {
|
|
|
578
601
|
this.#textures.set(texture, variable);
|
|
579
602
|
return variable;
|
|
580
603
|
}
|
|
581
|
-
#textureImportEntries() {
|
|
582
|
-
return [...this.#textures.keys()]
|
|
583
|
-
.filter((texture) => this.options.textureImports?.[texture])
|
|
584
|
-
.map((texture, index) => [texture, `__pixifactTextureUrl${index + 1}`]);
|
|
585
|
-
}
|
|
586
|
-
#textureImportVariable(texture) {
|
|
587
|
-
const index = [...this.#textures.keys()]
|
|
588
|
-
.filter((key) => this.options.textureImports?.[key])
|
|
589
|
-
.indexOf(texture);
|
|
590
|
-
return index >= 0 ? `__pixifactTextureUrl${index + 1}` : undefined;
|
|
591
|
-
}
|
|
592
|
-
#textureLoadSource(texture) {
|
|
593
|
-
return this.#textureImportVariable(texture) ?? this.#value(texture);
|
|
594
|
-
}
|
|
595
604
|
#textureValue(value) {
|
|
596
605
|
return typeof value === 'string' ? this.#textureVariable(value) : this.#value(value);
|
|
597
606
|
}
|
|
@@ -4,5 +4,6 @@ export interface PixifactScenesPluginOptions {
|
|
|
4
4
|
}
|
|
5
5
|
export declare function pixifactScenesPlugin(options?: PixifactScenesPluginOptions): {
|
|
6
6
|
name: string;
|
|
7
|
-
resolveId(id: string):
|
|
7
|
+
resolveId(id: string): "\0pixifact:scenes" | undefined;
|
|
8
|
+
load(id: string): Promise<string | undefined>;
|
|
8
9
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { generatedSceneAssetsFileName } from '../compiler/compileScenes.js';
|
|
3
5
|
function projectRootPath(projectRoot) {
|
|
4
6
|
if (typeof projectRoot === 'string') {
|
|
5
7
|
return projectRoot;
|
|
@@ -10,12 +12,37 @@ function projectRootPath(projectRoot) {
|
|
|
10
12
|
return process.cwd();
|
|
11
13
|
}
|
|
12
14
|
export function pixifactScenesPlugin(options = {}) {
|
|
13
|
-
const
|
|
15
|
+
const projectRoot = projectRootPath(options.projectRoot);
|
|
16
|
+
const generatedDir = path.resolve(projectRoot, options.generatedDir ?? '.pixifact/generated');
|
|
14
17
|
const sceneRegistry = path.join(generatedDir, 'scenes.generated.ts');
|
|
18
|
+
const sceneAssets = path.join(generatedDir, generatedSceneAssetsFileName);
|
|
19
|
+
const virtualSceneRegistry = '\0pixifact:scenes';
|
|
15
20
|
return {
|
|
16
21
|
name: 'pixifact-scenes',
|
|
17
22
|
resolveId(id) {
|
|
18
|
-
return id === 'pixifact:scenes' ?
|
|
23
|
+
return id === 'pixifact:scenes' ? virtualSceneRegistry : undefined;
|
|
24
|
+
},
|
|
25
|
+
async load(id) {
|
|
26
|
+
if (id !== virtualSceneRegistry) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const assets = JSON.parse(await readFile(sceneAssets, 'utf8'));
|
|
30
|
+
const imports = assets.map((asset, index) => `import __pixifactAsset${index + 1} from ${JSON.stringify(viteFileImport(path.resolve(projectRoot, asset), '?url'))};`);
|
|
31
|
+
const manifest = Object.fromEntries(assets.map((asset, index) => [
|
|
32
|
+
asset,
|
|
33
|
+
{ src: `__pixifactAsset${index + 1}` },
|
|
34
|
+
]));
|
|
35
|
+
const manifestSource = JSON.stringify(manifest, null, 2)
|
|
36
|
+
.replace(/"src": "(__pixifactAsset\d+)"/g, '"src": $1');
|
|
37
|
+
return [
|
|
38
|
+
...imports,
|
|
39
|
+
"import { configureSceneAssets } from 'pixifact/scene';",
|
|
40
|
+
`import ${JSON.stringify(viteFileImport(sceneRegistry))};`,
|
|
41
|
+
`configureSceneAssets(${manifestSource});`,
|
|
42
|
+
].join('\n');
|
|
19
43
|
},
|
|
20
44
|
};
|
|
21
45
|
}
|
|
46
|
+
function viteFileImport(filePath, suffix = '') {
|
|
47
|
+
return `/@fs/${filePath.replaceAll(path.sep, '/')}${suffix}`;
|
|
48
|
+
}
|