@datamoc/mw_games 0.37.0 → 0.38.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/CHANGELOG.md +24 -0
- package/README.md +26 -0
- package/api-surface.json +150 -0
- package/dist/mw_games.global.js +4 -4
- package/dist/mwl/presentation.d.ts +70 -0
- package/dist/mwl/presentation.d.ts.map +1 -0
- package/dist/mwl/presentation.js +412 -0
- package/dist/mwl/presentation.js.map +1 -0
- package/dist/two-d/presentation/MwlPresentation.d.ts +98 -0
- package/dist/two-d/presentation/MwlPresentation.d.ts.map +1 -0
- package/dist/two-d/presentation/MwlPresentation.js +704 -0
- package/dist/two-d/presentation/MwlPresentation.js.map +1 -0
- package/dist/two-d/presentation/index.d.ts +3 -0
- package/dist/two-d/presentation/index.d.ts.map +1 -0
- package/dist/two-d/presentation/index.js +2 -0
- package/dist/two-d/presentation/index.js.map +1 -0
- package/dist/two-d/ui/Bar.d.ts +3 -1
- package/dist/two-d/ui/Bar.d.ts.map +1 -1
- package/dist/two-d/ui/Bar.js +5 -0
- package/dist/two-d/ui/Bar.js.map +1 -1
- package/dist/two-d/ui/Button.d.ts +12 -0
- package/dist/two-d/ui/Button.d.ts.map +1 -1
- package/dist/two-d/ui/Button.js +16 -4
- package/dist/two-d/ui/Button.js.map +1 -1
- package/dist/two-d/ui/Window.d.ts +10 -0
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +17 -6
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +2 -0
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +16 -1
- package/sbom.cdx.json +6 -6
- package/tools/verify-scenarios.d.mts +15 -0
- package/tools/verify-scenarios.mjs +129 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type MwlSourceFile } from './compiler.ts';
|
|
2
|
+
export type PresentationScalarType = 'string' | 'number' | 'boolean';
|
|
3
|
+
export type PresentationValue = string | number | boolean;
|
|
4
|
+
export type PresentationItem = Readonly<Record<string, PresentationValue>>;
|
|
5
|
+
export interface PresentationCollection {
|
|
6
|
+
readonly type: 'items';
|
|
7
|
+
readonly fields: Readonly<Record<string, PresentationScalarType>>;
|
|
8
|
+
}
|
|
9
|
+
/** The game's TypeScript adapter declares these names and value types at build time. */
|
|
10
|
+
export interface PresentationManifest {
|
|
11
|
+
readonly values: Readonly<Record<string, PresentationScalarType | PresentationCollection>>;
|
|
12
|
+
readonly actions: readonly string[];
|
|
13
|
+
readonly adapters?: readonly string[];
|
|
14
|
+
readonly assets?: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
export type PresentationProperties = Readonly<Record<string, string>>;
|
|
17
|
+
export interface PresentationNode {
|
|
18
|
+
readonly kind: string;
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** Authored definition path, shared by every instance of a reusable component. */
|
|
21
|
+
readonly source: string;
|
|
22
|
+
readonly properties: PresentationProperties;
|
|
23
|
+
readonly states: Readonly<Record<string, PresentationProperties>>;
|
|
24
|
+
readonly children: readonly PresentationNode[];
|
|
25
|
+
}
|
|
26
|
+
export interface PresentationTheme {
|
|
27
|
+
readonly tokens: Readonly<Record<string, number>>;
|
|
28
|
+
readonly properties: PresentationProperties;
|
|
29
|
+
}
|
|
30
|
+
export interface PresentationContext {
|
|
31
|
+
readonly theme: string;
|
|
32
|
+
readonly tokens: Readonly<Record<string, number>>;
|
|
33
|
+
readonly overrides: Readonly<Record<string, PresentationProperties>>;
|
|
34
|
+
}
|
|
35
|
+
export interface PresentationScene {
|
|
36
|
+
readonly theme: string;
|
|
37
|
+
readonly children: readonly PresentationNode[];
|
|
38
|
+
}
|
|
39
|
+
export interface CompiledPresentation {
|
|
40
|
+
readonly scenes: Readonly<Record<string, PresentationScene>>;
|
|
41
|
+
readonly themes: Readonly<Record<string, PresentationTheme>>;
|
|
42
|
+
readonly contexts: Readonly<Record<string, PresentationContext>>;
|
|
43
|
+
readonly variants: Readonly<Record<string, PresentationProperties>>;
|
|
44
|
+
readonly manifest: PresentationManifest;
|
|
45
|
+
readonly ids: readonly string[];
|
|
46
|
+
readonly assets: readonly string[];
|
|
47
|
+
readonly messages: readonly string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Compiles optional scene/UI definitions, validating every reference against the game's manifest.
|
|
51
|
+
* Reusable components are expanded at build time; emitted data contains no parser or executable content.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { compilePresentation, emitPresentationModule } from '@datamoc/mw_games/mwl/presentation';
|
|
56
|
+
* const data = compilePresentation([], { values: {}, actions: [] });
|
|
57
|
+
* console.log(emitPresentationModule(data).startsWith('export const presentationData')); // true
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function compilePresentation(files: readonly MwlSourceFile[], manifest: PresentationManifest): CompiledPresentation;
|
|
61
|
+
/**
|
|
62
|
+
* Emits data and literal ID types for a game's build script to write alongside its other MWL artifacts.
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { compilePresentation, emitPresentationModule } from '@datamoc/mw_games/mwl/presentation';
|
|
66
|
+
* console.log(emitPresentationModule(compilePresentation([], { values: {}, actions: [] })));
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function emitPresentationModule(data: CompiledPresentation): string;
|
|
70
|
+
//# sourceMappingURL=presentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../src/mwl/presentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { compileSources } from './compiler.js';
|
|
2
|
+
import { schema10 } from './schema.js';
|
|
3
|
+
import { contrastRatio } from '../two-d/ui/contrast.js';
|
|
4
|
+
const styleAttributes = {
|
|
5
|
+
color_token: 'id',
|
|
6
|
+
background_token: 'id',
|
|
7
|
+
border_token: 'id',
|
|
8
|
+
width: 'number',
|
|
9
|
+
height: 'number',
|
|
10
|
+
gap: 'number',
|
|
11
|
+
padding: 'number',
|
|
12
|
+
alpha: 'number',
|
|
13
|
+
};
|
|
14
|
+
const commonAttributes = {
|
|
15
|
+
id: 'id',
|
|
16
|
+
...styleAttributes,
|
|
17
|
+
variant: 'id',
|
|
18
|
+
anchor: [
|
|
19
|
+
'top-left',
|
|
20
|
+
'top',
|
|
21
|
+
'top-right',
|
|
22
|
+
'left',
|
|
23
|
+
'center',
|
|
24
|
+
'right',
|
|
25
|
+
'bottom-left',
|
|
26
|
+
'bottom',
|
|
27
|
+
'bottom-right',
|
|
28
|
+
'fill',
|
|
29
|
+
],
|
|
30
|
+
x: 'number',
|
|
31
|
+
y: 'number',
|
|
32
|
+
visible: 'boolean',
|
|
33
|
+
visible_binding: 'string',
|
|
34
|
+
};
|
|
35
|
+
const uiTags = [
|
|
36
|
+
'ui_container',
|
|
37
|
+
'ui_row',
|
|
38
|
+
'ui_column',
|
|
39
|
+
'ui_grid',
|
|
40
|
+
'ui_label',
|
|
41
|
+
'ui_button',
|
|
42
|
+
'ui_bar',
|
|
43
|
+
'ui_window',
|
|
44
|
+
'ui_repeat',
|
|
45
|
+
'ui_mount',
|
|
46
|
+
'ui_adapter',
|
|
47
|
+
];
|
|
48
|
+
const children = [...uiTags, 'ui_state'];
|
|
49
|
+
const tree = { attributes: commonAttributes, required: ['id'], children };
|
|
50
|
+
const vocabulary = {
|
|
51
|
+
theme_definition: {
|
|
52
|
+
attributes: { id: 'id', font_family: 'string', font_size: 'number', padding: 'number', spacing: 'number' },
|
|
53
|
+
required: ['id'],
|
|
54
|
+
children: ['theme_token'],
|
|
55
|
+
},
|
|
56
|
+
theme_token: { attributes: { id: 'id', value: 'number' }, required: ['id', 'value'], children: [] },
|
|
57
|
+
presentation_context: {
|
|
58
|
+
attributes: { id: 'id', theme: 'id' },
|
|
59
|
+
required: ['id', 'theme'],
|
|
60
|
+
children: ['theme_token', 'ui_override'],
|
|
61
|
+
},
|
|
62
|
+
ui_override: {
|
|
63
|
+
attributes: { target: 'string', ...styleAttributes, image: 'string' },
|
|
64
|
+
required: ['target'],
|
|
65
|
+
children: [],
|
|
66
|
+
},
|
|
67
|
+
component_variant: { attributes: { id: 'id', ...styleAttributes }, required: ['id'], children: [] },
|
|
68
|
+
ui_component: { attributes: { id: 'id', items_binding: 'id' }, required: ['id'], children: uiTags },
|
|
69
|
+
scene_definition: {
|
|
70
|
+
attributes: { id: 'id', theme: 'id' },
|
|
71
|
+
required: ['id', 'theme'],
|
|
72
|
+
children: ['scene_layer', 'scene_camera', ...uiTags],
|
|
73
|
+
},
|
|
74
|
+
scene_layer: {
|
|
75
|
+
...tree,
|
|
76
|
+
attributes: { ...commonAttributes, space: ['world', 'screen'], adapter: 'id', image: 'string' },
|
|
77
|
+
},
|
|
78
|
+
scene_camera: {
|
|
79
|
+
attributes: { id: 'id', zoom: 'number', x: 'number', y: 'number', fit_width: 'number', fit_height: 'number' },
|
|
80
|
+
required: ['id'],
|
|
81
|
+
children: [],
|
|
82
|
+
},
|
|
83
|
+
ui_container: tree,
|
|
84
|
+
ui_row: { ...tree, attributes: { ...commonAttributes, wrap: 'boolean', align: ['start', 'center', 'end'] } },
|
|
85
|
+
ui_column: tree,
|
|
86
|
+
ui_grid: { ...tree, attributes: { ...commonAttributes, columns: 'integer' }, required: ['id', 'columns'] },
|
|
87
|
+
ui_label: {
|
|
88
|
+
...tree,
|
|
89
|
+
attributes: { ...commonAttributes, text: 'string', text_binding: 'string' },
|
|
90
|
+
children: ['ui_state'],
|
|
91
|
+
},
|
|
92
|
+
ui_button: {
|
|
93
|
+
...tree,
|
|
94
|
+
attributes: {
|
|
95
|
+
...commonAttributes,
|
|
96
|
+
text: 'string',
|
|
97
|
+
text_binding: 'string',
|
|
98
|
+
action: 'id',
|
|
99
|
+
selected_binding: 'string',
|
|
100
|
+
disabled_binding: 'string',
|
|
101
|
+
},
|
|
102
|
+
children: ['ui_state'],
|
|
103
|
+
},
|
|
104
|
+
ui_bar: {
|
|
105
|
+
...tree,
|
|
106
|
+
attributes: {
|
|
107
|
+
...commonAttributes,
|
|
108
|
+
value: 'number',
|
|
109
|
+
max: 'number',
|
|
110
|
+
value_binding: 'string',
|
|
111
|
+
max_binding: 'string',
|
|
112
|
+
color_binding: 'string',
|
|
113
|
+
},
|
|
114
|
+
children: ['ui_state'],
|
|
115
|
+
},
|
|
116
|
+
ui_window: {
|
|
117
|
+
...tree,
|
|
118
|
+
attributes: {
|
|
119
|
+
...commonAttributes,
|
|
120
|
+
anchor: ['center', 'top', 'bottom'],
|
|
121
|
+
title: 'string',
|
|
122
|
+
title_binding: 'string',
|
|
123
|
+
modal: 'boolean',
|
|
124
|
+
closable: 'boolean',
|
|
125
|
+
close_action: 'id',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
ui_repeat: {
|
|
129
|
+
...tree,
|
|
130
|
+
attributes: { ...commonAttributes, items_binding: 'id', key: 'id' },
|
|
131
|
+
required: ['id', 'items_binding', 'key'],
|
|
132
|
+
},
|
|
133
|
+
ui_mount: {
|
|
134
|
+
...tree,
|
|
135
|
+
attributes: { ...commonAttributes, component: 'id' },
|
|
136
|
+
required: ['id', 'component'],
|
|
137
|
+
children: [],
|
|
138
|
+
},
|
|
139
|
+
ui_adapter: {
|
|
140
|
+
...tree,
|
|
141
|
+
attributes: { ...commonAttributes, adapter: 'id', image: 'string' },
|
|
142
|
+
required: ['id', 'adapter'],
|
|
143
|
+
children: [],
|
|
144
|
+
},
|
|
145
|
+
ui_state: {
|
|
146
|
+
attributes: { state: ['idle', 'hover', 'pressed', 'disabled', 'selected', 'focused'], ...styleAttributes },
|
|
147
|
+
required: ['state'],
|
|
148
|
+
children: [],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
const bindingTypes = {
|
|
152
|
+
text_binding: 'string',
|
|
153
|
+
title_binding: 'string',
|
|
154
|
+
value_binding: 'number',
|
|
155
|
+
max_binding: 'number',
|
|
156
|
+
color_binding: 'number',
|
|
157
|
+
visible_binding: 'boolean',
|
|
158
|
+
selected_binding: 'boolean',
|
|
159
|
+
disabled_binding: 'boolean',
|
|
160
|
+
};
|
|
161
|
+
const semanticTokens = ['panel', 'text', 'accent', 'success', 'warning', 'danger', 'selection'];
|
|
162
|
+
/**
|
|
163
|
+
* Compiles optional scene/UI definitions, validating every reference against the game's manifest.
|
|
164
|
+
* Reusable components are expanded at build time; emitted data contains no parser or executable content.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* import { compilePresentation, emitPresentationModule } from '@datamoc/mw_games/mwl/presentation';
|
|
169
|
+
* const data = compilePresentation([], { values: {}, actions: [] });
|
|
170
|
+
* console.log(emitPresentationModule(data).startsWith('export const presentationData')); // true
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export function compilePresentation(files, manifest) {
|
|
174
|
+
const game = compileSources(files, { schemas: { ...schema10, ...vocabulary } });
|
|
175
|
+
const roots = game.roots;
|
|
176
|
+
const definitions = new Map();
|
|
177
|
+
const sources = new Map();
|
|
178
|
+
const mountedComponents = new Set();
|
|
179
|
+
const tokenUses = [];
|
|
180
|
+
const fail = (node, message) => {
|
|
181
|
+
const location = node.location;
|
|
182
|
+
throw new Error(`${location?.file ?? '<presentation>'}:${location?.line ?? 1}:${location?.column ?? 1}: ${message}`);
|
|
183
|
+
};
|
|
184
|
+
const keyOf = (tag, id) => `${tag}:${id}`;
|
|
185
|
+
for (const node of roots) {
|
|
186
|
+
if (node.attributes.id === '__proto__')
|
|
187
|
+
fail(node, 'reserved definition id "__proto__"');
|
|
188
|
+
if (![
|
|
189
|
+
'theme_definition',
|
|
190
|
+
'presentation_context',
|
|
191
|
+
'component_variant',
|
|
192
|
+
'ui_component',
|
|
193
|
+
'scene_definition',
|
|
194
|
+
].includes(node.tag))
|
|
195
|
+
continue;
|
|
196
|
+
const key = keyOf(node.tag, node.attributes.id);
|
|
197
|
+
if (definitions.has(key))
|
|
198
|
+
fail(node, `duplicate ${key}`);
|
|
199
|
+
definitions.set(key, node);
|
|
200
|
+
}
|
|
201
|
+
const find = (node, tag, id) => definitions.get(keyOf(tag, id)) ?? fail(node, `unknown ${tag} "${id}"`);
|
|
202
|
+
const props = (node, excluded = ['id']) => Object.fromEntries(Object.entries(node.attributes).filter(([key]) => !excluded.includes(key)));
|
|
203
|
+
const validateStyle = (node) => {
|
|
204
|
+
if (node.attributes.image && !manifest.assets?.includes(node.attributes.image))
|
|
205
|
+
fail(node, `unknown asset "${node.attributes.image}"`);
|
|
206
|
+
for (const [name, value] of Object.entries(node.attributes)) {
|
|
207
|
+
if (name.endsWith('_token'))
|
|
208
|
+
tokenUses.push({ node, token: value });
|
|
209
|
+
if (['width', 'height', 'gap', 'padding'].includes(name) && Number(value) < 0)
|
|
210
|
+
fail(node, `${name} must be nonnegative`);
|
|
211
|
+
if (name === 'alpha' && (Number(value) < 0 || Number(value) > 1))
|
|
212
|
+
fail(node, 'alpha must be between 0 and 1');
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const readTokens = (node) => {
|
|
216
|
+
const tokens = Object.create(null);
|
|
217
|
+
for (const child of node.children.filter((child) => child.tag === 'theme_token')) {
|
|
218
|
+
const { id, value } = child.attributes;
|
|
219
|
+
if (id === '__proto__')
|
|
220
|
+
fail(child, 'reserved token id "__proto__"');
|
|
221
|
+
const color = Number(value);
|
|
222
|
+
if (Object.hasOwn(tokens, id))
|
|
223
|
+
fail(child, `duplicate theme token "${id}"`);
|
|
224
|
+
if (!Number.isInteger(color) || color < 0 || color > 0xffffff)
|
|
225
|
+
fail(child, `token "${id}" must be a 24-bit color`);
|
|
226
|
+
tokens[id] = color;
|
|
227
|
+
}
|
|
228
|
+
return tokens;
|
|
229
|
+
};
|
|
230
|
+
const themes = Object.create(null);
|
|
231
|
+
const contexts = Object.create(null);
|
|
232
|
+
const variants = Object.create(null);
|
|
233
|
+
const scenes = Object.create(null);
|
|
234
|
+
for (const node of roots) {
|
|
235
|
+
const id = node.attributes.id;
|
|
236
|
+
if (node.tag === 'theme_definition') {
|
|
237
|
+
validateStyle(node);
|
|
238
|
+
if (node.attributes.font_size !== undefined && Number(node.attributes.font_size) <= 0)
|
|
239
|
+
fail(node, 'font_size must be positive');
|
|
240
|
+
const tokens = readTokens(node);
|
|
241
|
+
for (const token of semanticTokens)
|
|
242
|
+
if (!Object.hasOwn(tokens, token))
|
|
243
|
+
fail(node, `missing semantic token "${token}"`);
|
|
244
|
+
themes[id] = { tokens, properties: props(node) };
|
|
245
|
+
}
|
|
246
|
+
else if (node.tag === 'component_variant') {
|
|
247
|
+
validateStyle(node);
|
|
248
|
+
variants[id] = props(node);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const buildTree = (nodes, prefix, fields, stack = []) => {
|
|
252
|
+
const siblings = new Set();
|
|
253
|
+
return nodes
|
|
254
|
+
.filter((node) => node.tag !== 'ui_state')
|
|
255
|
+
.map((node) => {
|
|
256
|
+
const id = node.attributes.id;
|
|
257
|
+
if (!id || siblings.has(id))
|
|
258
|
+
fail(node, `duplicate or missing component id "${id}" in ${prefix}`);
|
|
259
|
+
siblings.add(id);
|
|
260
|
+
const source = `${prefix}/${id}`;
|
|
261
|
+
sources.set(source, node);
|
|
262
|
+
validateStyle(node);
|
|
263
|
+
const attributes = node.attributes;
|
|
264
|
+
if (attributes.variant)
|
|
265
|
+
find(node, 'component_variant', attributes.variant);
|
|
266
|
+
for (const name of ['action', 'close_action'])
|
|
267
|
+
if (attributes[name] && !manifest.actions.includes(attributes[name]))
|
|
268
|
+
fail(node, `unknown action "${attributes[name]}"`);
|
|
269
|
+
if (attributes.adapter && !manifest.adapters?.includes(attributes.adapter))
|
|
270
|
+
fail(node, `unknown adapter "${attributes.adapter}"`);
|
|
271
|
+
for (const [name, expected] of Object.entries(bindingTypes)) {
|
|
272
|
+
const binding = attributes[name];
|
|
273
|
+
if (!binding)
|
|
274
|
+
continue;
|
|
275
|
+
const actual = binding.startsWith('item.') ? fields?.[binding.slice(5)] : manifest.values[binding];
|
|
276
|
+
if (actual !== expected)
|
|
277
|
+
fail(node, `binding "${binding}" for ${name} must be ${expected}`);
|
|
278
|
+
}
|
|
279
|
+
const states = Object.create(null);
|
|
280
|
+
for (const state of node.children.filter((child) => child.tag === 'ui_state')) {
|
|
281
|
+
if (Object.hasOwn(states, state.attributes.state))
|
|
282
|
+
fail(state, `duplicate component state "${state.attributes.state}"`);
|
|
283
|
+
validateStyle(state);
|
|
284
|
+
states[state.attributes.state] = props(state, ['state']);
|
|
285
|
+
}
|
|
286
|
+
let childNodes;
|
|
287
|
+
if (node.tag === 'ui_mount') {
|
|
288
|
+
const name = attributes.component;
|
|
289
|
+
if (stack.includes(name))
|
|
290
|
+
fail(node, `component cycle: ${[...stack, name].join(' -> ')}`);
|
|
291
|
+
mountedComponents.add(name);
|
|
292
|
+
const component = find(node, 'ui_component', name);
|
|
293
|
+
childNodes = buildTree(component.children, `component:${name}`, fields, [...stack, name]);
|
|
294
|
+
}
|
|
295
|
+
else if (node.tag === 'ui_repeat') {
|
|
296
|
+
const collection = manifest.values[attributes.items_binding];
|
|
297
|
+
if (!collection || typeof collection !== 'object' || collection.type !== 'items')
|
|
298
|
+
fail(node, `unknown collection "${attributes.items_binding}"`);
|
|
299
|
+
const itemFields = collection.fields;
|
|
300
|
+
if (!['string', 'number'].includes(itemFields[attributes.key]))
|
|
301
|
+
fail(node, `repeat key "${attributes.key}" must be a string or number field`);
|
|
302
|
+
if (node.children.filter((child) => child.tag !== 'ui_state').length !== 1)
|
|
303
|
+
fail(node, 'ui_repeat needs exactly one template child');
|
|
304
|
+
childNodes = buildTree(node.children, source, itemFields, stack);
|
|
305
|
+
}
|
|
306
|
+
else
|
|
307
|
+
childNodes = buildTree(node.children, source, fields, stack);
|
|
308
|
+
if (node.tag === 'ui_grid' && Number(attributes.columns) < 1)
|
|
309
|
+
fail(node, 'grid columns must be positive');
|
|
310
|
+
if (node.tag === 'scene_camera') {
|
|
311
|
+
if (attributes.zoom !== undefined && Number(attributes.zoom) <= 0)
|
|
312
|
+
fail(node, 'camera zoom must be positive');
|
|
313
|
+
if (Boolean(attributes.fit_width) !== Boolean(attributes.fit_height))
|
|
314
|
+
fail(node, 'camera fit needs width and height');
|
|
315
|
+
if (attributes.fit_width &&
|
|
316
|
+
(Number(attributes.fit_width) <= 0 || Number(attributes.fit_height) <= 0))
|
|
317
|
+
fail(node, 'camera fit dimensions must be positive');
|
|
318
|
+
}
|
|
319
|
+
return { kind: node.tag, id, source, properties: props(node), states, children: childNodes };
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
function componentFields(node) {
|
|
323
|
+
if (!node.attributes.items_binding)
|
|
324
|
+
return undefined;
|
|
325
|
+
const collection = manifest.values[node.attributes.items_binding];
|
|
326
|
+
if (typeof collection !== 'object' || collection.type !== 'items')
|
|
327
|
+
fail(node, `unknown collection "${node.attributes.items_binding}"`);
|
|
328
|
+
return collection.fields;
|
|
329
|
+
}
|
|
330
|
+
for (const node of roots.filter((node) => node.tag === 'scene_definition')) {
|
|
331
|
+
find(node, 'theme_definition', node.attributes.theme);
|
|
332
|
+
if (node.children.filter((child) => child.tag === 'scene_camera').length > 1)
|
|
333
|
+
fail(node, 'a scene can have only one camera');
|
|
334
|
+
scenes[node.attributes.id] = {
|
|
335
|
+
theme: node.attributes.theme,
|
|
336
|
+
children: buildTree(node.children, `scene:${node.attributes.id}`),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
// Validate unused reusable definitions too; an unmounted typo must not escape the build.
|
|
340
|
+
for (const node of roots.filter((node) => node.tag === 'ui_component')) {
|
|
341
|
+
if (!mountedComponents.has(node.attributes.id))
|
|
342
|
+
buildTree(node.children, `component:${node.attributes.id}`, componentFields(node), [node.attributes.id]);
|
|
343
|
+
}
|
|
344
|
+
for (const node of roots.filter((node) => node.tag === 'presentation_context')) {
|
|
345
|
+
find(node, 'theme_definition', node.attributes.theme);
|
|
346
|
+
const overrides = Object.create(null);
|
|
347
|
+
for (const override of node.children.filter((child) => child.tag === 'ui_override')) {
|
|
348
|
+
const target = override.attributes.target;
|
|
349
|
+
if (!sources.has(target))
|
|
350
|
+
fail(override, `unknown override target "${target}"`);
|
|
351
|
+
if (override.attributes.image && !['scene_layer', 'ui_adapter'].includes(sources.get(target).tag))
|
|
352
|
+
fail(override, 'image overrides require a scene layer or adapter');
|
|
353
|
+
if (Object.hasOwn(overrides, target))
|
|
354
|
+
fail(override, `duplicate override target "${target}"`);
|
|
355
|
+
validateStyle(override);
|
|
356
|
+
overrides[target] = props(override, ['target']);
|
|
357
|
+
}
|
|
358
|
+
const tokens = readTokens(node);
|
|
359
|
+
for (const token of Object.keys(tokens))
|
|
360
|
+
if (!Object.hasOwn(themes[node.attributes.theme].tokens, token))
|
|
361
|
+
fail(node, `unknown context token "${token}"`);
|
|
362
|
+
contexts[node.attributes.id] = { theme: node.attributes.theme, tokens, overrides };
|
|
363
|
+
}
|
|
364
|
+
const checkPalette = (node, tokens) => {
|
|
365
|
+
for (const use of tokenUses)
|
|
366
|
+
if (!Object.hasOwn(tokens, use.token))
|
|
367
|
+
fail(use.node, `unknown theme token "${use.token}" in ${node.attributes.id}`);
|
|
368
|
+
if (contrastRatio(tokens.text, tokens.panel) < 4.5)
|
|
369
|
+
fail(node, 'text/panel contrast must reach 4.5');
|
|
370
|
+
for (const token of ['danger', 'selection'])
|
|
371
|
+
if (contrastRatio(tokens[token], tokens.panel) < 3)
|
|
372
|
+
fail(node, `${token}/panel contrast must reach 3`);
|
|
373
|
+
};
|
|
374
|
+
for (const node of roots.filter((node) => node.tag === 'theme_definition'))
|
|
375
|
+
checkPalette(node, themes[node.attributes.id].tokens);
|
|
376
|
+
for (const node of roots.filter((node) => node.tag === 'presentation_context')) {
|
|
377
|
+
const context = contexts[node.attributes.id];
|
|
378
|
+
checkPalette(node, { ...themes[context.theme].tokens, ...context.tokens });
|
|
379
|
+
}
|
|
380
|
+
const ids = [];
|
|
381
|
+
const collect = (nodes, prefix) => {
|
|
382
|
+
for (const node of nodes) {
|
|
383
|
+
const path = `${prefix}/${node.id}`;
|
|
384
|
+
ids.push(path);
|
|
385
|
+
collect(node.children, node.kind === 'ui_repeat' ? `${path}/*` : path);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
for (const [id, scene] of Object.entries(scenes))
|
|
389
|
+
collect(scene.children, id);
|
|
390
|
+
return {
|
|
391
|
+
scenes,
|
|
392
|
+
themes,
|
|
393
|
+
contexts,
|
|
394
|
+
variants,
|
|
395
|
+
manifest,
|
|
396
|
+
ids: ids.sort(),
|
|
397
|
+
assets: game.assets,
|
|
398
|
+
messages: game.messages,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Emits data and literal ID types for a game's build script to write alongside its other MWL artifacts.
|
|
403
|
+
* @example
|
|
404
|
+
* ```ts
|
|
405
|
+
* import { compilePresentation, emitPresentationModule } from '@datamoc/mw_games/mwl/presentation';
|
|
406
|
+
* console.log(emitPresentationModule(compilePresentation([], { values: {}, actions: [] })));
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
export function emitPresentationModule(data) {
|
|
410
|
+
return `export const presentationData = ${JSON.stringify(data, null, '\t')} as const;\ntype ExpandRepeat<S extends string> = S extends \`\${infer Prefix}/*/\${infer Rest}\` ? \`\${Prefix}/\${string}/\${ExpandRepeat<Rest>}\` : S;\nexport type PresentationId = ExpandRepeat<typeof presentationData.ids[number]>;\nexport type PresentationSceneId = keyof typeof presentationData.scenes;\n`;
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=presentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.js","sourceRoot":"","sources":["../../src/mwl/presentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Container } from 'pixi.js';
|
|
2
|
+
import { Camera } from '../render/Camera.ts';
|
|
3
|
+
import { WindowStack } from '../ui/WindowStack.ts';
|
|
4
|
+
import type { CompiledPresentation, PresentationItem, PresentationProperties, PresentationValue } from '../../mwl/presentation.ts';
|
|
5
|
+
export type PresentationState = Readonly<Record<string, PresentationValue | readonly PresentationItem[]>>;
|
|
6
|
+
export interface PresentationAdapterContext {
|
|
7
|
+
readonly tokens: Readonly<Record<string, number>>;
|
|
8
|
+
readonly properties: PresentationProperties;
|
|
9
|
+
}
|
|
10
|
+
/** Runtime owns and destroys `view`; destroy detaches adapter-owned subscriptions/resources. */
|
|
11
|
+
export interface PresentationAdapter {
|
|
12
|
+
readonly view: Container;
|
|
13
|
+
update?(dt: number, state: PresentationState): void;
|
|
14
|
+
resize?(width: number, height: number): void;
|
|
15
|
+
restyle?(context: PresentationAdapterContext): void;
|
|
16
|
+
destroy?(): void;
|
|
17
|
+
}
|
|
18
|
+
export interface PresentationRuntimeOptions {
|
|
19
|
+
readonly parent: Container;
|
|
20
|
+
readonly state: () => PresentationState;
|
|
21
|
+
readonly actions: Readonly<Record<string, (item?: PresentationItem) => void>>;
|
|
22
|
+
readonly adapters?: Readonly<Record<string, (context: PresentationAdapterContext) => PresentationAdapter>>;
|
|
23
|
+
readonly translate?: (message: string) => string;
|
|
24
|
+
/** Optional external notification; returned disposer is called at destruction. */
|
|
25
|
+
readonly subscribe?: (refresh: () => void) => () => void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Instantiates compiled MWL presentation using existing Pixi widgets. The controller owns state
|
|
29
|
+
* and actions; context switches restyle the same views without rebuilding procedural adapters.
|
|
30
|
+
* Kept off the root barrel so a game pays for this runtime only when it imports the subpath.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { MwlPresentation } from '@datamoc/mw_games/two-d/presentation';
|
|
35
|
+
* import type { CompiledPresentation } from '@datamoc/mw_games/mwl/presentation';
|
|
36
|
+
* import { Node2D } from '@datamoc/mw_games/two-d/render';
|
|
37
|
+
* declare const data: CompiledPresentation;
|
|
38
|
+
* const ui = new MwlPresentation(data, 'game', { parent: new Node2D(), state: () => ({}), actions: {} });
|
|
39
|
+
* ui.resize(800, 600);
|
|
40
|
+
* ui.update(1 / 60);
|
|
41
|
+
* ui.destroy();
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class MwlPresentation<Id extends string = string> {
|
|
45
|
+
private readonly data;
|
|
46
|
+
private readonly options;
|
|
47
|
+
readonly root: Container<import("pixi.js").ContainerChild>;
|
|
48
|
+
readonly windows: WindowStack;
|
|
49
|
+
readonly camera: Camera;
|
|
50
|
+
private readonly nodes;
|
|
51
|
+
private readonly roots;
|
|
52
|
+
private readonly baseTheme;
|
|
53
|
+
private readonly cameraProperties;
|
|
54
|
+
private readonly cameraPath;
|
|
55
|
+
private readonly previousTheme;
|
|
56
|
+
private appliedTheme;
|
|
57
|
+
private context;
|
|
58
|
+
private tokens;
|
|
59
|
+
private viewport;
|
|
60
|
+
private focused;
|
|
61
|
+
private destroyed;
|
|
62
|
+
private unsubscribe?;
|
|
63
|
+
private state;
|
|
64
|
+
private readonly inputListener;
|
|
65
|
+
constructor(data: CompiledPresentation, sceneId: string, options: PresentationRuntimeOptions);
|
|
66
|
+
/** Looks up an instance by its compiled path; repeats add their stable key to the path. */
|
|
67
|
+
get(id: Id): Container | null;
|
|
68
|
+
get focusId(): string | null;
|
|
69
|
+
get activeContext(): string;
|
|
70
|
+
get palette(): Readonly<Record<string, number>>;
|
|
71
|
+
setContext(context?: string): void;
|
|
72
|
+
private applyTheme;
|
|
73
|
+
update(dt?: number): void;
|
|
74
|
+
resize(width: number, height: number): void;
|
|
75
|
+
private createRecord;
|
|
76
|
+
private read;
|
|
77
|
+
private coerce;
|
|
78
|
+
private resolveProperties;
|
|
79
|
+
private refresh;
|
|
80
|
+
private mount;
|
|
81
|
+
private reconcile;
|
|
82
|
+
private token;
|
|
83
|
+
private applyProperties;
|
|
84
|
+
private layout;
|
|
85
|
+
private layoutNode;
|
|
86
|
+
private invoke;
|
|
87
|
+
private isFocusable;
|
|
88
|
+
private focusable;
|
|
89
|
+
private setFocus;
|
|
90
|
+
private navigate;
|
|
91
|
+
/** Offers modal windows input first, then the screen-space buttons. */
|
|
92
|
+
handleAction(action: string): boolean;
|
|
93
|
+
private unmount;
|
|
94
|
+
private dispose;
|
|
95
|
+
private assertAlive;
|
|
96
|
+
destroy(): void;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=MwlPresentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MwlPresentation.d.ts","sourceRoot":"","sources":["../../../src/two-d/presentation/MwlPresentation.ts"],"names":[],"mappings":"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"}
|