Skip to content

Commit 623eccf

Browse files
author
DavidQ
committed
Wire games->Workspace tool roundtrip presets via metadata so tool links load preset content (samplePresetPath/sampleId) instead of opening blank defaults.
1 parent c7ed023 commit 623eccf

4 files changed

Lines changed: 283 additions & 13 deletions

File tree

games/index.render.js

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ function escapeHtml(value) {
5252
.replaceAll("'", "'");
5353
}
5454

55-
function toStandaloneToolHref(entryPoint) {
56-
const normalized = String(entryPoint || "").replace(/^\.?\/*/, "");
57-
return normalized ? `/tools/${encodeURI(normalized)}` : "";
58-
}
59-
6055
function normalizeGameHref(value) {
6156
const href = normalize(value).replace(/\\/g, "/");
6257
if (!href || href.includes("..") || !href.startsWith("/games/")) {
@@ -65,6 +60,45 @@ function normalizeGameHref(value) {
6560
return href;
6661
}
6762

63+
function normalizePresetPath(value) {
64+
const normalized = normalize(value).replace(/\\/g, "/");
65+
if (!normalized || normalized.includes("..")) {
66+
return "";
67+
}
68+
if (normalized.startsWith("/samples/")) {
69+
return normalized;
70+
}
71+
if (normalized.startsWith("samples/")) {
72+
return `/${normalized}`;
73+
}
74+
if (normalized.startsWith("./samples/")) {
75+
return `/${normalized.slice(2)}`;
76+
}
77+
return "";
78+
}
79+
80+
function getExplicitRoundtripPresetPath(game, toolId) {
81+
const safeToolId = normalizeToken(toolId);
82+
if (!safeToolId) {
83+
return "";
84+
}
85+
const mappedEntries = asArray(game?.roundtripToolPresets);
86+
for (const entry of mappedEntries) {
87+
if (!entry || typeof entry !== "object") {
88+
continue;
89+
}
90+
const mappedToolId = normalizeToken(entry.toolId);
91+
if (mappedToolId !== safeToolId) {
92+
continue;
93+
}
94+
const presetPath = normalizePresetPath(entry.presetPath);
95+
if (presetPath) {
96+
return presetPath;
97+
}
98+
}
99+
return "";
100+
}
101+
68102
function buildWorkspaceManagerHref(gameId) {
69103
const normalizedGameId = normalize(gameId);
70104
return normalizedGameId
@@ -103,21 +137,27 @@ function buildRoundtripLinks(game, toolRegistryMap) {
103137
if (!tool) {
104138
return;
105139
}
106-
const baseHref = toStandaloneToolHref(tool.entryPoint);
107-
if (!baseHref) {
108-
return;
109-
}
140+
const workspaceHref = "/tools/Workspace%20Manager/index.html";
110141
const query = new URLSearchParams();
142+
query.set("tool", tool.id);
111143
query.set("gameId", game.id);
112144
if (game.title) {
113145
query.set("gameTitle", game.title);
114146
}
115147
if (game.href) {
116148
query.set("gameHref", game.href);
117149
}
150+
const presetPath = getExplicitRoundtripPresetPath(game, tool.id);
151+
if (presetPath) {
152+
query.set("samplePresetPath", presetPath);
153+
const sampleIdMatch = /sample-(\d{4})-[^.]+\.json$/i.exec(presetPath);
154+
if (sampleIdMatch?.[1]) {
155+
query.set("sampleId", sampleIdMatch[1]);
156+
}
157+
}
118158
query.set("workspaceHref", buildWorkspaceManagerHref(game.id));
119159
query.set("returnTo", buildReturnHref(tool.id));
120-
const href = `${baseHref}?${query.toString()}`;
160+
const href = `${workspaceHref}?${query.toString()}`;
121161
const label = `Open ${normalize(tool.displayName) || normalize(tool.name) || toolId}`;
122162
links.push({ toolId, href, label });
123163
});
@@ -177,7 +217,8 @@ function buildRows(metadata, pinnedSet, toolLabelMap, toolRegistryMap) {
177217
id,
178218
title,
179219
href,
180-
toolHints: game?.toolHints
220+
toolHints: game?.toolHints,
221+
roundtripToolPresets: game?.roundtripToolPresets
181222
}, toolRegistryMap);
182223
return {
183224
id,

games/metadata/games.index.metadata.json

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@
2424
"physics-sandbox",
2525
"state-inspector",
2626
"replay-visualizer"
27+
],
28+
"roundtripToolPresets": [
29+
{
30+
"toolId": "physics-sandbox",
31+
"presetPath": "/samples/phase-03/0303/sample-0303-physics-sandbox.json"
32+
},
33+
{
34+
"toolId": "state-inspector",
35+
"presetPath": "/samples/phase-02/0205/sample-0205-state-inspector.json"
36+
},
37+
{
38+
"toolId": "replay-visualizer",
39+
"presetPath": "/samples/phase-07/0708/sample-0708-replay-visualizer.json"
40+
}
2741
]
2842
},
2943
{
@@ -49,6 +63,20 @@
4963
"sprite-editor",
5064
"tile-map-editor",
5165
"replay-visualizer"
66+
],
67+
"roundtripToolPresets": [
68+
{
69+
"toolId": "sprite-editor",
70+
"presetPath": "/samples/phase-14/1414/sample-1414-sprite-editor.json"
71+
},
72+
{
73+
"toolId": "tile-map-editor",
74+
"presetPath": "/samples/phase-12/1208/sample-1208-tile-map-editor.json"
75+
},
76+
{
77+
"toolId": "replay-visualizer",
78+
"presetPath": "/samples/phase-07/0708/sample-0708-replay-visualizer.json"
79+
}
5280
]
5381
},
5482
{
@@ -74,6 +102,20 @@
74102
"physics-sandbox",
75103
"performance-profiler",
76104
"state-inspector"
105+
],
106+
"roundtripToolPresets": [
107+
{
108+
"toolId": "physics-sandbox",
109+
"presetPath": "/samples/phase-03/0303/sample-0303-physics-sandbox.json"
110+
},
111+
{
112+
"toolId": "performance-profiler",
113+
"presetPath": "/samples/phase-13/1319/sample-1319-performance-profiler.json"
114+
},
115+
{
116+
"toolId": "state-inspector",
117+
"presetPath": "/samples/phase-02/0205/sample-0205-state-inspector.json"
118+
}
77119
]
78120
},
79121
{
@@ -99,6 +141,20 @@
99141
"vector-asset-studio",
100142
"vector-map-editor",
101143
"physics-sandbox"
144+
],
145+
"roundtripToolPresets": [
146+
{
147+
"toolId": "vector-asset-studio",
148+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-asset-studio.json"
149+
},
150+
{
151+
"toolId": "vector-map-editor",
152+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-map-editor.json"
153+
},
154+
{
155+
"toolId": "physics-sandbox",
156+
"presetPath": "/samples/phase-03/0303/sample-0303-physics-sandbox.json"
157+
}
102158
]
103159
},
104160
{
@@ -124,6 +180,20 @@
124180
"sprite-editor",
125181
"tile-map-editor",
126182
"replay-visualizer"
183+
],
184+
"roundtripToolPresets": [
185+
{
186+
"toolId": "sprite-editor",
187+
"presetPath": "/samples/phase-14/1414/sample-1414-sprite-editor.json"
188+
},
189+
{
190+
"toolId": "tile-map-editor",
191+
"presetPath": "/samples/phase-12/1208/sample-1208-tile-map-editor.json"
192+
},
193+
{
194+
"toolId": "replay-visualizer",
195+
"presetPath": "/samples/phase-07/0708/sample-0708-replay-visualizer.json"
196+
}
127197
]
128198
},
129199
{
@@ -149,6 +219,20 @@
149219
"vector-asset-studio",
150220
"vector-map-editor",
151221
"asset-pipeline-tool"
222+
],
223+
"roundtripToolPresets": [
224+
{
225+
"toolId": "vector-asset-studio",
226+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-asset-studio.json"
227+
},
228+
{
229+
"toolId": "vector-map-editor",
230+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-map-editor.json"
231+
},
232+
{
233+
"toolId": "asset-pipeline-tool",
234+
"presetPath": "/samples/phase-14/1413/sample-1413-asset-pipeline-tool.json"
235+
}
152236
]
153237
},
154238
{
@@ -174,6 +258,20 @@
174258
"sprite-editor",
175259
"tile-map-editor",
176260
"asset-pipeline-tool"
261+
],
262+
"roundtripToolPresets": [
263+
{
264+
"toolId": "sprite-editor",
265+
"presetPath": "/samples/phase-14/1414/sample-1414-sprite-editor.json"
266+
},
267+
{
268+
"toolId": "tile-map-editor",
269+
"presetPath": "/samples/phase-12/1208/sample-1208-tile-map-editor.json"
270+
},
271+
{
272+
"toolId": "asset-pipeline-tool",
273+
"presetPath": "/samples/phase-14/1413/sample-1413-asset-pipeline-tool.json"
274+
}
177275
]
178276
},
179277
{
@@ -199,6 +297,20 @@
199297
"vector-asset-studio",
200298
"replay-visualizer",
201299
"state-inspector"
300+
],
301+
"roundtripToolPresets": [
302+
{
303+
"toolId": "vector-asset-studio",
304+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-asset-studio.json"
305+
},
306+
{
307+
"toolId": "replay-visualizer",
308+
"presetPath": "/samples/phase-07/0708/sample-0708-replay-visualizer.json"
309+
},
310+
{
311+
"toolId": "state-inspector",
312+
"presetPath": "/samples/phase-02/0205/sample-0205-state-inspector.json"
313+
}
202314
]
203315
},
204316
{
@@ -224,6 +336,20 @@
224336
"state-inspector",
225337
"replay-visualizer",
226338
"performance-profiler"
339+
],
340+
"roundtripToolPresets": [
341+
{
342+
"toolId": "state-inspector",
343+
"presetPath": "/samples/phase-02/0205/sample-0205-state-inspector.json"
344+
},
345+
{
346+
"toolId": "replay-visualizer",
347+
"presetPath": "/samples/phase-07/0708/sample-0708-replay-visualizer.json"
348+
},
349+
{
350+
"toolId": "performance-profiler",
351+
"presetPath": "/samples/phase-13/1319/sample-1319-performance-profiler.json"
352+
}
227353
]
228354
},
229355
{
@@ -249,6 +375,20 @@
249375
"tile-map-editor",
250376
"sprite-editor",
251377
"state-inspector"
378+
],
379+
"roundtripToolPresets": [
380+
{
381+
"toolId": "tile-map-editor",
382+
"presetPath": "/samples/phase-12/1208/sample-1208-tile-map-editor.json"
383+
},
384+
{
385+
"toolId": "sprite-editor",
386+
"presetPath": "/samples/phase-14/1414/sample-1414-sprite-editor.json"
387+
},
388+
{
389+
"toolId": "state-inspector",
390+
"presetPath": "/samples/phase-02/0205/sample-0205-state-inspector.json"
391+
}
252392
]
253393
},
254394
{
@@ -274,6 +414,20 @@
274414
"vector-asset-studio",
275415
"vector-map-editor",
276416
"tile-map-editor"
417+
],
418+
"roundtripToolPresets": [
419+
{
420+
"toolId": "vector-asset-studio",
421+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-asset-studio.json"
422+
},
423+
{
424+
"toolId": "vector-map-editor",
425+
"presetPath": "/samples/phase-09/0901/sample-0901-vector-map-editor.json"
426+
},
427+
{
428+
"toolId": "tile-map-editor",
429+
"presetPath": "/samples/phase-12/1208/sample-1208-tile-map-editor.json"
430+
}
277431
]
278432
},
279433
{

0 commit comments

Comments
 (0)