@combos-fun/plugin-development-tool 0.0.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/dist/plugin-development-tool.cjs.js +299 -0
- package/dist/plugin-development-tool.cjs.js.map +1 -0
- package/dist/plugin-development-tool.cjs.prod.js +1 -0
- package/dist/plugin-development-tool.d.ts +81 -0
- package/dist/plugin-development-tool.esm.js +293 -0
- package/dist/plugin-development-tool.esm.js.map +1 -0
- package/index.js +7 -0
- package/package.json +28 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var engine = require('@combos-fun/engine');
|
|
4
|
+
var tslib = require('tslib');
|
|
5
|
+
var pluginRendererGraphics = require('@combos-fun/plugin-renderer-graphics');
|
|
6
|
+
var pluginRendererEvent = require('@combos-fun/plugin-renderer-event');
|
|
7
|
+
|
|
8
|
+
/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
|
|
9
|
+
const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set';
|
|
10
|
+
/** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */
|
|
11
|
+
const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh';
|
|
12
|
+
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
13
|
+
const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gameobject-selected';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach
|
|
17
|
+
* extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).
|
|
18
|
+
*/
|
|
19
|
+
class CombosDevelopmentToolTarget extends engine.Component {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
this.payload = {};
|
|
23
|
+
}
|
|
24
|
+
static { this.componentName = 'CombosDevelopmentToolTarget'; }
|
|
25
|
+
init(params) {
|
|
26
|
+
this.payload = params?.payload ? { ...params.payload } : {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
31
|
+
/**
|
|
32
|
+
* **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).
|
|
33
|
+
* Turn on/off via:
|
|
34
|
+
* - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
|
|
35
|
+
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
36
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
37
|
+
*
|
|
38
|
+
* With `scope: 'scene'`, while enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`, or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
39
|
+
*/
|
|
40
|
+
let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends engine.System {
|
|
41
|
+
constructor() {
|
|
42
|
+
super(...arguments);
|
|
43
|
+
this.postMessageOrigin = '*';
|
|
44
|
+
this.scope = 'scene';
|
|
45
|
+
this.enabled = false;
|
|
46
|
+
this.outlineGo = null;
|
|
47
|
+
this.selected = null;
|
|
48
|
+
this.tapHandlers = new Map();
|
|
49
|
+
this.tapOwners = new Map();
|
|
50
|
+
/** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */
|
|
51
|
+
this.injectedEvents = new Set();
|
|
52
|
+
this.needsSceneRescan = false;
|
|
53
|
+
this.onWindowSet = (e) => {
|
|
54
|
+
const d = e.detail;
|
|
55
|
+
if (d && typeof d.enabled === 'boolean') {
|
|
56
|
+
this.setEnabled(d.enabled);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.onWindowMessage = (e) => {
|
|
60
|
+
const d = e.data;
|
|
61
|
+
if (!d || typeof d !== 'object')
|
|
62
|
+
return;
|
|
63
|
+
if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {
|
|
64
|
+
this.setEnabled(d.enabled);
|
|
65
|
+
}
|
|
66
|
+
else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {
|
|
67
|
+
this.requestSceneRescan();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
this.onGameSet = (payload) => {
|
|
71
|
+
if (payload && typeof payload.enabled === 'boolean') {
|
|
72
|
+
this.setEnabled(payload.enabled);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.onGameRefresh = () => {
|
|
76
|
+
this.requestSceneRescan();
|
|
77
|
+
};
|
|
78
|
+
this.onWindowRefresh = () => {
|
|
79
|
+
this.requestSceneRescan();
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
static { this.systemName = 'CombosDevelopmentToolSystem'; }
|
|
83
|
+
init(params) {
|
|
84
|
+
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
85
|
+
this.scope = params?.scope ?? 'scene';
|
|
86
|
+
if (typeof window !== 'undefined') {
|
|
87
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
88
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
89
|
+
window.addEventListener('message', this.onWindowMessage);
|
|
90
|
+
}
|
|
91
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
92
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
93
|
+
if (this.enabled && this.scope === 'scene') {
|
|
94
|
+
this.needsSceneRescan = true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
onDestroy() {
|
|
98
|
+
if (typeof window !== 'undefined') {
|
|
99
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
100
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
101
|
+
window.removeEventListener('message', this.onWindowMessage);
|
|
102
|
+
}
|
|
103
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
104
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
105
|
+
this.detachAllTaps();
|
|
106
|
+
this.clearSelection();
|
|
107
|
+
}
|
|
108
|
+
/** Programmatic toggle (same effect as events). */
|
|
109
|
+
setEnabled(on) {
|
|
110
|
+
if (this.enabled === on)
|
|
111
|
+
return;
|
|
112
|
+
this.enabled = on;
|
|
113
|
+
if (!on) {
|
|
114
|
+
this.clearSelection();
|
|
115
|
+
if (this.scope === 'scene') {
|
|
116
|
+
this.detachAllTaps();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (this.scope === 'scene') {
|
|
120
|
+
this.needsSceneRescan = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
get isEnabled() {
|
|
124
|
+
return this.enabled;
|
|
125
|
+
}
|
|
126
|
+
update(e) {
|
|
127
|
+
if (this.scope === 'scene' && this.enabled && this.needsSceneRescan) {
|
|
128
|
+
this.needsSceneRescan = false;
|
|
129
|
+
this.attachSceneTree();
|
|
130
|
+
}
|
|
131
|
+
for (const go of [...this.tapOwners.values()]) {
|
|
132
|
+
if (go.destroyed) {
|
|
133
|
+
this.releaseTap(go);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (!this.enabled || !this.selected || !this.outlineGo)
|
|
137
|
+
return;
|
|
138
|
+
const gfxComp = this.outlineGo.getComponent(pluginRendererGraphics.Graphics);
|
|
139
|
+
if (!gfxComp?.graphics)
|
|
140
|
+
return;
|
|
141
|
+
const { width, height } = this.selected.transform.size;
|
|
142
|
+
const g = gfxComp.graphics;
|
|
143
|
+
g.clear();
|
|
144
|
+
const t = typeof performance !== 'undefined' ? performance.now() : e.time;
|
|
145
|
+
const pulse = 0.35 + 0.65 * (0.5 + 0.5 * Math.sin(t * 0.012));
|
|
146
|
+
g.rect(0, 0, Math.max(1, width), Math.max(1, height));
|
|
147
|
+
g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });
|
|
148
|
+
}
|
|
149
|
+
componentChanged(changed) {
|
|
150
|
+
if (this.scope === 'scene')
|
|
151
|
+
return;
|
|
152
|
+
const { type, gameObject, componentName } = changed;
|
|
153
|
+
if (!gameObject || componentName !== 'CombosDevelopmentToolTarget')
|
|
154
|
+
return;
|
|
155
|
+
if (type === engine.OBSERVER_TYPE.ADD) {
|
|
156
|
+
this.ensureTap(gameObject);
|
|
157
|
+
}
|
|
158
|
+
else if (type === engine.OBSERVER_TYPE.REMOVE) {
|
|
159
|
+
this.releaseTap(gameObject);
|
|
160
|
+
if (this.selected === gameObject) {
|
|
161
|
+
this.clearSelection();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */
|
|
166
|
+
requestSceneRescan() {
|
|
167
|
+
if (this.scope !== 'scene' || !this.enabled)
|
|
168
|
+
return;
|
|
169
|
+
this.needsSceneRescan = true;
|
|
170
|
+
}
|
|
171
|
+
attachSceneTree() {
|
|
172
|
+
this.detachAllTaps();
|
|
173
|
+
const list = [];
|
|
174
|
+
for (const tr of this.game.scene.transform.children) {
|
|
175
|
+
this.collectGameObjects(tr.gameObject, list);
|
|
176
|
+
}
|
|
177
|
+
for (const go of list) {
|
|
178
|
+
if (go.name === OUTLINE_GO_NAME)
|
|
179
|
+
continue;
|
|
180
|
+
if (go === this.outlineGo)
|
|
181
|
+
continue;
|
|
182
|
+
this.ensureTap(go);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
collectGameObjects(go, out) {
|
|
186
|
+
out.push(go);
|
|
187
|
+
for (const tr of go.transform.children) {
|
|
188
|
+
this.collectGameObjects(tr.gameObject, out);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
detachAllTaps() {
|
|
192
|
+
for (const go of [...this.tapOwners.values()]) {
|
|
193
|
+
this.releaseTap(go);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
ensureTap(go) {
|
|
197
|
+
let ev = go.getComponent(pluginRendererEvent.Event);
|
|
198
|
+
if (!ev) {
|
|
199
|
+
const { width, height } = go.transform.size;
|
|
200
|
+
ev = go.addComponent(new pluginRendererEvent.Event({
|
|
201
|
+
hitArea: {
|
|
202
|
+
type: pluginRendererEvent.HIT_AREA_TYPE.Rect,
|
|
203
|
+
style: { x: 0, y: 0, width: width || 1, height: height || 1 },
|
|
204
|
+
},
|
|
205
|
+
}));
|
|
206
|
+
this.injectedEvents.add(go.id);
|
|
207
|
+
}
|
|
208
|
+
if (this.tapHandlers.has(go.id))
|
|
209
|
+
return;
|
|
210
|
+
const handler = () => this.onSelect(go);
|
|
211
|
+
this.tapHandlers.set(go.id, handler);
|
|
212
|
+
this.tapOwners.set(go.id, go);
|
|
213
|
+
ev.on('tap', handler);
|
|
214
|
+
}
|
|
215
|
+
releaseTap(go) {
|
|
216
|
+
const handler = this.tapHandlers.get(go.id);
|
|
217
|
+
if (!handler)
|
|
218
|
+
return;
|
|
219
|
+
const ev = go.getComponent(pluginRendererEvent.Event);
|
|
220
|
+
ev?.off('tap', handler);
|
|
221
|
+
this.tapHandlers.delete(go.id);
|
|
222
|
+
this.tapOwners.delete(go.id);
|
|
223
|
+
if (this.injectedEvents.has(go.id)) {
|
|
224
|
+
try {
|
|
225
|
+
go.removeComponent(pluginRendererEvent.Event);
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
/* ignore */
|
|
229
|
+
}
|
|
230
|
+
this.injectedEvents.delete(go.id);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
ensureOutline() {
|
|
234
|
+
if (this.outlineGo)
|
|
235
|
+
return;
|
|
236
|
+
const go = new engine.GameObject(OUTLINE_GO_NAME, {
|
|
237
|
+
size: { width: 1, height: 1 },
|
|
238
|
+
position: { x: 0, y: 0 },
|
|
239
|
+
origin: { x: 0, y: 0 },
|
|
240
|
+
});
|
|
241
|
+
go.addComponent(new pluginRendererGraphics.Graphics());
|
|
242
|
+
this.outlineGo = go;
|
|
243
|
+
}
|
|
244
|
+
onSelect(go) {
|
|
245
|
+
if (!this.enabled)
|
|
246
|
+
return;
|
|
247
|
+
this.ensureOutline();
|
|
248
|
+
if (!this.outlineGo)
|
|
249
|
+
return;
|
|
250
|
+
this.selected = go;
|
|
251
|
+
if (this.outlineGo.parent) {
|
|
252
|
+
this.outlineGo.remove();
|
|
253
|
+
}
|
|
254
|
+
go.addChild(this.outlineGo);
|
|
255
|
+
const payload = this.serializeGameObject(go);
|
|
256
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
257
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
clearSelection() {
|
|
261
|
+
this.selected = null;
|
|
262
|
+
if (this.outlineGo?.parent) {
|
|
263
|
+
this.outlineGo.remove();
|
|
264
|
+
}
|
|
265
|
+
const gfx = this.outlineGo?.getComponent(pluginRendererGraphics.Graphics);
|
|
266
|
+
if (gfx?.graphics) {
|
|
267
|
+
gfx.graphics.clear();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
serializeGameObject(go) {
|
|
271
|
+
const tag = go.getComponent(CombosDevelopmentToolTarget);
|
|
272
|
+
const pos = go.transform.position;
|
|
273
|
+
const size = go.transform.size;
|
|
274
|
+
return {
|
|
275
|
+
type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,
|
|
276
|
+
gameObject: {
|
|
277
|
+
name: go.name,
|
|
278
|
+
id: go.id,
|
|
279
|
+
position: { x: pos.x, y: pos.y },
|
|
280
|
+
size: { width: size.width, height: size.height },
|
|
281
|
+
rotation: go.transform.rotation,
|
|
282
|
+
payload: tag?.payload ?? {},
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
CombosDevelopmentToolSystem = tslib.__decorate([
|
|
288
|
+
engine.decorators.componentObserver({
|
|
289
|
+
CombosDevelopmentToolTarget: [],
|
|
290
|
+
})
|
|
291
|
+
], CombosDevelopmentToolSystem);
|
|
292
|
+
var CombosDevelopmentToolSystem_default = CombosDevelopmentToolSystem;
|
|
293
|
+
|
|
294
|
+
exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED;
|
|
295
|
+
exports.COMBOS_DEVELOPMENT_TOOL_REFRESH = COMBOS_DEVELOPMENT_TOOL_REFRESH;
|
|
296
|
+
exports.COMBOS_DEVELOPMENT_TOOL_SET = COMBOS_DEVELOPMENT_TOOL_SET;
|
|
297
|
+
exports.CombosDevelopmentToolSystem = CombosDevelopmentToolSystem_default;
|
|
298
|
+
exports.CombosDevelopmentToolTarget = CombosDevelopmentToolTarget;
|
|
299
|
+
//# sourceMappingURL=plugin-development-tool.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-development-tool.cjs.js","sources":["../lib/constants.ts","../lib/CombosDevelopmentToolTarget.ts","../lib/CombosDevelopmentToolSystem.ts"],"sourcesContent":["/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */\nexport const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set' as const;\n\n/** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */\nexport const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh' as const;\n\n/** Emitted to `window.parent` when an object is selected while the tool is on. */\nexport const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED =\n 'combos-development-tool:gameobject-selected' as const;\n","import { Component, ComponentParams } from '@combos-fun/engine';\n\nexport interface CombosDevelopmentToolTargetParams extends ComponentParams {\n /** Extra JSON-serializable fields included in postMessage to parent. */\n payload?: Record<string, unknown>;\n}\n\n/**\n * Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach\n * extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).\n */\nexport default class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToolTargetParams> {\n static componentName = 'CombosDevelopmentToolTarget';\n\n payload: Record<string, unknown> = {};\n\n init(params?: CombosDevelopmentToolTargetParams) {\n this.payload = params?.payload ? { ...params.payload } : {};\n }\n}\n","import {\n ComponentChanged,\n GameObject,\n OBSERVER_TYPE,\n System,\n UpdateParams,\n decorators,\n} from '@combos-fun/engine';\nimport { Graphics } from '@combos-fun/plugin-renderer-graphics';\nimport { Event, HIT_AREA_TYPE } from '@combos-fun/plugin-renderer-event';\nimport {\n COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,\n COMBOS_DEVELOPMENT_TOOL_REFRESH,\n COMBOS_DEVELOPMENT_TOOL_SET,\n} from './constants';\nimport CombosDevelopmentToolTarget from './CombosDevelopmentToolTarget';\n\nexport type CombosDevelopmentToolSelectScope = 'tagged' | 'scene';\n\nexport interface CombosDevelopmentToolSystemParams {\n /** postMessage `targetOrigin` when notifying parent (default `'*'`). */\n postMessageOrigin?: string;\n /**\n * - `tagged`: only `GameObject`s with {@link CombosDevelopmentToolTarget} participate (optional `payload`).\n * - `scene`: all objects under `game.scene` (except the outline helper) get tap → outline + postMessage; no marker component required (default).\n */\n scope?: CombosDevelopmentToolSelectScope;\n}\n\nconst OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';\n\ntype SetPayload = { enabled?: boolean };\n\n/**\n * **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).\n * Turn on/off via:\n * - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`\n * - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)\n * - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`\n *\n * With `scope: 'scene'`, while enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`, or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.\n */\n@decorators.componentObserver({\n CombosDevelopmentToolTarget: [],\n})\nexport default class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {\n static systemName = 'CombosDevelopmentToolSystem';\n\n private postMessageOrigin = '*';\n private scope: CombosDevelopmentToolSelectScope = 'scene';\n private enabled = false;\n private outlineGo: GameObject | null = null;\n private selected: GameObject | null = null;\n private readonly tapHandlers = new Map<number, () => void>();\n private readonly tapOwners = new Map<number, GameObject>();\n /** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */\n private readonly injectedEvents = new Set<number>();\n private needsSceneRescan = false;\n\n private readonly onWindowSet = (e: globalThis.Event) => {\n const d = (e as unknown as CustomEvent<SetPayload>).detail;\n if (d && typeof d.enabled === 'boolean') {\n this.setEnabled(d.enabled);\n }\n };\n\n private readonly onWindowMessage = (e: MessageEvent) => {\n const d = e.data;\n if (!d || typeof d !== 'object') return;\n if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {\n this.setEnabled(d.enabled);\n } else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {\n this.requestSceneRescan();\n }\n };\n\n private readonly onGameSet = (payload: SetPayload) => {\n if (payload && typeof payload.enabled === 'boolean') {\n this.setEnabled(payload.enabled);\n }\n };\n\n private readonly onGameRefresh = () => {\n this.requestSceneRescan();\n };\n\n private readonly onWindowRefresh = () => {\n this.requestSceneRescan();\n };\n\n init(params?: CombosDevelopmentToolSystemParams) {\n this.postMessageOrigin = params?.postMessageOrigin ?? '*';\n this.scope = params?.scope ?? 'scene';\n\n if (typeof window !== 'undefined') {\n window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);\n window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);\n window.addEventListener('message', this.onWindowMessage);\n }\n this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);\n this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);\n\n if (this.enabled && this.scope === 'scene') {\n this.needsSceneRescan = true;\n }\n }\n\n onDestroy() {\n if (typeof window !== 'undefined') {\n window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);\n window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);\n window.removeEventListener('message', this.onWindowMessage);\n }\n this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);\n this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);\n this.detachAllTaps();\n this.clearSelection();\n }\n\n /** Programmatic toggle (same effect as events). */\n setEnabled(on: boolean) {\n if (this.enabled === on) return;\n this.enabled = on;\n if (!on) {\n this.clearSelection();\n if (this.scope === 'scene') {\n this.detachAllTaps();\n }\n } else if (this.scope === 'scene') {\n this.needsSceneRescan = true;\n }\n }\n\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n update(e: UpdateParams) {\n if (this.scope === 'scene' && this.enabled && this.needsSceneRescan) {\n this.needsSceneRescan = false;\n this.attachSceneTree();\n }\n\n for (const go of [...this.tapOwners.values()]) {\n if (go.destroyed) {\n this.releaseTap(go);\n }\n }\n\n if (!this.enabled || !this.selected || !this.outlineGo) return;\n\n const gfxComp = this.outlineGo.getComponent(Graphics);\n if (!gfxComp?.graphics) return;\n\n const { width, height } = this.selected.transform.size;\n const g = gfxComp.graphics;\n g.clear();\n const t = typeof performance !== 'undefined' ? performance.now() : e.time;\n const pulse = 0.35 + 0.65 * (0.5 + 0.5 * Math.sin(t * 0.012));\n g.rect(0, 0, Math.max(1, width), Math.max(1, height));\n g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });\n }\n\n componentChanged(changed: ComponentChanged) {\n if (this.scope === 'scene') return;\n\n const { type, gameObject, componentName } = changed;\n if (!gameObject || componentName !== 'CombosDevelopmentToolTarget') return;\n\n if (type === OBSERVER_TYPE.ADD) {\n this.ensureTap(gameObject);\n } else if (type === OBSERVER_TYPE.REMOVE) {\n this.releaseTap(gameObject);\n if (this.selected === gameObject) {\n this.clearSelection();\n }\n }\n }\n\n /** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */\n requestSceneRescan() {\n if (this.scope !== 'scene' || !this.enabled) return;\n this.needsSceneRescan = true;\n }\n\n private attachSceneTree() {\n this.detachAllTaps();\n const list: GameObject[] = [];\n for (const tr of this.game.scene.transform.children) {\n this.collectGameObjects(tr.gameObject, list);\n }\n for (const go of list) {\n if (go.name === OUTLINE_GO_NAME) continue;\n if (go === this.outlineGo) continue;\n this.ensureTap(go);\n }\n }\n\n private collectGameObjects(go: GameObject, out: GameObject[]) {\n out.push(go);\n for (const tr of go.transform.children) {\n this.collectGameObjects(tr.gameObject, out);\n }\n }\n\n private detachAllTaps() {\n for (const go of [...this.tapOwners.values()]) {\n this.releaseTap(go);\n }\n }\n\n private ensureTap(go: GameObject) {\n let ev = go.getComponent(Event);\n if (!ev) {\n const { width, height } = go.transform.size;\n ev = go.addComponent(\n new Event({\n hitArea: {\n type: HIT_AREA_TYPE.Rect,\n style: { x: 0, y: 0, width: width || 1, height: height || 1 },\n },\n }),\n );\n this.injectedEvents.add(go.id);\n }\n\n if (this.tapHandlers.has(go.id)) return;\n\n const handler = () => this.onSelect(go);\n this.tapHandlers.set(go.id, handler);\n this.tapOwners.set(go.id, go);\n ev.on('tap', handler);\n }\n\n private releaseTap(go: GameObject) {\n const handler = this.tapHandlers.get(go.id);\n if (!handler) return;\n const ev = go.getComponent(Event);\n ev?.off('tap', handler);\n this.tapHandlers.delete(go.id);\n this.tapOwners.delete(go.id);\n if (this.injectedEvents.has(go.id)) {\n try {\n go.removeComponent(Event);\n } catch {\n /* ignore */\n }\n this.injectedEvents.delete(go.id);\n }\n }\n\n private ensureOutline() {\n if (this.outlineGo) return;\n const go = new GameObject(OUTLINE_GO_NAME, {\n size: { width: 1, height: 1 },\n position: { x: 0, y: 0 },\n origin: { x: 0, y: 0 },\n });\n go.addComponent(new Graphics());\n this.outlineGo = go;\n }\n\n private onSelect(go: GameObject) {\n if (!this.enabled) return;\n\n this.ensureOutline();\n if (!this.outlineGo) return;\n\n this.selected = go;\n\n if (this.outlineGo.parent) {\n this.outlineGo.remove();\n }\n go.addChild(this.outlineGo);\n\n const payload = this.serializeGameObject(go);\n if (typeof window !== 'undefined' && window.parent && window.parent !== window) {\n window.parent.postMessage(payload, this.postMessageOrigin);\n }\n }\n\n private clearSelection() {\n this.selected = null;\n if (this.outlineGo?.parent) {\n this.outlineGo.remove();\n }\n const gfx = this.outlineGo?.getComponent(Graphics);\n if (gfx?.graphics) {\n gfx.graphics.clear();\n }\n }\n\n private serializeGameObject(go: GameObject) {\n const tag = go.getComponent(CombosDevelopmentToolTarget);\n const pos = go.transform.position;\n const size = go.transform.size;\n return {\n type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,\n gameObject: {\n name: go.name,\n id: go.id,\n position: { x: pos.x, y: pos.y },\n size: { width: size.width, height: size.height },\n rotation: go.transform.rotation,\n payload: tag?.payload ?? {},\n },\n };\n }\n}\n"],"names":["Component","System","Graphics","OBSERVER_TYPE","Event","HIT_AREA_TYPE","GameObject","__decorate","decorators"],"mappings":";;;;;;;AAAA;AACO,MAAM,2BAA2B,GAAG;AAE3C;AACO,MAAM,+BAA+B,GAAG;AAE/C;AACO,MAAM,2CAA2C,GACtD;;ACDF;;;AAGG;AACW,MAAO,2BAA4B,SAAQA,gBAA4C,CAAA;AAArG,IAAA,WAAA,GAAA;;QAGE,IAAA,CAAA,OAAO,GAA4B,EAAE;IAKvC;aAPS,IAAA,CAAA,aAAa,GAAG,6BAAH,CAAiC;AAIrD,IAAA,IAAI,CAAC,MAA0C,EAAA;AAC7C,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE;IAC7D;;;ACWF,MAAM,eAAe,GAAG,gCAAgC;AAIxD;;;;;;;;AAQG;AAIY,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQC,aAAyC,CAAA;AAAnF,IAAA,WAAA,GAAA;;QAGL,IAAA,CAAA,iBAAiB,GAAG,GAAG;QACvB,IAAA,CAAA,KAAK,GAAqC,OAAO;QACjD,IAAA,CAAA,OAAO,GAAG,KAAK;QACf,IAAA,CAAA,SAAS,GAAsB,IAAI;QACnC,IAAA,CAAA,QAAQ,GAAsB,IAAI;AACzB,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,GAAG,EAAsB;AAC3C,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,GAAG,EAAsB;;AAEzC,QAAA,IAAA,CAAA,cAAc,GAAG,IAAI,GAAG,EAAU;QAC3C,IAAA,CAAA,gBAAgB,GAAG,KAAK;AAEf,QAAA,IAAA,CAAA,WAAW,GAAG,CAAC,CAAmB,KAAI;AACrD,YAAA,MAAM,CAAC,GAAI,CAAwC,CAAC,MAAM;YAC1D,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE;AACvC,gBAAA,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5B;AACF,QAAA,CAAC;AAEgB,QAAA,IAAA,CAAA,eAAe,GAAG,CAAC,CAAe,KAAI;AACrD,YAAA,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI;AAChB,YAAA,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE;AACjC,YAAA,IAAI,CAAC,CAAC,IAAI,KAAK,2BAA2B,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE;AAC5E,gBAAA,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5B;AAAO,iBAAA,IAAI,CAAC,CAAC,IAAI,KAAK,+BAA+B,EAAE;gBACrD,IAAI,CAAC,kBAAkB,EAAE;YAC3B;AACF,QAAA,CAAC;AAEgB,QAAA,IAAA,CAAA,SAAS,GAAG,CAAC,OAAmB,KAAI;YACnD,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;AACnD,gBAAA,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;YAClC;AACF,QAAA,CAAC;QAEgB,IAAA,CAAA,aAAa,GAAG,MAAK;YACpC,IAAI,CAAC,kBAAkB,EAAE;AAC3B,QAAA,CAAC;QAEgB,IAAA,CAAA,eAAe,GAAG,MAAK;YACtC,IAAI,CAAC,kBAAkB,EAAE;AAC3B,QAAA,CAAC;IA4NH;aAtQS,IAAA,CAAA,UAAU,GAAG,6BAAH,CAAiC;AA4ClD,IAAA,IAAI,CAAC,MAA0C,EAAA;QAC7C,IAAI,CAAC,iBAAiB,GAAG,MAAM,EAAE,iBAAiB,IAAI,GAAG;QACzD,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,OAAO;AAErC,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,IAAI,CAAC,WAAW,CAAC;YACtE,MAAM,CAAC,gBAAgB,CAAC,+BAA+B,EAAE,IAAI,CAAC,eAAe,CAAC;YAC9E,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC;QAC1D;QACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,2BAA2B,EAAE,IAAI,CAAC,SAAS,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,+BAA+B,EAAE,IAAI,CAAC,aAAa,CAAC;QAEjE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE;AAC1C,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC9B;IACF;IAEA,SAAS,GAAA;AACP,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,MAAM,CAAC,mBAAmB,CAAC,2BAA2B,EAAE,IAAI,CAAC,WAAW,CAAC;YACzE,MAAM,CAAC,mBAAmB,CAAC,+BAA+B,EAAE,IAAI,CAAC,eAAe,CAAC;YACjF,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC;QAC7D;QACA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,SAAS,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC,aAAa,CAAC;QAClE,IAAI,CAAC,aAAa,EAAE;QACpB,IAAI,CAAC,cAAc,EAAE;IACvB;;AAGA,IAAA,UAAU,CAAC,EAAW,EAAA;AACpB,QAAA,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE;YAAE;AACzB,QAAA,IAAI,CAAC,OAAO,GAAG,EAAE;QACjB,IAAI,CAAC,EAAE,EAAE;YACP,IAAI,CAAC,cAAc,EAAE;AACrB,YAAA,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE;gBAC1B,IAAI,CAAC,aAAa,EAAE;YACtB;QACF;AAAO,aAAA,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE;AACjC,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;QAC9B;IACF;AAEA,IAAA,IAAI,SAAS,GAAA;QACX,OAAO,IAAI,CAAC,OAAO;IACrB;AAEA,IAAA,MAAM,CAAC,CAAe,EAAA;AACpB,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACnE,YAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK;YAC7B,IAAI,CAAC,eAAe,EAAE;QACxB;AAEA,QAAA,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE;AAC7C,YAAA,IAAI,EAAE,CAAC,SAAS,EAAE;AAChB,gBAAA,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACrB;QACF;AAEA,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;QAExD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAACC,+BAAQ,CAAC;QACrD,IAAI,CAAC,OAAO,EAAE,QAAQ;YAAE;AAExB,QAAA,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI;AACtD,QAAA,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ;QAC1B,CAAC,CAAC,KAAK,EAAE;AACT,QAAA,MAAM,CAAC,GAAG,OAAO,WAAW,KAAK,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI;QACzE,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QAC7D,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACrD,QAAA,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACvD;AAEA,IAAA,gBAAgB,CAAC,OAAyB,EAAA;AACxC,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO;YAAE;QAE5B,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO;AACnD,QAAA,IAAI,CAAC,UAAU,IAAI,aAAa,KAAK,6BAA6B;YAAE;AAEpE,QAAA,IAAI,IAAI,KAAKC,oBAAa,CAAC,GAAG,EAAE;AAC9B,YAAA,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;QAC5B;AAAO,aAAA,IAAI,IAAI,KAAKA,oBAAa,CAAC,MAAM,EAAE;AACxC,YAAA,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;AAC3B,YAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE;gBAChC,IAAI,CAAC,cAAc,EAAE;YACvB;QACF;IACF;;IAGA,kBAAkB,GAAA;QAChB,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAC7C,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;IAC9B;IAEQ,eAAe,GAAA;QACrB,IAAI,CAAC,aAAa,EAAE;QACpB,MAAM,IAAI,GAAiB,EAAE;AAC7B,QAAA,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE;YACnD,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC;QAC9C;AACA,QAAA,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE;AACrB,YAAA,IAAI,EAAE,CAAC,IAAI,KAAK,eAAe;gBAAE;AACjC,YAAA,IAAI,EAAE,KAAK,IAAI,CAAC,SAAS;gBAAE;AAC3B,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB;IACF;IAEQ,kBAAkB,CAAC,EAAc,EAAE,GAAiB,EAAA;AAC1D,QAAA,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACZ,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE;YACtC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC;QAC7C;IACF;IAEQ,aAAa,GAAA;AACnB,QAAA,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE;AAC7C,YAAA,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACrB;IACF;AAEQ,IAAA,SAAS,CAAC,EAAc,EAAA;QAC9B,IAAI,EAAE,GAAG,EAAE,CAAC,YAAY,CAACC,yBAAK,CAAC;QAC/B,IAAI,CAAC,EAAE,EAAE;YACP,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI;AAC3C,YAAA,EAAE,GAAG,EAAE,CAAC,YAAY,CAClB,IAAIA,yBAAK,CAAC;AACR,gBAAA,OAAO,EAAE;oBACP,IAAI,EAAEC,iCAAa,CAAC,IAAI;oBACxB,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE;AAC9D,iBAAA;AACF,aAAA,CAAC,CACH;YACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QAChC;QAEA,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAAE;QAEjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AAC7B,QAAA,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;IACvB;AAEQ,IAAA,UAAU,CAAC,EAAc,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3C,QAAA,IAAI,CAAC,OAAO;YAAE;QACd,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAACD,yBAAK,CAAC;AACjC,QAAA,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAClC,YAAA,IAAI;AACF,gBAAA,EAAE,CAAC,eAAe,CAACA,yBAAK,CAAC;YAC3B;AAAE,YAAA,MAAM;;YAER;YACA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC;IACF;IAEQ,aAAa,GAAA;QACnB,IAAI,IAAI,CAAC,SAAS;YAAE;AACpB,QAAA,MAAM,EAAE,GAAG,IAAIE,iBAAU,CAAC,eAAe,EAAE;YACzC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;YAC7B,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;YACxB,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACvB,SAAA,CAAC;AACF,QAAA,EAAE,CAAC,YAAY,CAAC,IAAIJ,+BAAQ,EAAE,CAAC;AAC/B,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEQ,IAAA,QAAQ,CAAC,EAAc,EAAA;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;QAEnB,IAAI,CAAC,aAAa,EAAE;QACpB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AAErB,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;AAElB,QAAA,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;AACzB,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;QACzB;AACA,QAAA,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;QAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;AAC5C,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE;YAC9E,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC5D;IACF;IAEQ,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACpB,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;QACzB;QACA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAACA,+BAAQ,CAAC;AAClD,QAAA,IAAI,GAAG,EAAE,QAAQ,EAAE;AACjB,YAAA,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE;QACtB;IACF;AAEQ,IAAA,mBAAmB,CAAC,EAAc,EAAA;QACxC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,2BAA2B,CAAC;AACxD,QAAA,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ;AACjC,QAAA,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI;QAC9B,OAAO;AACL,YAAA,IAAI,EAAE,2CAA2C;AACjD,YAAA,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,EAAE,EAAE,EAAE,CAAC,EAAE;AACT,gBAAA,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;AAChC,gBAAA,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;AAChD,gBAAA,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ;AAC/B,gBAAA,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE;AAC5B,aAAA;SACF;IACH;;AAtQmB,2BAA2B,GAAAK,gBAAA,CAAA;IAH/CC,iBAAU,CAAC,iBAAiB,CAAC;AAC5B,QAAA,2BAA2B,EAAE,EAAE;KAChC;AACoB,CAAA,EAAA,2BAA2B,CAuQ/C;0CAvQoB,2BAA2B;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("@combos-fun/engine"),t=require("tslib"),s=require("@combos-fun/plugin-renderer-graphics"),n=require("@combos-fun/plugin-renderer-event");const o="combos-development-tool:set",i="combos-development-tool:refresh",a="combos-development-tool:gameobject-selected";class r extends e.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const h="__combosDevelopmentToolOutline";let c=class extends e.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.scope="scene",this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.injectedEvents=new Set,this.needsSceneRescan=!1,this.onWindowSet=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowMessage=e=>{const t=e.data;t&&"object"==typeof t&&(t.type===o&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===i&&this.requestSceneRescan())},this.onGameSet=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onWindowRefresh=()=>{this.requestSceneRescan()}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*",this.scope=e?.scope??"scene","undefined"!=typeof window&&(window.addEventListener(o,this.onWindowSet),window.addEventListener(i,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(o,this.onGameSet),this.game.on(i,this.onGameRefresh),this.enabled&&"scene"===this.scope&&(this.needsSceneRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(o,this.onWindowSet),window.removeEventListener(i,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(o,this.onGameSet),this.game.off(i,this.onGameRefresh),this.detachAllTaps(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?"scene"===this.scope&&(this.needsSceneRescan=!0):(this.clearSelection(),"scene"===this.scope&&this.detachAllTaps()))}get isEnabled(){return this.enabled}update(e){"scene"===this.scope&&this.enabled&&this.needsSceneRescan&&(this.needsSceneRescan=!1,this.attachSceneTree());for(const e of[...this.tapOwners.values()])e.destroyed&&this.releaseTap(e);if(!this.enabled||!this.selected||!this.outlineGo)return;const t=this.outlineGo.getComponent(s.Graphics);if(!t?.graphics)return;const{width:n,height:o}=this.selected.transform.size,i=t.graphics;i.clear();const a="undefined"!=typeof performance?performance.now():e.time,r=.35+.65*(.5+.5*Math.sin(.012*a));i.rect(0,0,Math.max(1,n),Math.max(1,o)),i.stroke({width:4,color:5636010,alpha:r})}componentChanged(t){if("scene"===this.scope)return;const{type:s,gameObject:n,componentName:o}=t;n&&"CombosDevelopmentToolTarget"===o&&(s===e.OBSERVER_TYPE.ADD?this.ensureTap(n):s===e.OBSERVER_TYPE.REMOVE&&(this.releaseTap(n),this.selected===n&&this.clearSelection()))}requestSceneRescan(){"scene"===this.scope&&this.enabled&&(this.needsSceneRescan=!0)}attachSceneTree(){this.detachAllTaps();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)t.name!==h&&t!==this.outlineGo&&this.ensureTap(t)}collectGameObjects(e,t){t.push(e);for(const s of e.transform.children)this.collectGameObjects(s.gameObject,t)}detachAllTaps(){for(const e of[...this.tapOwners.values()])this.releaseTap(e)}ensureTap(e){let t=e.getComponent(n.Event);if(!t){const{width:s,height:o}=e.transform.size;t=e.addComponent(new n.Event({hitArea:{type:n.HIT_AREA_TYPE.Rect,style:{x:0,y:0,width:s||1,height:o||1}}})),this.injectedEvents.add(e.id)}if(this.tapHandlers.has(e.id))return;const s=()=>this.onSelect(e);this.tapHandlers.set(e.id,s),this.tapOwners.set(e.id,e),t.on("tap",s)}releaseTap(e){const t=this.tapHandlers.get(e.id);if(!t)return;const s=e.getComponent(n.Event);if(s?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.injectedEvents.has(e.id)){try{e.removeComponent(n.Event)}catch{}this.injectedEvents.delete(e.id)}}ensureOutline(){if(this.outlineGo)return;const t=new e.GameObject(h,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});t.addComponent(new s.Graphics),this.outlineGo=t}onSelect(e){if(!this.enabled)return;if(this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo);const t=this.serializeGameObject(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin)}clearSelection(){this.selected=null,this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(s.Graphics);e?.graphics&&e.graphics.clear()}serializeGameObject(e){const t=e.getComponent(r),s=e.transform.position,n=e.transform.size;return{type:a,gameObject:{name:e.name,id:e.id,position:{x:s.x,y:s.y},size:{width:n.width,height:n.height},rotation:e.transform.rotation,payload:t?.payload??{}}}}};c=t.__decorate([e.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],c);var d=c;exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=a,exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=i,exports.COMBOS_DEVELOPMENT_TOOL_SET=o,exports.CombosDevelopmentToolSystem=d,exports.CombosDevelopmentToolTarget=r;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Component, ComponentParams, System, UpdateParams, ComponentChanged } from '@combos-fun/engine';
|
|
2
|
+
|
|
3
|
+
/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
|
|
4
|
+
declare const COMBOS_DEVELOPMENT_TOOL_SET: "combos-development-tool:set";
|
|
5
|
+
/** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */
|
|
6
|
+
declare const COMBOS_DEVELOPMENT_TOOL_REFRESH: "combos-development-tool:refresh";
|
|
7
|
+
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
8
|
+
declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED: "combos-development-tool:gameobject-selected";
|
|
9
|
+
|
|
10
|
+
interface CombosDevelopmentToolTargetParams extends ComponentParams {
|
|
11
|
+
/** Extra JSON-serializable fields included in postMessage to parent. */
|
|
12
|
+
payload?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach
|
|
16
|
+
* extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).
|
|
17
|
+
*/
|
|
18
|
+
declare class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToolTargetParams> {
|
|
19
|
+
static componentName: string;
|
|
20
|
+
payload: Record<string, unknown>;
|
|
21
|
+
init(params?: CombosDevelopmentToolTargetParams): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type CombosDevelopmentToolSelectScope = 'tagged' | 'scene';
|
|
25
|
+
interface CombosDevelopmentToolSystemParams {
|
|
26
|
+
/** postMessage `targetOrigin` when notifying parent (default `'*'`). */
|
|
27
|
+
postMessageOrigin?: string;
|
|
28
|
+
/**
|
|
29
|
+
* - `tagged`: only `GameObject`s with {@link CombosDevelopmentToolTarget} participate (optional `payload`).
|
|
30
|
+
* - `scene`: all objects under `game.scene` (except the outline helper) get tap → outline + postMessage; no marker component required (default).
|
|
31
|
+
*/
|
|
32
|
+
scope?: CombosDevelopmentToolSelectScope;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).
|
|
36
|
+
* Turn on/off via:
|
|
37
|
+
* - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
|
|
38
|
+
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
39
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
40
|
+
*
|
|
41
|
+
* With `scope: 'scene'`, while enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`, or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
42
|
+
*/
|
|
43
|
+
declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {
|
|
44
|
+
static systemName: string;
|
|
45
|
+
private postMessageOrigin;
|
|
46
|
+
private scope;
|
|
47
|
+
private enabled;
|
|
48
|
+
private outlineGo;
|
|
49
|
+
private selected;
|
|
50
|
+
private readonly tapHandlers;
|
|
51
|
+
private readonly tapOwners;
|
|
52
|
+
/** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */
|
|
53
|
+
private readonly injectedEvents;
|
|
54
|
+
private needsSceneRescan;
|
|
55
|
+
private readonly onWindowSet;
|
|
56
|
+
private readonly onWindowMessage;
|
|
57
|
+
private readonly onGameSet;
|
|
58
|
+
private readonly onGameRefresh;
|
|
59
|
+
private readonly onWindowRefresh;
|
|
60
|
+
init(params?: CombosDevelopmentToolSystemParams): void;
|
|
61
|
+
onDestroy(): void;
|
|
62
|
+
/** Programmatic toggle (same effect as events). */
|
|
63
|
+
setEnabled(on: boolean): void;
|
|
64
|
+
get isEnabled(): boolean;
|
|
65
|
+
update(e: UpdateParams): void;
|
|
66
|
+
componentChanged(changed: ComponentChanged): void;
|
|
67
|
+
/** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */
|
|
68
|
+
requestSceneRescan(): void;
|
|
69
|
+
private attachSceneTree;
|
|
70
|
+
private collectGameObjects;
|
|
71
|
+
private detachAllTaps;
|
|
72
|
+
private ensureTap;
|
|
73
|
+
private releaseTap;
|
|
74
|
+
private ensureOutline;
|
|
75
|
+
private onSelect;
|
|
76
|
+
private clearSelection;
|
|
77
|
+
private serializeGameObject;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget };
|
|
81
|
+
export type { CombosDevelopmentToolSelectScope, CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams };
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { Component, System, OBSERVER_TYPE, GameObject, decorators } from '@combos-fun/engine';
|
|
2
|
+
import { __decorate } from 'tslib';
|
|
3
|
+
import { Graphics } from '@combos-fun/plugin-renderer-graphics';
|
|
4
|
+
import { Event, HIT_AREA_TYPE } from '@combos-fun/plugin-renderer-event';
|
|
5
|
+
|
|
6
|
+
/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
|
|
7
|
+
const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set';
|
|
8
|
+
/** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */
|
|
9
|
+
const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh';
|
|
10
|
+
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
11
|
+
const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gameobject-selected';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach
|
|
15
|
+
* extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).
|
|
16
|
+
*/
|
|
17
|
+
class CombosDevelopmentToolTarget extends Component {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.payload = {};
|
|
21
|
+
}
|
|
22
|
+
static { this.componentName = 'CombosDevelopmentToolTarget'; }
|
|
23
|
+
init(params) {
|
|
24
|
+
this.payload = params?.payload ? { ...params.payload } : {};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
29
|
+
/**
|
|
30
|
+
* **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).
|
|
31
|
+
* Turn on/off via:
|
|
32
|
+
* - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
|
|
33
|
+
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
34
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
35
|
+
*
|
|
36
|
+
* With `scope: 'scene'`, while enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`, or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
37
|
+
*/
|
|
38
|
+
let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends System {
|
|
39
|
+
constructor() {
|
|
40
|
+
super(...arguments);
|
|
41
|
+
this.postMessageOrigin = '*';
|
|
42
|
+
this.scope = 'scene';
|
|
43
|
+
this.enabled = false;
|
|
44
|
+
this.outlineGo = null;
|
|
45
|
+
this.selected = null;
|
|
46
|
+
this.tapHandlers = new Map();
|
|
47
|
+
this.tapOwners = new Map();
|
|
48
|
+
/** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */
|
|
49
|
+
this.injectedEvents = new Set();
|
|
50
|
+
this.needsSceneRescan = false;
|
|
51
|
+
this.onWindowSet = (e) => {
|
|
52
|
+
const d = e.detail;
|
|
53
|
+
if (d && typeof d.enabled === 'boolean') {
|
|
54
|
+
this.setEnabled(d.enabled);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
this.onWindowMessage = (e) => {
|
|
58
|
+
const d = e.data;
|
|
59
|
+
if (!d || typeof d !== 'object')
|
|
60
|
+
return;
|
|
61
|
+
if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {
|
|
62
|
+
this.setEnabled(d.enabled);
|
|
63
|
+
}
|
|
64
|
+
else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {
|
|
65
|
+
this.requestSceneRescan();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
this.onGameSet = (payload) => {
|
|
69
|
+
if (payload && typeof payload.enabled === 'boolean') {
|
|
70
|
+
this.setEnabled(payload.enabled);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
this.onGameRefresh = () => {
|
|
74
|
+
this.requestSceneRescan();
|
|
75
|
+
};
|
|
76
|
+
this.onWindowRefresh = () => {
|
|
77
|
+
this.requestSceneRescan();
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
static { this.systemName = 'CombosDevelopmentToolSystem'; }
|
|
81
|
+
init(params) {
|
|
82
|
+
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
83
|
+
this.scope = params?.scope ?? 'scene';
|
|
84
|
+
if (typeof window !== 'undefined') {
|
|
85
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
86
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
87
|
+
window.addEventListener('message', this.onWindowMessage);
|
|
88
|
+
}
|
|
89
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
90
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
91
|
+
if (this.enabled && this.scope === 'scene') {
|
|
92
|
+
this.needsSceneRescan = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
onDestroy() {
|
|
96
|
+
if (typeof window !== 'undefined') {
|
|
97
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
98
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
99
|
+
window.removeEventListener('message', this.onWindowMessage);
|
|
100
|
+
}
|
|
101
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
102
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
103
|
+
this.detachAllTaps();
|
|
104
|
+
this.clearSelection();
|
|
105
|
+
}
|
|
106
|
+
/** Programmatic toggle (same effect as events). */
|
|
107
|
+
setEnabled(on) {
|
|
108
|
+
if (this.enabled === on)
|
|
109
|
+
return;
|
|
110
|
+
this.enabled = on;
|
|
111
|
+
if (!on) {
|
|
112
|
+
this.clearSelection();
|
|
113
|
+
if (this.scope === 'scene') {
|
|
114
|
+
this.detachAllTaps();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else if (this.scope === 'scene') {
|
|
118
|
+
this.needsSceneRescan = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
get isEnabled() {
|
|
122
|
+
return this.enabled;
|
|
123
|
+
}
|
|
124
|
+
update(e) {
|
|
125
|
+
if (this.scope === 'scene' && this.enabled && this.needsSceneRescan) {
|
|
126
|
+
this.needsSceneRescan = false;
|
|
127
|
+
this.attachSceneTree();
|
|
128
|
+
}
|
|
129
|
+
for (const go of [...this.tapOwners.values()]) {
|
|
130
|
+
if (go.destroyed) {
|
|
131
|
+
this.releaseTap(go);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!this.enabled || !this.selected || !this.outlineGo)
|
|
135
|
+
return;
|
|
136
|
+
const gfxComp = this.outlineGo.getComponent(Graphics);
|
|
137
|
+
if (!gfxComp?.graphics)
|
|
138
|
+
return;
|
|
139
|
+
const { width, height } = this.selected.transform.size;
|
|
140
|
+
const g = gfxComp.graphics;
|
|
141
|
+
g.clear();
|
|
142
|
+
const t = typeof performance !== 'undefined' ? performance.now() : e.time;
|
|
143
|
+
const pulse = 0.35 + 0.65 * (0.5 + 0.5 * Math.sin(t * 0.012));
|
|
144
|
+
g.rect(0, 0, Math.max(1, width), Math.max(1, height));
|
|
145
|
+
g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });
|
|
146
|
+
}
|
|
147
|
+
componentChanged(changed) {
|
|
148
|
+
if (this.scope === 'scene')
|
|
149
|
+
return;
|
|
150
|
+
const { type, gameObject, componentName } = changed;
|
|
151
|
+
if (!gameObject || componentName !== 'CombosDevelopmentToolTarget')
|
|
152
|
+
return;
|
|
153
|
+
if (type === OBSERVER_TYPE.ADD) {
|
|
154
|
+
this.ensureTap(gameObject);
|
|
155
|
+
}
|
|
156
|
+
else if (type === OBSERVER_TYPE.REMOVE) {
|
|
157
|
+
this.releaseTap(gameObject);
|
|
158
|
+
if (this.selected === gameObject) {
|
|
159
|
+
this.clearSelection();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */
|
|
164
|
+
requestSceneRescan() {
|
|
165
|
+
if (this.scope !== 'scene' || !this.enabled)
|
|
166
|
+
return;
|
|
167
|
+
this.needsSceneRescan = true;
|
|
168
|
+
}
|
|
169
|
+
attachSceneTree() {
|
|
170
|
+
this.detachAllTaps();
|
|
171
|
+
const list = [];
|
|
172
|
+
for (const tr of this.game.scene.transform.children) {
|
|
173
|
+
this.collectGameObjects(tr.gameObject, list);
|
|
174
|
+
}
|
|
175
|
+
for (const go of list) {
|
|
176
|
+
if (go.name === OUTLINE_GO_NAME)
|
|
177
|
+
continue;
|
|
178
|
+
if (go === this.outlineGo)
|
|
179
|
+
continue;
|
|
180
|
+
this.ensureTap(go);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
collectGameObjects(go, out) {
|
|
184
|
+
out.push(go);
|
|
185
|
+
for (const tr of go.transform.children) {
|
|
186
|
+
this.collectGameObjects(tr.gameObject, out);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
detachAllTaps() {
|
|
190
|
+
for (const go of [...this.tapOwners.values()]) {
|
|
191
|
+
this.releaseTap(go);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
ensureTap(go) {
|
|
195
|
+
let ev = go.getComponent(Event);
|
|
196
|
+
if (!ev) {
|
|
197
|
+
const { width, height } = go.transform.size;
|
|
198
|
+
ev = go.addComponent(new Event({
|
|
199
|
+
hitArea: {
|
|
200
|
+
type: HIT_AREA_TYPE.Rect,
|
|
201
|
+
style: { x: 0, y: 0, width: width || 1, height: height || 1 },
|
|
202
|
+
},
|
|
203
|
+
}));
|
|
204
|
+
this.injectedEvents.add(go.id);
|
|
205
|
+
}
|
|
206
|
+
if (this.tapHandlers.has(go.id))
|
|
207
|
+
return;
|
|
208
|
+
const handler = () => this.onSelect(go);
|
|
209
|
+
this.tapHandlers.set(go.id, handler);
|
|
210
|
+
this.tapOwners.set(go.id, go);
|
|
211
|
+
ev.on('tap', handler);
|
|
212
|
+
}
|
|
213
|
+
releaseTap(go) {
|
|
214
|
+
const handler = this.tapHandlers.get(go.id);
|
|
215
|
+
if (!handler)
|
|
216
|
+
return;
|
|
217
|
+
const ev = go.getComponent(Event);
|
|
218
|
+
ev?.off('tap', handler);
|
|
219
|
+
this.tapHandlers.delete(go.id);
|
|
220
|
+
this.tapOwners.delete(go.id);
|
|
221
|
+
if (this.injectedEvents.has(go.id)) {
|
|
222
|
+
try {
|
|
223
|
+
go.removeComponent(Event);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
/* ignore */
|
|
227
|
+
}
|
|
228
|
+
this.injectedEvents.delete(go.id);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
ensureOutline() {
|
|
232
|
+
if (this.outlineGo)
|
|
233
|
+
return;
|
|
234
|
+
const go = new GameObject(OUTLINE_GO_NAME, {
|
|
235
|
+
size: { width: 1, height: 1 },
|
|
236
|
+
position: { x: 0, y: 0 },
|
|
237
|
+
origin: { x: 0, y: 0 },
|
|
238
|
+
});
|
|
239
|
+
go.addComponent(new Graphics());
|
|
240
|
+
this.outlineGo = go;
|
|
241
|
+
}
|
|
242
|
+
onSelect(go) {
|
|
243
|
+
if (!this.enabled)
|
|
244
|
+
return;
|
|
245
|
+
this.ensureOutline();
|
|
246
|
+
if (!this.outlineGo)
|
|
247
|
+
return;
|
|
248
|
+
this.selected = go;
|
|
249
|
+
if (this.outlineGo.parent) {
|
|
250
|
+
this.outlineGo.remove();
|
|
251
|
+
}
|
|
252
|
+
go.addChild(this.outlineGo);
|
|
253
|
+
const payload = this.serializeGameObject(go);
|
|
254
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
255
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
clearSelection() {
|
|
259
|
+
this.selected = null;
|
|
260
|
+
if (this.outlineGo?.parent) {
|
|
261
|
+
this.outlineGo.remove();
|
|
262
|
+
}
|
|
263
|
+
const gfx = this.outlineGo?.getComponent(Graphics);
|
|
264
|
+
if (gfx?.graphics) {
|
|
265
|
+
gfx.graphics.clear();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
serializeGameObject(go) {
|
|
269
|
+
const tag = go.getComponent(CombosDevelopmentToolTarget);
|
|
270
|
+
const pos = go.transform.position;
|
|
271
|
+
const size = go.transform.size;
|
|
272
|
+
return {
|
|
273
|
+
type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,
|
|
274
|
+
gameObject: {
|
|
275
|
+
name: go.name,
|
|
276
|
+
id: go.id,
|
|
277
|
+
position: { x: pos.x, y: pos.y },
|
|
278
|
+
size: { width: size.width, height: size.height },
|
|
279
|
+
rotation: go.transform.rotation,
|
|
280
|
+
payload: tag?.payload ?? {},
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
CombosDevelopmentToolSystem = __decorate([
|
|
286
|
+
decorators.componentObserver({
|
|
287
|
+
CombosDevelopmentToolTarget: [],
|
|
288
|
+
})
|
|
289
|
+
], CombosDevelopmentToolSystem);
|
|
290
|
+
var CombosDevelopmentToolSystem_default = CombosDevelopmentToolSystem;
|
|
291
|
+
|
|
292
|
+
export { COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, CombosDevelopmentToolSystem_default as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget };
|
|
293
|
+
//# sourceMappingURL=plugin-development-tool.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-development-tool.esm.js","sources":["../lib/constants.ts","../lib/CombosDevelopmentToolTarget.ts","../lib/CombosDevelopmentToolSystem.ts"],"sourcesContent":["/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */\nexport const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set' as const;\n\n/** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */\nexport const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh' as const;\n\n/** Emitted to `window.parent` when an object is selected while the tool is on. */\nexport const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED =\n 'combos-development-tool:gameobject-selected' as const;\n","import { Component, ComponentParams } from '@combos-fun/engine';\n\nexport interface CombosDevelopmentToolTargetParams extends ComponentParams {\n /** Extra JSON-serializable fields included in postMessage to parent. */\n payload?: Record<string, unknown>;\n}\n\n/**\n * Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach\n * extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).\n */\nexport default class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToolTargetParams> {\n static componentName = 'CombosDevelopmentToolTarget';\n\n payload: Record<string, unknown> = {};\n\n init(params?: CombosDevelopmentToolTargetParams) {\n this.payload = params?.payload ? { ...params.payload } : {};\n }\n}\n","import {\n ComponentChanged,\n GameObject,\n OBSERVER_TYPE,\n System,\n UpdateParams,\n decorators,\n} from '@combos-fun/engine';\nimport { Graphics } from '@combos-fun/plugin-renderer-graphics';\nimport { Event, HIT_AREA_TYPE } from '@combos-fun/plugin-renderer-event';\nimport {\n COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,\n COMBOS_DEVELOPMENT_TOOL_REFRESH,\n COMBOS_DEVELOPMENT_TOOL_SET,\n} from './constants';\nimport CombosDevelopmentToolTarget from './CombosDevelopmentToolTarget';\n\nexport type CombosDevelopmentToolSelectScope = 'tagged' | 'scene';\n\nexport interface CombosDevelopmentToolSystemParams {\n /** postMessage `targetOrigin` when notifying parent (default `'*'`). */\n postMessageOrigin?: string;\n /**\n * - `tagged`: only `GameObject`s with {@link CombosDevelopmentToolTarget} participate (optional `payload`).\n * - `scene`: all objects under `game.scene` (except the outline helper) get tap → outline + postMessage; no marker component required (default).\n */\n scope?: CombosDevelopmentToolSelectScope;\n}\n\nconst OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';\n\ntype SetPayload = { enabled?: boolean };\n\n/**\n * **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).\n * Turn on/off via:\n * - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`\n * - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)\n * - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`\n *\n * With `scope: 'scene'`, while enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`, or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.\n */\n@decorators.componentObserver({\n CombosDevelopmentToolTarget: [],\n})\nexport default class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {\n static systemName = 'CombosDevelopmentToolSystem';\n\n private postMessageOrigin = '*';\n private scope: CombosDevelopmentToolSelectScope = 'scene';\n private enabled = false;\n private outlineGo: GameObject | null = null;\n private selected: GameObject | null = null;\n private readonly tapHandlers = new Map<number, () => void>();\n private readonly tapOwners = new Map<number, GameObject>();\n /** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */\n private readonly injectedEvents = new Set<number>();\n private needsSceneRescan = false;\n\n private readonly onWindowSet = (e: globalThis.Event) => {\n const d = (e as unknown as CustomEvent<SetPayload>).detail;\n if (d && typeof d.enabled === 'boolean') {\n this.setEnabled(d.enabled);\n }\n };\n\n private readonly onWindowMessage = (e: MessageEvent) => {\n const d = e.data;\n if (!d || typeof d !== 'object') return;\n if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {\n this.setEnabled(d.enabled);\n } else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {\n this.requestSceneRescan();\n }\n };\n\n private readonly onGameSet = (payload: SetPayload) => {\n if (payload && typeof payload.enabled === 'boolean') {\n this.setEnabled(payload.enabled);\n }\n };\n\n private readonly onGameRefresh = () => {\n this.requestSceneRescan();\n };\n\n private readonly onWindowRefresh = () => {\n this.requestSceneRescan();\n };\n\n init(params?: CombosDevelopmentToolSystemParams) {\n this.postMessageOrigin = params?.postMessageOrigin ?? '*';\n this.scope = params?.scope ?? 'scene';\n\n if (typeof window !== 'undefined') {\n window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);\n window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);\n window.addEventListener('message', this.onWindowMessage);\n }\n this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);\n this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);\n\n if (this.enabled && this.scope === 'scene') {\n this.needsSceneRescan = true;\n }\n }\n\n onDestroy() {\n if (typeof window !== 'undefined') {\n window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);\n window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);\n window.removeEventListener('message', this.onWindowMessage);\n }\n this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);\n this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);\n this.detachAllTaps();\n this.clearSelection();\n }\n\n /** Programmatic toggle (same effect as events). */\n setEnabled(on: boolean) {\n if (this.enabled === on) return;\n this.enabled = on;\n if (!on) {\n this.clearSelection();\n if (this.scope === 'scene') {\n this.detachAllTaps();\n }\n } else if (this.scope === 'scene') {\n this.needsSceneRescan = true;\n }\n }\n\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n update(e: UpdateParams) {\n if (this.scope === 'scene' && this.enabled && this.needsSceneRescan) {\n this.needsSceneRescan = false;\n this.attachSceneTree();\n }\n\n for (const go of [...this.tapOwners.values()]) {\n if (go.destroyed) {\n this.releaseTap(go);\n }\n }\n\n if (!this.enabled || !this.selected || !this.outlineGo) return;\n\n const gfxComp = this.outlineGo.getComponent(Graphics);\n if (!gfxComp?.graphics) return;\n\n const { width, height } = this.selected.transform.size;\n const g = gfxComp.graphics;\n g.clear();\n const t = typeof performance !== 'undefined' ? performance.now() : e.time;\n const pulse = 0.35 + 0.65 * (0.5 + 0.5 * Math.sin(t * 0.012));\n g.rect(0, 0, Math.max(1, width), Math.max(1, height));\n g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });\n }\n\n componentChanged(changed: ComponentChanged) {\n if (this.scope === 'scene') return;\n\n const { type, gameObject, componentName } = changed;\n if (!gameObject || componentName !== 'CombosDevelopmentToolTarget') return;\n\n if (type === OBSERVER_TYPE.ADD) {\n this.ensureTap(gameObject);\n } else if (type === OBSERVER_TYPE.REMOVE) {\n this.releaseTap(gameObject);\n if (this.selected === gameObject) {\n this.clearSelection();\n }\n }\n }\n\n /** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */\n requestSceneRescan() {\n if (this.scope !== 'scene' || !this.enabled) return;\n this.needsSceneRescan = true;\n }\n\n private attachSceneTree() {\n this.detachAllTaps();\n const list: GameObject[] = [];\n for (const tr of this.game.scene.transform.children) {\n this.collectGameObjects(tr.gameObject, list);\n }\n for (const go of list) {\n if (go.name === OUTLINE_GO_NAME) continue;\n if (go === this.outlineGo) continue;\n this.ensureTap(go);\n }\n }\n\n private collectGameObjects(go: GameObject, out: GameObject[]) {\n out.push(go);\n for (const tr of go.transform.children) {\n this.collectGameObjects(tr.gameObject, out);\n }\n }\n\n private detachAllTaps() {\n for (const go of [...this.tapOwners.values()]) {\n this.releaseTap(go);\n }\n }\n\n private ensureTap(go: GameObject) {\n let ev = go.getComponent(Event);\n if (!ev) {\n const { width, height } = go.transform.size;\n ev = go.addComponent(\n new Event({\n hitArea: {\n type: HIT_AREA_TYPE.Rect,\n style: { x: 0, y: 0, width: width || 1, height: height || 1 },\n },\n }),\n );\n this.injectedEvents.add(go.id);\n }\n\n if (this.tapHandlers.has(go.id)) return;\n\n const handler = () => this.onSelect(go);\n this.tapHandlers.set(go.id, handler);\n this.tapOwners.set(go.id, go);\n ev.on('tap', handler);\n }\n\n private releaseTap(go: GameObject) {\n const handler = this.tapHandlers.get(go.id);\n if (!handler) return;\n const ev = go.getComponent(Event);\n ev?.off('tap', handler);\n this.tapHandlers.delete(go.id);\n this.tapOwners.delete(go.id);\n if (this.injectedEvents.has(go.id)) {\n try {\n go.removeComponent(Event);\n } catch {\n /* ignore */\n }\n this.injectedEvents.delete(go.id);\n }\n }\n\n private ensureOutline() {\n if (this.outlineGo) return;\n const go = new GameObject(OUTLINE_GO_NAME, {\n size: { width: 1, height: 1 },\n position: { x: 0, y: 0 },\n origin: { x: 0, y: 0 },\n });\n go.addComponent(new Graphics());\n this.outlineGo = go;\n }\n\n private onSelect(go: GameObject) {\n if (!this.enabled) return;\n\n this.ensureOutline();\n if (!this.outlineGo) return;\n\n this.selected = go;\n\n if (this.outlineGo.parent) {\n this.outlineGo.remove();\n }\n go.addChild(this.outlineGo);\n\n const payload = this.serializeGameObject(go);\n if (typeof window !== 'undefined' && window.parent && window.parent !== window) {\n window.parent.postMessage(payload, this.postMessageOrigin);\n }\n }\n\n private clearSelection() {\n this.selected = null;\n if (this.outlineGo?.parent) {\n this.outlineGo.remove();\n }\n const gfx = this.outlineGo?.getComponent(Graphics);\n if (gfx?.graphics) {\n gfx.graphics.clear();\n }\n }\n\n private serializeGameObject(go: GameObject) {\n const tag = go.getComponent(CombosDevelopmentToolTarget);\n const pos = go.transform.position;\n const size = go.transform.size;\n return {\n type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,\n gameObject: {\n name: go.name,\n id: go.id,\n position: { x: pos.x, y: pos.y },\n size: { width: size.width, height: size.height },\n rotation: go.transform.rotation,\n payload: tag?.payload ?? {},\n },\n };\n }\n}\n"],"names":[],"mappings":"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"}
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@combos-fun/plugin-development-tool",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Scene / tagged object tap development tool: outline overlay and parent postMessage",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "dist/plugin-development-tool.esm.js",
|
|
7
|
+
"bundle": "CombosFun.plugin.developmentTool",
|
|
8
|
+
"unpkg": "dist/CombosFun.plugin.developmentTool.min.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"types": "dist/plugin-development-tool.d.ts",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"combos-fun",
|
|
16
|
+
"game",
|
|
17
|
+
"development-tool"
|
|
18
|
+
],
|
|
19
|
+
"author": "sun668 <q947692259@gmail.com>",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@combos-fun/engine": "0.0.3",
|
|
22
|
+
"@combos-fun/plugin-renderer-event": "0.0.3",
|
|
23
|
+
"@combos-fun/plugin-renderer-graphics": "0.0.3"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "node ../../scripts/build-package.mjs"
|
|
27
|
+
}
|
|
28
|
+
}
|