pixifact 0.1.3
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 +44 -0
- package/dist/authoring/ActionRegistry.d.ts +10 -0
- package/dist/authoring/ActionRegistry.js +26 -0
- package/dist/authoring/ComponentPalette.d.ts +16 -0
- package/dist/authoring/ComponentPalette.js +50 -0
- package/dist/authoring/DesignToken.d.ts +16 -0
- package/dist/authoring/DesignToken.js +33 -0
- package/dist/authoring/DiffModel.d.ts +10 -0
- package/dist/authoring/DiffModel.js +104 -0
- package/dist/authoring/InspectorModel.d.ts +27 -0
- package/dist/authoring/InspectorModel.js +139 -0
- package/dist/authoring/LogicGraph.d.ts +66 -0
- package/dist/authoring/LogicGraph.js +184 -0
- package/dist/authoring/OverrideJournal.d.ts +18 -0
- package/dist/authoring/OverrideJournal.js +23 -0
- package/dist/authoring/PreferenceMemory.d.ts +21 -0
- package/dist/authoring/PreferenceMemory.js +39 -0
- package/dist/authoring/ProjectConfig.d.ts +20 -0
- package/dist/authoring/ProjectConfig.js +78 -0
- package/dist/authoring/RuntimePreview.d.ts +11 -0
- package/dist/authoring/RuntimePreview.js +25 -0
- package/dist/authoring/SceneDocument.d.ts +74 -0
- package/dist/authoring/SceneDocument.js +332 -0
- package/dist/authoring/SceneProjectState.d.ts +20 -0
- package/dist/authoring/SceneProjectState.js +8 -0
- package/dist/authoring/SceneSelection.d.ts +11 -0
- package/dist/authoring/SceneSelection.js +1 -0
- package/dist/authoring/index.d.ts +13 -0
- package/dist/authoring/index.js +13 -0
- package/dist/commands/Command.d.ts +63 -0
- package/dist/commands/Command.js +1 -0
- package/dist/commands/CommandStack.d.ts +14 -0
- package/dist/commands/CommandStack.js +45 -0
- package/dist/commands/applyCommand.d.ts +23 -0
- package/dist/commands/applyCommand.js +316 -0
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +4 -0
- package/dist/commands/utils.d.ts +17 -0
- package/dist/commands/utils.js +77 -0
- package/dist/commands/validateCommand.d.ts +12 -0
- package/dist/commands/validateCommand.js +285 -0
- package/dist/compiler/commands/index.d.ts +109 -0
- package/dist/compiler/commands/index.js +492 -0
- package/dist/compiler/compileScenes.d.ts +11 -0
- package/dist/compiler/compileScenes.js +220 -0
- package/dist/compiler/decorators.d.ts +6 -0
- package/dist/compiler/decorators.js +79 -0
- package/dist/compiler/eventRuntime.d.ts +8 -0
- package/dist/compiler/eventRuntime.js +29 -0
- package/dist/compiler/index.d.ts +14 -0
- package/dist/compiler/index.js +14 -0
- package/dist/compiler/pixiNodeSchema.d.ts +39 -0
- package/dist/compiler/pixiNodeSchema.js +267 -0
- package/dist/compiler/sceneAssetPair.d.ts +11 -0
- package/dist/compiler/sceneAssetPair.js +92 -0
- package/dist/compiler/scenePartValidation.d.ts +6 -0
- package/dist/compiler/scenePartValidation.js +24 -0
- package/dist/compiler/sceneRuntime.d.ts +13 -0
- package/dist/compiler/sceneRuntime.js +22 -0
- package/dist/compiler/sceneValidation.d.ts +48 -0
- package/dist/compiler/sceneValidation.js +383 -0
- package/dist/compiler/scriptInterfaceExtractor.d.ts +6 -0
- package/dist/compiler/scriptInterfaceExtractor.js +258 -0
- package/dist/compiler/slotRuntime.d.ts +3 -0
- package/dist/compiler/slotRuntime.js +17 -0
- package/dist/compiler/spec.d.ts +95 -0
- package/dist/compiler/spec.js +1 -0
- package/dist/compiler/templateParser.d.ts +2 -0
- package/dist/compiler/templateParser.js +302 -0
- package/dist/compiler/templateSerializer.d.ts +2 -0
- package/dist/compiler/templateSerializer.js +101 -0
- package/dist/compiler/typescriptCompiler.d.ts +2 -0
- package/dist/compiler/typescriptCompiler.js +494 -0
- package/dist/compiler-node/index.d.ts +2 -0
- package/dist/compiler-node/index.js +2 -0
- package/dist/compiler-node/vite.d.ts +8 -0
- package/dist/compiler-node/vite.js +21 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/nodes/Input.d.ts +91 -0
- package/dist/nodes/Input.js +352 -0
- package/dist/nodes/Textarea.d.ts +10 -0
- package/dist/nodes/Textarea.js +38 -0
- package/dist/nodes/components/Button.d.ts +8 -0
- package/dist/nodes/components/Button.js +45 -0
- package/dist/nodes/components/InputField.d.ts +12 -0
- package/dist/nodes/components/InputField.js +53 -0
- package/dist/nodes/components/ProgressBar.d.ts +14 -0
- package/dist/nodes/components/ProgressBar.js +66 -0
- package/dist/nodes/components/ScrollRect.d.ts +23 -0
- package/dist/nodes/components/ScrollRect.js +108 -0
- package/dist/nodes/components/Selectable.d.ts +32 -0
- package/dist/nodes/components/Selectable.js +153 -0
- package/dist/nodes/components/index.d.ts +5 -0
- package/dist/nodes/components/index.js +5 -0
- package/dist/nodes/graphics/Graphic.d.ts +14 -0
- package/dist/nodes/graphics/Graphic.js +47 -0
- package/dist/nodes/graphics/ImageGraphic.d.ts +9 -0
- package/dist/nodes/graphics/ImageGraphic.js +42 -0
- package/dist/nodes/graphics/RoundedRectGraphic.d.ts +13 -0
- package/dist/nodes/graphics/RoundedRectGraphic.js +65 -0
- package/dist/nodes/graphics/TextGraphic.d.ts +13 -0
- package/dist/nodes/graphics/TextGraphic.js +70 -0
- package/dist/nodes/graphics/index.d.ts +4 -0
- package/dist/nodes/graphics/index.js +4 -0
- package/dist/nodes/index.d.ts +3 -0
- package/dist/nodes/index.js +3 -0
- package/dist/runtime/Application.d.ts +15 -0
- package/dist/runtime/Application.js +67 -0
- package/dist/runtime/GameObject.d.ts +100 -0
- package/dist/runtime/GameObject.js +297 -0
- package/dist/runtime/GameObjectEvent.d.ts +52 -0
- package/dist/runtime/GameObjectEvent.js +38 -0
- package/dist/runtime/Transform.d.ts +32 -0
- package/dist/runtime/Transform.js +157 -0
- package/dist/runtime/component/Component.d.ts +13 -0
- package/dist/runtime/component/Component.js +13 -0
- package/dist/runtime/component/ComponentRegistry.d.ts +49 -0
- package/dist/runtime/component/ComponentRegistry.js +25 -0
- package/dist/runtime/component/Flex.d.ts +6 -0
- package/dist/runtime/component/Flex.js +15 -0
- package/dist/runtime/component/FlexGroup.d.ts +26 -0
- package/dist/runtime/component/FlexGroup.js +136 -0
- package/dist/runtime/component/GridLayout.d.ts +47 -0
- package/dist/runtime/component/GridLayout.js +129 -0
- package/dist/runtime/component/Layout.d.ts +104 -0
- package/dist/runtime/component/Layout.js +248 -0
- package/dist/runtime/component/decorators.d.ts +4 -0
- package/dist/runtime/component/decorators.js +52 -0
- package/dist/runtime/component/index.d.ts +7 -0
- package/dist/runtime/component/index.js +7 -0
- package/dist/runtime/graphics/index.d.ts +11 -0
- package/dist/runtime/graphics/index.js +29 -0
- package/dist/runtime/group/index.d.ts +39 -0
- package/dist/runtime/group/index.js +102 -0
- package/dist/runtime/image/Image.d.ts +19 -0
- package/dist/runtime/image/Image.js +60 -0
- package/dist/runtime/image/NineSliceImage.d.ts +23 -0
- package/dist/runtime/image/NineSliceImage.js +64 -0
- package/dist/runtime/image/index.d.ts +2 -0
- package/dist/runtime/image/index.js +2 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/label/Label.d.ts +11 -0
- package/dist/runtime/label/Label.js +26 -0
- package/dist/runtime/label/LabelStyle.d.ts +3 -0
- package/dist/runtime/label/LabelStyle.js +3 -0
- package/dist/runtime/label/index.d.ts +2 -0
- package/dist/runtime/label/index.js +2 -0
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +1 -0
- package/dist/runtime/utils/onlyOnceQueueMicrotask.d.ts +1 -0
- package/dist/runtime/utils/onlyOnceQueueMicrotask.js +12 -0
- package/dist/runtime/utils/setProps.d.ts +10 -0
- package/dist/runtime/utils/setProps.js +17 -0
- package/dist/scene/dsl.d.ts +25 -0
- package/dist/scene/dsl.js +112 -0
- package/dist/scene/index.d.ts +5 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/instantiate.d.ts +8 -0
- package/dist/scene/instantiate.js +208 -0
- package/dist/scene/nodesDsl.d.ts +42 -0
- package/dist/scene/nodesDsl.js +169 -0
- package/dist/scene/spec.d.ts +100 -0
- package/dist/scene/spec.js +1 -0
- package/dist/scene/templates.d.ts +21 -0
- package/dist/scene/templates.js +239 -0
- package/package.json +90 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { pixiSceneNodeAcceptsChildren } from '../pixiNodeSchema.js';
|
|
2
|
+
function cloneNode(node) {
|
|
3
|
+
return structuredClone(node);
|
|
4
|
+
}
|
|
5
|
+
export function compilerSceneNodeLocator(node, path = '') {
|
|
6
|
+
const suffix = node.kind === 'slotOutlet'
|
|
7
|
+
? `slot:${node.name}`
|
|
8
|
+
: node.id ?? (node.kind === 'sceneInstance' ? `${node.type}:${node.scene}` : node.type);
|
|
9
|
+
if (path) {
|
|
10
|
+
return `${path}:${suffix}`;
|
|
11
|
+
}
|
|
12
|
+
if (node.kind === 'slotOutlet') {
|
|
13
|
+
return suffix;
|
|
14
|
+
}
|
|
15
|
+
return suffix;
|
|
16
|
+
}
|
|
17
|
+
function childCompilerSceneNodeLocator(parentLocator, node, index) {
|
|
18
|
+
return compilerSceneNodeLocator(node, parentLocator === '__scene__' ? String(index) : `${parentLocator}/${index}`);
|
|
19
|
+
}
|
|
20
|
+
function normalizeSlotOutletName(value) {
|
|
21
|
+
return value.trim() || 'default';
|
|
22
|
+
}
|
|
23
|
+
function sceneInstanceHasSlot(node, slot, context) {
|
|
24
|
+
return node.slots[slot] !== undefined
|
|
25
|
+
|| context.sceneInterfaces?.[node.scene]?.slots[slot] !== undefined;
|
|
26
|
+
}
|
|
27
|
+
function canInsertNodeIntoParent(parentLocator, child, acceptsSlotOutlet) {
|
|
28
|
+
if (child.kind === 'slotOutlet') {
|
|
29
|
+
return parentLocator !== '__scene__' && acceptsSlotOutlet;
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
function findCompilerSceneNodeLocation(nodes, locator, context, parentLocator = '__scene__', acceptsSlotOutlet = false) {
|
|
34
|
+
for (const [index, node] of nodes.entries()) {
|
|
35
|
+
const nodeLocator = childCompilerSceneNodeLocator(parentLocator, node, index);
|
|
36
|
+
if (nodeLocator === locator) {
|
|
37
|
+
return {
|
|
38
|
+
acceptsSlotOutlet,
|
|
39
|
+
index,
|
|
40
|
+
locator: nodeLocator,
|
|
41
|
+
node,
|
|
42
|
+
nodes,
|
|
43
|
+
parentLocator,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (node.kind === 'pixi') {
|
|
47
|
+
const found = findCompilerSceneNodeLocation(node.children, locator, context, nodeLocator, pixiSceneNodeAcceptsChildren(node.type));
|
|
48
|
+
if (found) {
|
|
49
|
+
return found;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (node.kind === 'sceneInstance') {
|
|
54
|
+
for (const [slot, children] of Object.entries(node.slots)) {
|
|
55
|
+
const found = findCompilerSceneNodeLocation(children, locator, context, `${nodeLocator}/slot:${slot}`, false);
|
|
56
|
+
if (found) {
|
|
57
|
+
return found;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
function directSlotName(ownerLocator, locator) {
|
|
65
|
+
const prefix = `${ownerLocator}/slot:`;
|
|
66
|
+
if (!locator.startsWith(prefix)) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
const rest = locator.slice(prefix.length);
|
|
70
|
+
return rest.includes('/') ? undefined : rest;
|
|
71
|
+
}
|
|
72
|
+
function findCompilerSceneChildList(nodes, parent, context, parentLocator = '__scene__') {
|
|
73
|
+
if (parentLocator === '__scene__' && parent === '__scene__') {
|
|
74
|
+
return {
|
|
75
|
+
acceptsSlotOutlet: false,
|
|
76
|
+
index: nodes.length,
|
|
77
|
+
nodes,
|
|
78
|
+
parentLocator: '__scene__',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
for (const [index, node] of nodes.entries()) {
|
|
82
|
+
const nodeLocator = childCompilerSceneNodeLocator(parentLocator, node, index);
|
|
83
|
+
if (node.kind === 'pixi') {
|
|
84
|
+
if (nodeLocator === parent) {
|
|
85
|
+
return pixiSceneNodeAcceptsChildren(node.type)
|
|
86
|
+
? {
|
|
87
|
+
acceptsSlotOutlet: true,
|
|
88
|
+
index: node.children.length,
|
|
89
|
+
nodes: node.children,
|
|
90
|
+
parentLocator: nodeLocator,
|
|
91
|
+
}
|
|
92
|
+
: undefined;
|
|
93
|
+
}
|
|
94
|
+
const found = findCompilerSceneChildList(node.children, parent, context, nodeLocator);
|
|
95
|
+
if (found) {
|
|
96
|
+
return found;
|
|
97
|
+
}
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (node.kind === 'sceneInstance') {
|
|
101
|
+
const slot = directSlotName(nodeLocator, parent);
|
|
102
|
+
if (slot) {
|
|
103
|
+
if (!sceneInstanceHasSlot(node, slot, context)) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const children = node.slots[slot] ?? [];
|
|
107
|
+
node.slots[slot] = children;
|
|
108
|
+
return {
|
|
109
|
+
acceptsSlotOutlet: false,
|
|
110
|
+
index: children.length,
|
|
111
|
+
nodes: children,
|
|
112
|
+
parentLocator: parent,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
for (const [slotName, children] of Object.entries(node.slots)) {
|
|
116
|
+
const found = findCompilerSceneChildList(children, parent, context, `${nodeLocator}/slot:${slotName}`);
|
|
117
|
+
if (found) {
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
function findCompilerSceneNodeLocator(nodes, target, parentLocator = '__scene__') {
|
|
126
|
+
for (const [index, node] of nodes.entries()) {
|
|
127
|
+
const nodeLocator = childCompilerSceneNodeLocator(parentLocator, node, index);
|
|
128
|
+
if (node === target) {
|
|
129
|
+
return nodeLocator;
|
|
130
|
+
}
|
|
131
|
+
if (node.kind === 'pixi') {
|
|
132
|
+
const found = findCompilerSceneNodeLocator(node.children, target, nodeLocator);
|
|
133
|
+
if (found) {
|
|
134
|
+
return found;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (node.kind === 'sceneInstance') {
|
|
139
|
+
for (const [slot, children] of Object.entries(node.slots)) {
|
|
140
|
+
const found = findCompilerSceneNodeLocator(children, target, `${nodeLocator}/slot:${slot}`);
|
|
141
|
+
if (found) {
|
|
142
|
+
return found;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
function setSceneName(template, command) {
|
|
150
|
+
const previous = template.name;
|
|
151
|
+
template.name = command.value;
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
command,
|
|
155
|
+
inverse: {
|
|
156
|
+
op: 'setSceneName',
|
|
157
|
+
value: previous,
|
|
158
|
+
},
|
|
159
|
+
selection: { type: 'scene' },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function setSceneProp(template, command) {
|
|
163
|
+
const previous = getPropPathValue(template.props, command.prop);
|
|
164
|
+
setPropPathValue(template.props, command.prop, command.value);
|
|
165
|
+
return {
|
|
166
|
+
ok: true,
|
|
167
|
+
command,
|
|
168
|
+
inverse: {
|
|
169
|
+
op: 'setSceneProp',
|
|
170
|
+
prop: command.prop,
|
|
171
|
+
value: previous,
|
|
172
|
+
},
|
|
173
|
+
selection: { type: 'scene' },
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function setNodeId(template, command, context) {
|
|
177
|
+
const located = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
178
|
+
if (!located || located.node.kind === 'slotOutlet') {
|
|
179
|
+
return { ok: false, command, error: 'Node was not found.' };
|
|
180
|
+
}
|
|
181
|
+
const previous = located.node.id;
|
|
182
|
+
located.node.id = command.value?.trim() || undefined;
|
|
183
|
+
const locator = childCompilerSceneNodeLocator(located.parentLocator, located.node, located.index);
|
|
184
|
+
return {
|
|
185
|
+
ok: true,
|
|
186
|
+
command,
|
|
187
|
+
inverse: {
|
|
188
|
+
op: 'setNodeId',
|
|
189
|
+
node: locator,
|
|
190
|
+
value: previous,
|
|
191
|
+
},
|
|
192
|
+
selection: { type: 'node', node: locator },
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function setNodeProp(template, command, context) {
|
|
196
|
+
const located = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
197
|
+
if (!located || located.node.kind === 'slotOutlet') {
|
|
198
|
+
return { ok: false, command, error: 'Node was not found.' };
|
|
199
|
+
}
|
|
200
|
+
const previous = getPropPathValue(located.node.props, command.prop);
|
|
201
|
+
setPropPathValue(located.node.props, command.prop, command.value);
|
|
202
|
+
return {
|
|
203
|
+
ok: true,
|
|
204
|
+
command,
|
|
205
|
+
inverse: {
|
|
206
|
+
op: 'setNodeProp',
|
|
207
|
+
node: command.node,
|
|
208
|
+
prop: command.prop,
|
|
209
|
+
value: previous,
|
|
210
|
+
},
|
|
211
|
+
selection: { type: 'node', node: command.node },
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function getPropPathValue(props, prop) {
|
|
215
|
+
const [root, field, ...rest] = prop.split('.');
|
|
216
|
+
if (!field || rest.length > 0) {
|
|
217
|
+
return props[prop];
|
|
218
|
+
}
|
|
219
|
+
const value = props[root];
|
|
220
|
+
return value && typeof value === 'object' ? value[field] : undefined;
|
|
221
|
+
}
|
|
222
|
+
function setPropPathValue(props, prop, value) {
|
|
223
|
+
const [root, field, ...rest] = prop.split('.');
|
|
224
|
+
if (!field || rest.length > 0) {
|
|
225
|
+
if (value === undefined) {
|
|
226
|
+
delete props[prop];
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
props[prop] = value;
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const current = props[root];
|
|
234
|
+
const objectValue = current && typeof current === 'object'
|
|
235
|
+
? { ...current }
|
|
236
|
+
: {};
|
|
237
|
+
if (value === undefined) {
|
|
238
|
+
delete objectValue[field];
|
|
239
|
+
}
|
|
240
|
+
else if (typeof value !== 'object') {
|
|
241
|
+
objectValue[field] = value;
|
|
242
|
+
}
|
|
243
|
+
if (Object.keys(objectValue).length === 0) {
|
|
244
|
+
delete props[root];
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
props[root] = objectValue;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function setNodeEvent(template, command, context) {
|
|
251
|
+
const located = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
252
|
+
if (!located || located.node.kind !== 'sceneInstance') {
|
|
253
|
+
return { ok: false, command, error: 'Node event target was not found.' };
|
|
254
|
+
}
|
|
255
|
+
const previous = located.node.events[command.event];
|
|
256
|
+
if (command.value === undefined) {
|
|
257
|
+
delete located.node.events[command.event];
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
located.node.events[command.event] = command.value;
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
ok: true,
|
|
264
|
+
command,
|
|
265
|
+
inverse: {
|
|
266
|
+
op: 'setNodeEvent',
|
|
267
|
+
node: command.node,
|
|
268
|
+
event: command.event,
|
|
269
|
+
value: previous,
|
|
270
|
+
},
|
|
271
|
+
selection: { type: 'node', node: command.node },
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function renameSlotOutlet(template, command, context) {
|
|
275
|
+
const located = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
276
|
+
if (!located || located.node.kind !== 'slotOutlet') {
|
|
277
|
+
return { ok: false, command, error: 'Slot outlet was not found.' };
|
|
278
|
+
}
|
|
279
|
+
const previous = located.node.name;
|
|
280
|
+
located.node.name = normalizeSlotOutletName(command.name);
|
|
281
|
+
const locator = childCompilerSceneNodeLocator(located.parentLocator, located.node, located.index);
|
|
282
|
+
return {
|
|
283
|
+
ok: true,
|
|
284
|
+
command,
|
|
285
|
+
inverse: {
|
|
286
|
+
op: 'renameSlotOutlet',
|
|
287
|
+
node: locator,
|
|
288
|
+
name: previous,
|
|
289
|
+
},
|
|
290
|
+
selection: { type: 'node', node: locator },
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function insertNode(template, command, context) {
|
|
294
|
+
const childList = findCompilerSceneChildList(template.children, command.parent, context);
|
|
295
|
+
if (!childList || !canInsertNodeIntoParent(command.parent, command.node, childList.acceptsSlotOutlet)) {
|
|
296
|
+
return { ok: false, command, error: 'Parent cannot contain this node.' };
|
|
297
|
+
}
|
|
298
|
+
const node = cloneNode(command.node);
|
|
299
|
+
const index = Math.max(0, Math.min(command.index ?? childList.nodes.length, childList.nodes.length));
|
|
300
|
+
childList.nodes.splice(index, 0, node);
|
|
301
|
+
const locator = childCompilerSceneNodeLocator(command.parent, node, index);
|
|
302
|
+
return {
|
|
303
|
+
ok: true,
|
|
304
|
+
command,
|
|
305
|
+
inverse: {
|
|
306
|
+
op: 'deleteNode',
|
|
307
|
+
node: locator,
|
|
308
|
+
},
|
|
309
|
+
selection: { type: 'node', node: locator },
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function deleteNode(template, command, context) {
|
|
313
|
+
const located = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
314
|
+
if (!located) {
|
|
315
|
+
return { ok: false, command, error: 'Node was not found.' };
|
|
316
|
+
}
|
|
317
|
+
const [removed] = located.nodes.splice(located.index, 1);
|
|
318
|
+
return {
|
|
319
|
+
ok: true,
|
|
320
|
+
command,
|
|
321
|
+
inverse: {
|
|
322
|
+
op: 'insertNode',
|
|
323
|
+
parent: located.parentLocator,
|
|
324
|
+
index: located.index,
|
|
325
|
+
node: cloneNode(removed),
|
|
326
|
+
},
|
|
327
|
+
selection: located.parentLocator === '__scene__'
|
|
328
|
+
? { type: 'scene' }
|
|
329
|
+
: { type: 'node', node: located.parentLocator },
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function moveNode(template, command, context) {
|
|
333
|
+
if (command.parent === command.node || command.parent.startsWith(`${command.node}/`)) {
|
|
334
|
+
return { ok: false, command, error: 'Cannot move a node into itself.' };
|
|
335
|
+
}
|
|
336
|
+
const source = findCompilerSceneNodeLocation(template.children, command.node, context);
|
|
337
|
+
const target = findCompilerSceneChildList(template.children, command.parent, context);
|
|
338
|
+
if (!source || !target || !canInsertNodeIntoParent(command.parent, source.node, target.acceptsSlotOutlet)) {
|
|
339
|
+
return { ok: false, command, error: 'Target cannot contain this node.' };
|
|
340
|
+
}
|
|
341
|
+
const [node] = source.nodes.splice(source.index, 1);
|
|
342
|
+
let index = Math.max(0, Math.min(command.index, target.nodes.length));
|
|
343
|
+
if (source.nodes === target.nodes && source.index < index) {
|
|
344
|
+
index -= 1;
|
|
345
|
+
}
|
|
346
|
+
target.nodes.splice(index, 0, node);
|
|
347
|
+
const locator = findCompilerSceneNodeLocator(template.children, node);
|
|
348
|
+
if (!locator) {
|
|
349
|
+
throw new Error('Moved Compiler Scene node is missing from the template.');
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
ok: true,
|
|
353
|
+
command,
|
|
354
|
+
inverse: {
|
|
355
|
+
op: 'moveNode',
|
|
356
|
+
node: locator,
|
|
357
|
+
parent: source.parentLocator,
|
|
358
|
+
index: source.index,
|
|
359
|
+
},
|
|
360
|
+
selection: { type: 'node', node: locator },
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function applyBatch(template, command, context) {
|
|
364
|
+
const inverseCommands = [];
|
|
365
|
+
let selection;
|
|
366
|
+
for (const child of command.commands) {
|
|
367
|
+
const result = applyCompilerSceneCommand(template, child, context);
|
|
368
|
+
if (!result.ok) {
|
|
369
|
+
for (let index = inverseCommands.length - 1; index >= 0; index--) {
|
|
370
|
+
applyCompilerSceneCommand(template, inverseCommands[index], context);
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
ok: false,
|
|
374
|
+
command,
|
|
375
|
+
error: result.error,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
inverseCommands.push(result.inverse);
|
|
379
|
+
selection = result.selection;
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
ok: true,
|
|
383
|
+
command,
|
|
384
|
+
inverse: {
|
|
385
|
+
op: 'batch',
|
|
386
|
+
commands: [...inverseCommands].reverse(),
|
|
387
|
+
},
|
|
388
|
+
selection,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
export function applyCompilerSceneCommand(template, command, context = {}) {
|
|
392
|
+
switch (command.op) {
|
|
393
|
+
case 'setSceneName':
|
|
394
|
+
return setSceneName(template, command);
|
|
395
|
+
case 'setSceneProp':
|
|
396
|
+
return setSceneProp(template, command);
|
|
397
|
+
case 'setNodeId':
|
|
398
|
+
return setNodeId(template, command, context);
|
|
399
|
+
case 'setNodeProp':
|
|
400
|
+
return setNodeProp(template, command, context);
|
|
401
|
+
case 'setNodeEvent':
|
|
402
|
+
return setNodeEvent(template, command, context);
|
|
403
|
+
case 'renameSlotOutlet':
|
|
404
|
+
return renameSlotOutlet(template, command, context);
|
|
405
|
+
case 'insertNode':
|
|
406
|
+
return insertNode(template, command, context);
|
|
407
|
+
case 'deleteNode':
|
|
408
|
+
return deleteNode(template, command, context);
|
|
409
|
+
case 'moveNode':
|
|
410
|
+
return moveNode(template, command, context);
|
|
411
|
+
case 'batch':
|
|
412
|
+
return applyBatch(template, command, context);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
export class CompilerSceneCommandStack {
|
|
416
|
+
undoStack = [];
|
|
417
|
+
redoStack = [];
|
|
418
|
+
currentRevision = 0;
|
|
419
|
+
savedRevision = 0;
|
|
420
|
+
get canUndo() {
|
|
421
|
+
return this.undoStack.length > 0;
|
|
422
|
+
}
|
|
423
|
+
get canRedo() {
|
|
424
|
+
return this.redoStack.length > 0;
|
|
425
|
+
}
|
|
426
|
+
get dirty() {
|
|
427
|
+
return this.currentRevision !== this.savedRevision;
|
|
428
|
+
}
|
|
429
|
+
execute(template, command, options = {}, context = {}) {
|
|
430
|
+
const beforeRevision = this.currentRevision;
|
|
431
|
+
const result = applyCompilerSceneCommand(template, command, context);
|
|
432
|
+
if (!result.ok) {
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
this.currentRevision += 1;
|
|
436
|
+
const previous = this.undoStack[this.undoStack.length - 1];
|
|
437
|
+
if (options.mergeKey && previous?.mergeKey === options.mergeKey) {
|
|
438
|
+
previous.command = command;
|
|
439
|
+
previous.afterRevision = this.currentRevision;
|
|
440
|
+
previous.label = options.label ?? previous.label;
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
this.undoStack.push({
|
|
444
|
+
afterRevision: this.currentRevision,
|
|
445
|
+
beforeRevision,
|
|
446
|
+
command,
|
|
447
|
+
inverse: result.inverse,
|
|
448
|
+
label: options.label,
|
|
449
|
+
mergeKey: options.mergeKey,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
this.redoStack.length = 0;
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
455
|
+
undo(template, context = {}) {
|
|
456
|
+
const entry = this.undoStack.pop();
|
|
457
|
+
if (!entry) {
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
const result = applyCompilerSceneCommand(template, entry.inverse, context);
|
|
461
|
+
if (!result.ok) {
|
|
462
|
+
this.undoStack.push(entry);
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
465
|
+
this.currentRevision = entry.beforeRevision;
|
|
466
|
+
this.redoStack.push(entry);
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
redo(template, context = {}) {
|
|
470
|
+
const entry = this.redoStack.pop();
|
|
471
|
+
if (!entry) {
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
const result = applyCompilerSceneCommand(template, entry.command, context);
|
|
475
|
+
if (!result.ok) {
|
|
476
|
+
this.redoStack.push(entry);
|
|
477
|
+
return result;
|
|
478
|
+
}
|
|
479
|
+
this.currentRevision = entry.afterRevision;
|
|
480
|
+
this.undoStack.push(entry);
|
|
481
|
+
return result;
|
|
482
|
+
}
|
|
483
|
+
markSaved() {
|
|
484
|
+
this.savedRevision = this.currentRevision;
|
|
485
|
+
}
|
|
486
|
+
clear() {
|
|
487
|
+
this.undoStack.length = 0;
|
|
488
|
+
this.redoStack.length = 0;
|
|
489
|
+
this.currentRevision = 0;
|
|
490
|
+
this.savedRevision = 0;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CompileScenesOptions {
|
|
2
|
+
projectRoot: string | URL;
|
|
3
|
+
sourceRoots?: string[];
|
|
4
|
+
generatedDir?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class CompileSceneError extends Error {
|
|
7
|
+
readonly scene: string;
|
|
8
|
+
readonly source?: string | undefined;
|
|
9
|
+
constructor(message: string, scene: string, source?: string | undefined);
|
|
10
|
+
}
|
|
11
|
+
export declare function compileScenes(options: CompileScenesOptions): Promise<void>;
|