Skip to content

Commit e589f80

Browse files
author
DavidQ
committed
Move Solar skin contract out of shared gameSkinLoader into games/SolarSystem and delegate Solar validation/legacy mapping through solarSkinContract.
1 parent ea5d2b8 commit e589f80

2 files changed

Lines changed: 131 additions & 101 deletions

File tree

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
function toObject(value) {
2+
return value && typeof value === "object" ? value : {};
3+
}
4+
5+
function normalizeText(value) {
6+
return typeof value === "string" ? value.trim() : "";
7+
}
8+
9+
const PLANET_IDS = Object.freeze([
10+
"mercury",
11+
"venus",
12+
"earth",
13+
"mars",
14+
"jupiter",
15+
"saturn",
16+
"uranus",
17+
"neptune"
18+
]);
19+
20+
const MOON_IDS = Object.freeze(["moon", "io", "europa", "ganymede", "titan"]);
21+
const RING_IDS = Object.freeze(["jupiter", "saturn", "uranus", "neptune"]);
22+
23+
const RING_KEY_BY_PLANET = Object.freeze({
24+
jupiter: "ringJupiter",
25+
saturn: "ringSaturn",
26+
uranus: "ringUranus",
27+
neptune: "ringNeptune"
28+
});
29+
30+
export function validateSolarSystemSkinObjects(source, helpers = {}) {
31+
const hasExpectedShape = typeof helpers.hasExpectedShape === "function" ? helpers.hasExpectedShape : () => false;
32+
const isHexColor = typeof helpers.isHexColor === "function" ? helpers.isHexColor : () => false;
33+
const isPositiveNumber = typeof helpers.isPositiveNumber === "function" ? helpers.isPositiveNumber : () => false;
34+
const skinObjects = toObject(source);
35+
36+
return hasExpectedShape(skinObjects.background, ["hud-color"])
37+
&& isHexColor(skinObjects.background?.color)
38+
&& hasExpectedShape(skinObjects.frame, ["hud-color"])
39+
&& isHexColor(skinObjects.frame?.color)
40+
&& hasExpectedShape(skinObjects.orbit, ["hud-color"])
41+
&& isHexColor(skinObjects.orbit?.color)
42+
&& hasExpectedShape(skinObjects.hudText, ["hud-color"])
43+
&& isHexColor(skinObjects.hudText?.color)
44+
&& hasExpectedShape(skinObjects.hudMuted, ["hud-color"])
45+
&& isHexColor(skinObjects.hudMuted?.color)
46+
&& hasExpectedShape(skinObjects.hudPanel, ["hud-color"])
47+
&& isHexColor(skinObjects.hudPanel?.color)
48+
&& hasExpectedShape(skinObjects.sun, ["circle"])
49+
&& isHexColor(skinObjects.sun?.color)
50+
&& isPositiveNumber(skinObjects.sun?.radius)
51+
&& PLANET_IDS.every((id) => (
52+
hasExpectedShape(skinObjects[id], ["circle"])
53+
&& isHexColor(skinObjects[id]?.color)
54+
&& isPositiveNumber(skinObjects[id]?.radius)
55+
))
56+
&& MOON_IDS.every((id) => (
57+
hasExpectedShape(skinObjects[id], ["circle"])
58+
&& isHexColor(skinObjects[id]?.color)
59+
&& isPositiveNumber(skinObjects[id]?.radius)
60+
))
61+
&& RING_IDS.every((id) => {
62+
const ringObjectKey = RING_KEY_BY_PLANET[id];
63+
const ring = skinObjects[ringObjectKey];
64+
return hasExpectedShape(ring, ["ring"])
65+
&& isHexColor(ring?.color)
66+
&& isPositiveNumber(ring?.innerRadius)
67+
&& isPositiveNumber(ring?.outerRadius)
68+
&& Number(ring.outerRadius) > Number(ring.innerRadius);
69+
});
70+
}
71+
72+
export function mapSolarSystemObjectsToLegacy(source, entities) {
73+
const skinObjects = toObject(source);
74+
return {
75+
colors: {
76+
background: normalizeText(skinObjects.background?.color),
77+
frame: normalizeText(skinObjects.frame?.color),
78+
orbit: normalizeText(skinObjects.orbit?.color),
79+
text: normalizeText(skinObjects.hudText?.color),
80+
muted: normalizeText(skinObjects.hudMuted?.color),
81+
panel: normalizeText(skinObjects.hudPanel?.color)
82+
},
83+
sizing: {},
84+
entities: {
85+
sun: {
86+
color: normalizeText(skinObjects.sun?.color),
87+
radius: Number(skinObjects.sun?.radius)
88+
},
89+
planets: Object.fromEntries(
90+
PLANET_IDS.map((id) => {
91+
const body = toObject(skinObjects[id]);
92+
return [id, {
93+
color: normalizeText(body.color),
94+
radius: Number(body.radius)
95+
}];
96+
})
97+
),
98+
moons: Object.fromEntries(
99+
MOON_IDS.map((id) => {
100+
const body = toObject(skinObjects[id]);
101+
return [id, {
102+
color: normalizeText(body.color),
103+
radius: Number(body.radius)
104+
}];
105+
})
106+
),
107+
rings: Object.fromEntries(
108+
RING_IDS.map((id) => {
109+
const ringObjectKey = RING_KEY_BY_PLANET[id];
110+
const ring = toObject(skinObjects[ringObjectKey]);
111+
return [id, {
112+
color: normalizeText(ring.color),
113+
innerRadius: Number(ring.innerRadius),
114+
outerRadius: Number(ring.outerRadius)
115+
}];
116+
})
117+
),
118+
...toObject(entities)
119+
}
120+
};
121+
}

games/shared/gameSkinLoader.js

Lines changed: 10 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,13 @@ import {
22
preloadWorkspaceGameAssetCatalog,
33
resolveWorkspaceGameAssetPath
44
} from "/games/shared/workspaceGameAssetCatalog.js";
5+
import {
6+
mapSolarSystemObjectsToLegacy,
7+
validateSolarSystemSkinObjects
8+
} from "/games/SolarSystem/game/solarSkinContract.js";
59

610
const SKIN_DOCUMENT_KIND = "game-skin";
711
const BREAKOUT_BRICK_KEYS = Object.freeze(["brick1", "brick2", "brick3", "brick4", "brick5", "brick6"]);
8-
const SOLAR_PLANET_IDS = Object.freeze([
9-
"mercury",
10-
"venus",
11-
"earth",
12-
"mars",
13-
"jupiter",
14-
"saturn",
15-
"uranus",
16-
"neptune"
17-
]);
18-
const SOLAR_MOON_IDS = Object.freeze(["moon", "io", "europa", "ganymede", "titan"]);
19-
const SOLAR_RING_IDS = Object.freeze(["jupiter", "saturn", "uranus", "neptune"]);
20-
const SOLAR_RING_KEY_BY_PLANET = Object.freeze({
21-
jupiter: "ringJupiter",
22-
saturn: "ringSaturn",
23-
uranus: "ringUranus",
24-
neptune: "ringNeptune"
25-
});
2612
const SUPPORTED_OBJECT_SHAPES = Object.freeze([
2713
"circle",
2814
"oval",
@@ -177,43 +163,11 @@ function validateGameSkinObjects(gameId, objects) {
177163
}
178164

179165
if (normalizedGameId === "solarsystem") {
180-
const requiredPlanets = SOLAR_PLANET_IDS;
181-
const requiredMoons = SOLAR_MOON_IDS;
182-
const requiredRings = SOLAR_RING_IDS;
183-
return hasExpectedShape(source?.background, ["hud-color"])
184-
&& isHexColor(source?.background?.color)
185-
&& hasExpectedShape(source?.frame, ["hud-color"])
186-
&& isHexColor(source?.frame?.color)
187-
&& hasExpectedShape(source?.orbit, ["hud-color"])
188-
&& isHexColor(source?.orbit?.color)
189-
&& hasExpectedShape(source?.hudText, ["hud-color"])
190-
&& isHexColor(source?.hudText?.color)
191-
&& hasExpectedShape(source?.hudMuted, ["hud-color"])
192-
&& isHexColor(source?.hudMuted?.color)
193-
&& hasExpectedShape(source?.hudPanel, ["hud-color"])
194-
&& isHexColor(source?.hudPanel?.color)
195-
&& hasExpectedShape(source?.sun, ["circle"])
196-
&& isHexColor(source?.sun?.color)
197-
&& isPositiveNumber(source?.sun?.radius)
198-
&& requiredPlanets.every((id) => (
199-
hasExpectedShape(source?.[id], ["circle"])
200-
&& isHexColor(source?.[id]?.color)
201-
&& isPositiveNumber(source?.[id]?.radius)
202-
))
203-
&& requiredMoons.every((id) => (
204-
hasExpectedShape(source?.[id], ["circle"])
205-
&& isHexColor(source?.[id]?.color)
206-
&& isPositiveNumber(source?.[id]?.radius)
207-
))
208-
&& requiredRings.every((id) => {
209-
const ringObjectKey = SOLAR_RING_KEY_BY_PLANET[id];
210-
const ring = source?.[ringObjectKey];
211-
return hasExpectedShape(ring, ["ring"])
212-
&& isHexColor(ring?.color)
213-
&& isPositiveNumber(ring?.innerRadius)
214-
&& isPositiveNumber(ring?.outerRadius)
215-
&& Number(ring.outerRadius) > Number(ring.innerRadius);
216-
});
166+
return validateSolarSystemSkinObjects(source, {
167+
hasExpectedShape,
168+
isHexColor,
169+
isPositiveNumber
170+
});
217171
}
218172

219173
return true;
@@ -285,52 +239,7 @@ function mapObjectsToLegacy(gameId, objects, entities) {
285239
}
286240

287241
if (normalizedGameId === "solarsystem") {
288-
return {
289-
colors: {
290-
background: normalizeText(source?.background?.color),
291-
frame: normalizeText(source?.frame?.color),
292-
orbit: normalizeText(source?.orbit?.color),
293-
text: normalizeText(source?.hudText?.color),
294-
muted: normalizeText(source?.hudMuted?.color),
295-
panel: normalizeText(source?.hudPanel?.color)
296-
},
297-
sizing: {},
298-
entities: {
299-
sun: {
300-
color: normalizeText(source?.sun?.color),
301-
radius: Number(source?.sun?.radius)
302-
},
303-
planets: Object.fromEntries(
304-
SOLAR_PLANET_IDS.map((id) => {
305-
const body = toObject(source?.[id]);
306-
return [id, {
307-
color: normalizeText(body.color),
308-
radius: Number(body.radius)
309-
}];
310-
})
311-
),
312-
moons: Object.fromEntries(
313-
SOLAR_MOON_IDS.map((id) => {
314-
const body = toObject(source?.[id]);
315-
return [id, {
316-
color: normalizeText(body.color),
317-
radius: Number(body.radius)
318-
}];
319-
})
320-
),
321-
rings: Object.fromEntries(
322-
SOLAR_RING_IDS.map((id) => {
323-
const ringObjectKey = SOLAR_RING_KEY_BY_PLANET[id];
324-
const ring = toObject(source?.[ringObjectKey]);
325-
return [id, {
326-
color: normalizeText(ring.color),
327-
innerRadius: Number(ring.innerRadius),
328-
outerRadius: Number(ring.outerRadius)
329-
}];
330-
})
331-
)
332-
}
333-
};
242+
return mapSolarSystemObjectsToLegacy(source, entities);
334243
}
335244

336245
if (normalizedGameId === "bouncing-ball") {

0 commit comments

Comments
 (0)