@combos-fun/plugin-development-tool 0.0.18 → 0.0.20

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.
@@ -1 +1 @@
1
- "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:refresh",a="combos-development-tool:gameobject-selected",c="combos-development-tool:apply-property";class h extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const l=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),d={Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function p(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>p(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=p(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function u(e){const t={},n=d[e.name];for(const o of Object.keys(e)){if(l.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=p(s);void 0!==i&&(t[o]=i)}return t}function f(e){const t=e.getComponent(h),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function m(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:u(e)}));return{id:e.id,name:e.name,components:t,source:f(e)}}function g(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const y=new Set(["position","size","origin","anchor","scale","skew"]);function b(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const w={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=b(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&y.has(n[0])){const t=n[0],s=n[1],r=b(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=b(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function v(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=w[t];return!!i?.(e,s,n,o)||g(e,t,n,o)}const O="__combosDevelopmentToolOutline";let T=class extends t.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.savedTapListeners=new Map,this.injectedEvents=new Set,this.needsSceneRescan=!1,this.needsTaggedRescan=!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===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===r?this.requestSceneRescan():t.type===c&&this.handleApplyProperty(t))},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(i,this.onWindowSet),window.addEventListener(r,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(r,this.onGameRefresh),this.enabled&&"scene"===this.scope?this.needsSceneRescan=!0:this.enabled&&"tagged"===this.scope&&(this.needsTaggedRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(r,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(r,this.onGameRefresh),this.detachAllTaps(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?"scene"===this.scope?this.needsSceneRescan=!0:this.needsTaggedRescan=!0:(this.clearSelection(),this.detachAllTaps()))}get isEnabled(){return this.enabled}update(e){this.enabled&&this.needsSceneRescan&&"scene"===this.scope&&(this.needsSceneRescan=!1,this.attachSceneTree()),this.enabled&&this.needsTaggedRescan&&"tagged"===this.scope&&(this.needsTaggedRescan=!1,this.attachTaggedObjects());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(o.Graphics);if(!t?.graphics)return;const n=this.resolvePickBounds(this.selected),s=t.graphics;s.clear();const i="undefined"!=typeof performance?performance.now():e.time,r=.35+.65*(.5+.5*Math.sin(.012*i));s.rect(n.x,n.y,n.width,n.height),s.stroke({width:4,color:5636010,alpha:r})}componentChanged(e){if("scene"===this.scope)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?this.ensureTap(o):n===t.OBSERVER_TYPE.REMOVE&&(this.releaseTap(o),this.selected===o&&this.clearSelection()))}requestSceneRescan(){this.enabled&&("scene"===this.scope?this.needsSceneRescan=!0:this.needsTaggedRescan=!0)}attachTaggedObjects(){const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)t.name!==O&&t!==this.outlineGo&&t.getComponent(h)&&this.ensureTap(t)}attachSceneTree(){this.detachAllTaps(!1);const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)t.name!==O&&t!==this.outlineGo&&this.ensureTap(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}detachAllTaps(e=!0){for(const t of[...this.tapOwners.values()])this.releaseTap(t,e)}ensureTap(e){let t=e.getComponent(s.Event);if(t||(t=e.addComponent(this.createInjectedEvent(e)),this.injectedEvents.add(e.id)),this.tapHandlers.has(e.id))return;if(!this.savedTapListeners.has(e.id)){const n=t.listeners("tap");this.savedTapListeners.set(e.id,[...n])}t.removeAllListeners("tap");const n=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,n),this.tapOwners.set(e.id,e),t.on("tap",n)}createInjectedEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveContainerLocalBounds(e);if(t)return t}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releaseTap(e,t=!0){const n=this.tapHandlers.get(e.id);if(!n)return;const o=e.getComponent(s.Event);if(o?.off("tap",n),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),t){const t=this.savedTapListeners.get(e.id);if(t&&t.length>0&&o)for(const e of t)o.on("tap",e);if(this.savedTapListeners.delete(e.id),this.injectedEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.injectedEvents.delete(e.id)}}}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(O,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo);const n=m(e),o={type:a,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=f(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;v(i,t,n,e.value)&&this.selected?.id===i.id&&this.postSnapshotUpdate(i)}postSnapshotUpdate(e){const t=m(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:a,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelection(){this.selected=null,this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}};T=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],T);var E=T;Object.assign(E,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.18"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=c,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=a,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=r,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.CombosDevelopmentToolSystem=E,exports.CombosDevelopmentToolTarget=h,exports.applyPropertyValue=g,exports.applyPropertyWithHooks=v,exports.buildGameObjectSnapshot=m,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=f;
1
+ "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/plugin-renderer"),o=require("@combos-fun/plugin-renderer-graphics"),s=require("@combos-fun/plugin-renderer-event");const i="combos-development-tool:set",r="combos-development-tool:set-success",a="combos-development-tool:refresh",c="combos-development-tool:gameobject-selected",h="combos-development-tool:apply-property";class d extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}const l=new Set(["gameObject","name","started","__componentDefaultParams","destroyed","inScene","worldTransform","children","_parent"]),p={Graphics:new Set(["graphics"]),Physics:new Set(["body","Body","PhysicsEngine","World","Constraint","mouseConstraint","bodyParams"]),Event:new Set(["hitArea"])};function u(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>u(e,t+1));if("object"==typeof e){const n={};for(const[o,s]of Object.entries(e)){if("function"==typeof s)continue;const e=u(s,t+1);void 0!==e&&(n[o]=e)}return n}}}function m(e){const t={},n=p[e.name];for(const o of Object.keys(e)){if(l.has(o)||o.startsWith("_"))continue;if(n?.has(o))continue;const s=e[o];if("function"==typeof s)continue;const i=u(s);void 0!==i&&(t[o]=i)}return t}function f(e){const t=e.getComponent(d),n=t?.payload?.source;var o;if((o=n)&&"object"==typeof o&&"string"==typeof o.file)return{file:n.file,anchor:n.anchor??e.name}}function g(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fields:m(e)}));return{id:e.id,name:e.name,components:t,source:f(e)}}function y(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;let i=s;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const b=new Set(["position","size","origin","anchor","scale","skew"]);function w(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const v={Transform:function(e,t,n,o){const s=e.transform??t,i=s;if(1===n.length&&"rotation"===n[0]){const e=w(o);return void 0!==e&&(s.rotation=e,!0)}if(2===n.length&&b.has(n[0])){const t=n[0],s=n[1],r=w(o);if(void 0===r)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[s]=r,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const s=t;if(1===n.length&&"text"===n[0])return s.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...s.style??{},[e]:o};return s.style=t,!0}return!1},Sound:function(e,t,n,o){const s=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=w(o);return void 0!==e&&(s.volume=e,!0)}return!1}};function E(e,t,n,o){const s=e.getComponent(t);if(!s||!n.length)return!1;const i=v[t];return!!i?.(e,s,n,o)||y(e,t,n,o)}const O="__combosDevelopmentToolOutline";let S=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.enabled=!1,this.outlineGo=null,this.selected=null,this.tapHandlers=new Map,this.tapOwners=new Map,this.cachedGameEvents=new Map,this.pickEvents=new Set,this.needsRescan=!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===i&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===a?this.requestSceneRescan():t.type===h&&this.handleApplyProperty(t))},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??"*","undefined"!=typeof window&&(window.addEventListener(i,this.onWindowSet),window.addEventListener(a,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(i,this.onGameSet),this.game.on(a,this.onGameRefresh),this.enabled&&(this.needsRescan=!0)}onDestroy(){"undefined"!=typeof window&&(window.removeEventListener(i,this.onWindowSet),window.removeEventListener(a,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(i,this.onGameSet),this.game.off(a,this.onGameRefresh),this.detachAllPicks(),this.restoreCachedGameEvents(),this.clearSelection()}setEnabled(e){this.enabled!==e&&(this.enabled=e,e?this.needsRescan=!0:(this.clearSelection(),this.detachAllPicks(),this.restoreCachedGameEvents(),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}update(e){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.attachEditMode(),this.postSetSuccess(!0));for(const e of[...this.tapOwners.values()])e.destroyed&&this.releasePick(e);if(!this.enabled||!this.selected||!this.outlineGo)return;const t=this.outlineGo.getComponent(o.Graphics);if(!t?.graphics)return;const n=this.resolvePickBounds(this.selected),s=t.graphics;s.clear();const i="undefined"!=typeof performance?performance.now():e.time,r=.35+.65*(.5+.5*Math.sin(.012*i));s.rect(n.x,n.y,n.width,n.height),s.stroke({width:4,color:5636010,alpha:r})}componentChanged(e){if(!this.enabled)return;const{type:n,gameObject:o,componentName:s}=e;o&&"CombosDevelopmentToolTarget"===s&&(n===t.OBSERVER_TYPE.ADD?(this.stripGameEvent(o),this.ensurePick(o)):n===t.OBSERVER_TYPE.REMOVE&&(this.releasePick(o),this.selected===o&&this.clearSelection()))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0)}attachEditMode(){this.detachAllPicks();const e=[];for(const t of this.game.scene.transform.children)this.collectGameObjects(t.gameObject,e);for(const t of e)this.isIgnoredPickGo(t)||this.stripGameEvent(t);for(const t of e)this.isIgnoredPickGo(t)||t.getComponent(d)&&this.ensurePick(t)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}isIgnoredPickGo(e){return e.name===O||e===this.outlineGo}stripGameEvent(e){if(this.cachedGameEvents.has(e.id))return;if(e.getComponent(s.Event))try{const t=e.removeComponent(s.Event);this.cachedGameEvents.set(e.id,t)}catch{}}restoreCachedGameEvents(){for(const[e,t]of[...this.cachedGameEvents.entries()]){const n=this.findGameObjectById(e);if(!n||n.destroyed||n.getComponent(s.Event))this.cachedGameEvents.delete(e);else{try{n.addComponent(t)}catch{}this.cachedGameEvents.delete(e)}}}detachAllPicks(){for(const e of[...this.tapOwners.values()])this.releasePick(e)}ensurePick(e){if(this.tapHandlers.has(e.id))return;let t=e.getComponent(s.Event);t||(t=e.addComponent(this.createPickEvent(e)),this.pickEvents.add(e.id));const n=t=>this.onSelect(e,t);this.tapHandlers.set(e.id,n),this.tapOwners.set(e.id,e),t.on("tap",n)}createPickEvent(e){const t=this.resolvePickBounds(e);return t.width>0&&t.height>0?new s.Event({hitArea:{type:s.HIT_AREA_TYPE.Rect,style:{x:t.x,y:t.y,width:t.width,height:t.height}}}):new s.Event}resolvePickBounds(e){if(this.shouldPreferRenderedBounds(e)){const t=this.resolveContainerLocalBounds(e);if(t)return t}const{width:t,height:n}=e.transform.size;if(t>0&&n>0)return{x:0,y:0,width:t,height:n};const o=this.resolveContainerLocalBounds(e);return o||{x:0,y:0,width:1,height:1}}shouldPreferRenderedBounds(e){return null!=e.getComponent(o.Graphics)}resolveContainerLocalBounds(e){const t=this.getRendererContainer(e);if(!t)return null;try{const e=t.getLocalBounds();if(e.width>0&&e.height>0)return{x:e.x,y:e.y,width:e.width,height:e.height}}catch{}return null}getRendererContainer(e){const t=this.game.getSystem(n.RendererSystem);if(!t?.containerManager)return null;try{return t.containerManager.getContainer(e.id)}catch{return null}}releasePick(e){const t=this.tapHandlers.get(e.id);if(!t)return;const n=e.getComponent(s.Event);if(n?.off("tap",t),this.tapHandlers.delete(e.id),this.tapOwners.delete(e.id),this.pickEvents.has(e.id)){try{e.removeComponent(s.Event)}catch{}this.pickEvents.delete(e.id)}}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}ensureOutline(){if(this.outlineGo)return;const e=new t.GameObject(O,{size:{width:1,height:1},position:{x:0,y:0},origin:{x:0,y:0}});e.addComponent(new o.Graphics),this.outlineGo=e}onSelect(e,t){if(!this.enabled)return;if(t?.stopPropagation?.(),this.ensureOutline(),!this.outlineGo)return;this.selected=e,this.outlineGo.parent&&this.outlineGo.remove(),e.addChild(this.outlineGo);const n=g(e),o={type:c,snapshot:n,pointer:t?.data?.position??null};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin)}findGameObjectById(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);return t.find(t=>t.id===e)??null}findGameObjectBySource(e){const t=[];for(const e of this.game.scene.transform.children)this.collectGameObjects(e.gameObject,t);const n=e.file.trim(),o=(e.anchor??"").trim();if(!o)return null;for(const e of t){const t=f(e);if(!t||t.file!==n)continue;if((t.anchor??e.name)===o)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,s=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!s||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;E(i,t,n,e.value)&&this.selected?.id===i.id&&this.postSnapshotUpdate(i)}postSnapshotUpdate(e){const t=g(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:c,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelection(){this.selected=null,this.outlineGo?.parent&&this.outlineGo.remove();const e=this.outlineGo?.getComponent(o.Graphics);e?.graphics&&e.graphics.clear()}};S=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],S);var G=S;Object.assign(G,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.20"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=h,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=c,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=a,exports.COMBOS_DEVELOPMENT_TOOL_SET=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS=r,exports.CombosDevelopmentToolSystem=G,exports.CombosDevelopmentToolTarget=d,exports.applyPropertyValue=y,exports.applyPropertyWithHooks=E,exports.buildGameObjectSnapshot=g,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let s=o;for(const e of n){if(null==s||"object"!=typeof s)return;s=s[e]}return s},exports.readSourceAnchor=f;
@@ -2,7 +2,9 @@ import { Component, ComponentParams, System, UpdateParams, ComponentChanged, Gam
2
2
 
3
3
  /** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
4
4
  declare const COMBOS_DEVELOPMENT_TOOL_SET: "combos-development-tool:set";
5
- /** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */
5
+ /** iframe parent: `setEnabled` finished (pick attach after enable, or restore after disable). Payload: `{ enabled: boolean }`. */
6
+ declare const COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS: "combos-development-tool:set-success";
7
+ /** Re-scan the scene tree while the development tool is enabled. */
6
8
  declare const COMBOS_DEVELOPMENT_TOOL_REFRESH: "combos-development-tool:refresh";
7
9
  /** Emitted to `window.parent` when an object is selected while the tool is on. */
8
10
  declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED: "combos-development-tool:gameobject-selected";
@@ -16,8 +18,9 @@ interface CombosDevelopmentToolTargetParams extends ComponentParams {
16
18
  payload?: Record<string, unknown>;
17
19
  }
18
20
  /**
19
- * Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach
20
- * extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).
21
+ * Marks a `GameObject` as selectable in editor pick mode. While the development tool is enabled,
22
+ * only nodes carrying this component receive a pick `Event`; all other game `Event` components
23
+ * are removed and cached until disable.
21
24
  */
22
25
  declare class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToolTargetParams> {
23
26
  static componentName: string;
@@ -25,41 +28,36 @@ declare class CombosDevelopmentToolTarget extends Component<CombosDevelopmentToo
25
28
  init(params?: CombosDevelopmentToolTargetParams): void;
26
29
  }
27
30
 
28
- type CombosDevelopmentToolSelectScope = 'tagged' | 'scene';
29
31
  interface CombosDevelopmentToolSystemParams {
30
32
  /** postMessage `targetOrigin` when notifying parent (default `'*'`). */
31
33
  postMessageOrigin?: string;
32
- /**
33
- * - `tagged`: only `GameObject`s with {@link CombosDevelopmentToolTarget} participate (optional `payload`).
34
- * - `scene`: all objects under `game.scene` (except the outline helper) get tap → outline + postMessage; no marker component required (default).
35
- */
36
- scope?: CombosDevelopmentToolSelectScope;
37
34
  }
38
35
  /**
39
- * **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).
40
- * While enabled, game `Event` `tap` listeners are removed and restored on disable.
36
+ * **Off** at start. While enabled:
37
+ * - strips `Event` from every scene `GameObject` (cached for restore on disable);
38
+ * - attaches pick `Event` + outline only on nodes with {@link CombosDevelopmentToolTarget}.
39
+ *
41
40
  * Turn on/off via:
42
41
  * - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
43
42
  * - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
44
43
  * - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
45
44
  *
46
- * 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.
45
+ * While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
46
+ * or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
47
47
  */
48
48
  declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSystemParams> {
49
49
  static systemName: string;
50
50
  private postMessageOrigin;
51
- private scope;
52
51
  private enabled;
53
52
  private outlineGo;
54
53
  private selected;
55
54
  private readonly tapHandlers;
56
55
  private readonly tapOwners;
57
- /** Game `tap` listeners removed while enabled; restored on disable. */
58
- private readonly savedTapListeners;
59
- /** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */
60
- private readonly injectedEvents;
61
- private needsSceneRescan;
62
- private needsTaggedRescan;
56
+ /** Game `Event` components removed while enabled; restored on disable. */
57
+ private readonly cachedGameEvents;
58
+ /** Pick `Event` injected for {@link CombosDevelopmentToolTarget} nodes. */
59
+ private readonly pickEvents;
60
+ private needsRescan;
63
61
  private readonly onWindowSet;
64
62
  private readonly onWindowMessage;
65
63
  private readonly onGameSet;
@@ -72,19 +70,22 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
72
70
  get isEnabled(): boolean;
73
71
  update(e: UpdateParams): void;
74
72
  componentChanged(changed: ComponentChanged): void;
75
- /** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */
73
+ /** Re-bind pick targets after dynamic scene changes while enabled. */
76
74
  requestSceneRescan(): void;
77
- private attachTaggedObjects;
78
- private attachSceneTree;
75
+ private attachEditMode;
79
76
  private collectGameObjects;
80
- private detachAllTaps;
81
- private ensureTap;
82
- private createInjectedEvent;
77
+ private isIgnoredPickGo;
78
+ private stripGameEvent;
79
+ private restoreCachedGameEvents;
80
+ private detachAllPicks;
81
+ private ensurePick;
82
+ private createPickEvent;
83
83
  private resolvePickBounds;
84
84
  private shouldPreferRenderedBounds;
85
85
  private resolveContainerLocalBounds;
86
86
  private getRendererContainer;
87
- private releaseTap;
87
+ private releasePick;
88
+ private postSetSuccess;
88
89
  private ensureOutline;
89
90
  private onSelect;
90
91
  private findGameObjectById;
@@ -126,5 +127,5 @@ declare function readPropertyValue(go: GameObject, componentName: string, path:
126
127
 
127
128
  declare function applyPropertyWithHooks(go: GameObject, componentName: string, path: string[], value: unknown): boolean;
128
129
 
129
- export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
130
- export type { CombosDevelopmentToolSelectScope, CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
130
+ export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
131
+ export type { CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
@@ -6,7 +6,9 @@ import { Event, HIT_AREA_TYPE } from '@combos-fun/plugin-renderer-event';
6
6
 
7
7
  /** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
8
8
  const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set';
9
- /** Re-scan the scene tree (only when `CombosDevelopmentToolSystem` uses `scope: 'scene'`). */
9
+ /** iframe parent: `setEnabled` finished (pick attach after enable, or restore after disable). Payload: `{ enabled: boolean }`. */
10
+ const COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS = 'combos-development-tool:set-success';
11
+ /** Re-scan the scene tree while the development tool is enabled. */
10
12
  const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh';
11
13
  /** Emitted to `window.parent` when an object is selected while the tool is on. */
12
14
  const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gameobject-selected';
@@ -16,8 +18,9 @@ const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = 'combos-development-tool:apply-pr
16
18
  const COMBOS_DEVELOPMENT_TOOL_READY = 'combos-development-tool:ready';
17
19
 
18
20
  /**
19
- * Optional marker when using `CombosDevelopmentToolSystem` with `scope: 'tagged'`, or to attach
20
- * extra `payload` on specific objects while using `scope: 'scene'` (serialization reads it if present).
21
+ * Marks a `GameObject` as selectable in editor pick mode. While the development tool is enabled,
22
+ * only nodes carrying this component receive a pick `Event`; all other game `Event` components
23
+ * are removed and cached until disable.
21
24
  */
22
25
  class CombosDevelopmentToolTarget extends Component {
23
26
  constructor() {
@@ -48,6 +51,7 @@ const SKIP_KEYS = new Set([
48
51
  '_parent',
49
52
  ]);
50
53
  const COMPONENT_SKIP_KEYS = {
54
+ Graphics: new Set(['graphics']),
51
55
  Physics: new Set([
52
56
  'body',
53
57
  'Body',
@@ -269,31 +273,32 @@ function applyPropertyWithHooks(go, componentName, path, value) {
269
273
 
270
274
  const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
271
275
  /**
272
- * **Defaults:** `scope: 'scene'`, **off** at start (no tap hijack until enabled).
273
- * While enabled, game `Event` `tap` listeners are removed and restored on disable.
276
+ * **Off** at start. While enabled:
277
+ * - strips `Event` from every scene `GameObject` (cached for restore on disable);
278
+ * - attaches pick `Event` + outline only on nodes with {@link CombosDevelopmentToolTarget}.
279
+ *
274
280
  * Turn on/off via:
275
281
  * - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
276
282
  * - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
277
283
  * - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
278
284
  *
279
- * 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.
285
+ * While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
286
+ * or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
280
287
  */
281
288
  let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends System {
282
289
  constructor() {
283
290
  super(...arguments);
284
291
  this.postMessageOrigin = '*';
285
- this.scope = 'scene';
286
292
  this.enabled = false;
287
293
  this.outlineGo = null;
288
294
  this.selected = null;
289
295
  this.tapHandlers = new Map();
290
296
  this.tapOwners = new Map();
291
- /** Game `tap` listeners removed while enabled; restored on disable. */
292
- this.savedTapListeners = new Map();
293
- /** We added `Event` for hit-testing; remove on teardown when disabling / releaseTap. */
294
- this.injectedEvents = new Set();
295
- this.needsSceneRescan = false;
296
- this.needsTaggedRescan = false;
297
+ /** Game `Event` components removed while enabled; restored on disable. */
298
+ this.cachedGameEvents = new Map();
299
+ /** Pick `Event` injected for {@link CombosDevelopmentToolTarget} nodes. */
300
+ this.pickEvents = new Set();
301
+ this.needsRescan = false;
297
302
  this.onWindowSet = (e) => {
298
303
  const d = e.detail;
299
304
  if (d && typeof d.enabled === 'boolean') {
@@ -329,7 +334,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
329
334
  static { this.systemName = 'CombosDevelopmentToolSystem'; }
330
335
  init(params) {
331
336
  this.postMessageOrigin = params?.postMessageOrigin ?? '*';
332
- this.scope = params?.scope ?? 'scene';
333
337
  if (typeof window !== 'undefined') {
334
338
  window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
335
339
  window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
@@ -337,11 +341,8 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
337
341
  }
338
342
  this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
339
343
  this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
340
- if (this.enabled && this.scope === 'scene') {
341
- this.needsSceneRescan = true;
342
- }
343
- else if (this.enabled && this.scope === 'tagged') {
344
- this.needsTaggedRescan = true;
344
+ if (this.enabled) {
345
+ this.needsRescan = true;
345
346
  }
346
347
  }
347
348
  onDestroy() {
@@ -352,7 +353,8 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
352
353
  }
353
354
  this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
354
355
  this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
355
- this.detachAllTaps();
356
+ this.detachAllPicks();
357
+ this.restoreCachedGameEvents();
356
358
  this.clearSelection();
357
359
  }
358
360
  /** Programmatic toggle (same effect as events). */
@@ -362,30 +364,26 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
362
364
  this.enabled = on;
363
365
  if (!on) {
364
366
  this.clearSelection();
365
- this.detachAllTaps();
366
- }
367
- else if (this.scope === 'scene') {
368
- this.needsSceneRescan = true;
367
+ this.detachAllPicks();
368
+ this.restoreCachedGameEvents();
369
+ this.postSetSuccess(false);
369
370
  }
370
371
  else {
371
- this.needsTaggedRescan = true;
372
+ this.needsRescan = true;
372
373
  }
373
374
  }
374
375
  get isEnabled() {
375
376
  return this.enabled;
376
377
  }
377
378
  update(e) {
378
- if (this.enabled && this.needsSceneRescan && this.scope === 'scene') {
379
- this.needsSceneRescan = false;
380
- this.attachSceneTree();
381
- }
382
- if (this.enabled && this.needsTaggedRescan && this.scope === 'tagged') {
383
- this.needsTaggedRescan = false;
384
- this.attachTaggedObjects();
379
+ if (this.enabled && this.needsRescan) {
380
+ this.needsRescan = false;
381
+ this.attachEditMode();
382
+ this.postSetSuccess(true);
385
383
  }
386
384
  for (const go of [...this.tapOwners.values()]) {
387
385
  if (go.destroyed) {
388
- this.releaseTap(go);
386
+ this.releasePick(go);
389
387
  }
390
388
  }
391
389
  if (!this.enabled || !this.selected || !this.outlineGo)
@@ -402,59 +400,45 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
402
400
  g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });
403
401
  }
404
402
  componentChanged(changed) {
405
- if (this.scope === 'scene')
403
+ if (!this.enabled)
406
404
  return;
407
405
  const { type, gameObject, componentName } = changed;
408
406
  if (!gameObject || componentName !== 'CombosDevelopmentToolTarget')
409
407
  return;
410
408
  if (type === OBSERVER_TYPE.ADD) {
411
- this.ensureTap(gameObject);
409
+ this.stripGameEvent(gameObject);
410
+ this.ensurePick(gameObject);
412
411
  }
413
412
  else if (type === OBSERVER_TYPE.REMOVE) {
414
- this.releaseTap(gameObject);
413
+ this.releasePick(gameObject);
415
414
  if (this.selected === gameObject) {
416
415
  this.clearSelection();
417
416
  }
418
417
  }
419
418
  }
420
- /** Re-bind scene taps when `scope === 'scene'` (e.g. after dynamic spawn). */
419
+ /** Re-bind pick targets after dynamic scene changes while enabled. */
421
420
  requestSceneRescan() {
422
421
  if (!this.enabled)
423
422
  return;
424
- if (this.scope === 'scene') {
425
- this.needsSceneRescan = true;
426
- }
427
- else {
428
- this.needsTaggedRescan = true;
429
- }
423
+ this.needsRescan = true;
430
424
  }
431
- attachTaggedObjects() {
425
+ attachEditMode() {
426
+ this.detachAllPicks();
432
427
  const list = [];
433
428
  for (const tr of this.game.scene.transform.children) {
434
429
  this.collectGameObjects(tr.gameObject, list);
435
430
  }
436
431
  for (const go of list) {
437
- if (go.name === OUTLINE_GO_NAME)
438
- continue;
439
- if (go === this.outlineGo)
440
- continue;
441
- if (!go.getComponent(CombosDevelopmentToolTarget))
432
+ if (this.isIgnoredPickGo(go))
442
433
  continue;
443
- this.ensureTap(go);
444
- }
445
- }
446
- attachSceneTree() {
447
- this.detachAllTaps(false);
448
- const list = [];
449
- for (const tr of this.game.scene.transform.children) {
450
- this.collectGameObjects(tr.gameObject, list);
434
+ this.stripGameEvent(go);
451
435
  }
452
436
  for (const go of list) {
453
- if (go.name === OUTLINE_GO_NAME)
437
+ if (this.isIgnoredPickGo(go))
454
438
  continue;
455
- if (go === this.outlineGo)
439
+ if (!go.getComponent(CombosDevelopmentToolTarget))
456
440
  continue;
457
- this.ensureTap(go);
441
+ this.ensurePick(go);
458
442
  }
459
443
  }
460
444
  collectGameObjects(go, out) {
@@ -463,30 +447,58 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
463
447
  this.collectGameObjects(tr.gameObject, out);
464
448
  }
465
449
  }
466
- detachAllTaps(restore = true) {
467
- for (const go of [...this.tapOwners.values()]) {
468
- this.releaseTap(go, restore);
450
+ isIgnoredPickGo(go) {
451
+ return go.name === OUTLINE_GO_NAME || go === this.outlineGo;
452
+ }
453
+ stripGameEvent(go) {
454
+ if (this.cachedGameEvents.has(go.id))
455
+ return;
456
+ const ev = go.getComponent(Event);
457
+ if (!ev)
458
+ return;
459
+ try {
460
+ const removed = go.removeComponent(Event);
461
+ this.cachedGameEvents.set(go.id, removed);
462
+ }
463
+ catch {
464
+ /* ignore */
469
465
  }
470
466
  }
471
- ensureTap(go) {
472
- let ev = go.getComponent(Event);
473
- if (!ev) {
474
- ev = go.addComponent(this.createInjectedEvent(go));
475
- this.injectedEvents.add(go.id);
467
+ restoreCachedGameEvents() {
468
+ for (const [id, event] of [...this.cachedGameEvents.entries()]) {
469
+ const go = this.findGameObjectById(id);
470
+ if (!go || go.destroyed || go.getComponent(Event)) {
471
+ this.cachedGameEvents.delete(id);
472
+ continue;
473
+ }
474
+ try {
475
+ go.addComponent(event);
476
+ }
477
+ catch {
478
+ /* ignore */
479
+ }
480
+ this.cachedGameEvents.delete(id);
481
+ }
482
+ }
483
+ detachAllPicks() {
484
+ for (const go of [...this.tapOwners.values()]) {
485
+ this.releasePick(go);
476
486
  }
487
+ }
488
+ ensurePick(go) {
477
489
  if (this.tapHandlers.has(go.id))
478
490
  return;
479
- if (!this.savedTapListeners.has(go.id)) {
480
- const existing = ev.listeners('tap');
481
- this.savedTapListeners.set(go.id, [...existing]);
491
+ let ev = go.getComponent(Event);
492
+ if (!ev) {
493
+ ev = go.addComponent(this.createPickEvent(go));
494
+ this.pickEvents.add(go.id);
482
495
  }
483
- ev.removeAllListeners('tap');
484
496
  const handler = payload => this.onSelect(go, payload);
485
497
  this.tapHandlers.set(go.id, handler);
486
498
  this.tapOwners.set(go.id, go);
487
499
  ev.on('tap', handler);
488
500
  }
489
- createInjectedEvent(go) {
501
+ createPickEvent(go) {
490
502
  const bounds = this.resolvePickBounds(go);
491
503
  if (bounds.width > 0 && bounds.height > 0) {
492
504
  return new Event({
@@ -501,12 +513,9 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
501
513
  },
502
514
  });
503
515
  }
504
- // Let Pixi use natural rendered bounds instead of forcing a 1×1 hit area.
505
516
  return new Event();
506
517
  }
507
518
  resolvePickBounds(go) {
508
- // Graphics draws in arbitrary local coordinates (often centered at 0,0).
509
- // transform.size is a layout box from (0,0) and must not override Pixi bounds.
510
519
  if (this.shouldPreferRenderedBounds(go)) {
511
520
  const fromGraphics = this.resolveContainerLocalBounds(go);
512
521
  if (fromGraphics) {
@@ -557,7 +566,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
557
566
  return null;
558
567
  }
559
568
  }
560
- releaseTap(go, restore = true) {
569
+ releasePick(go) {
561
570
  const handler = this.tapHandlers.get(go.id);
562
571
  if (!handler)
563
572
  return;
@@ -565,24 +574,25 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
565
574
  ev?.off('tap', handler);
566
575
  this.tapHandlers.delete(go.id);
567
576
  this.tapOwners.delete(go.id);
568
- if (restore) {
569
- const saved = this.savedTapListeners.get(go.id);
570
- if (saved && saved.length > 0 && ev) {
571
- for (const fn of saved) {
572
- ev.on('tap', fn);
573
- }
577
+ if (this.pickEvents.has(go.id)) {
578
+ try {
579
+ go.removeComponent(Event);
574
580
  }
575
- this.savedTapListeners.delete(go.id);
576
- if (this.injectedEvents.has(go.id)) {
577
- try {
578
- go.removeComponent(Event);
579
- }
580
- catch {
581
- /* ignore */
582
- }
583
- this.injectedEvents.delete(go.id);
581
+ catch {
582
+ /* ignore */
584
583
  }
584
+ this.pickEvents.delete(go.id);
585
+ }
586
+ }
587
+ postSetSuccess(enabled) {
588
+ const payload = {
589
+ type: COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS,
590
+ enabled,
591
+ };
592
+ if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
593
+ window.parent.postMessage(payload, this.postMessageOrigin);
585
594
  }
595
+ this.game.emit(COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, { enabled });
586
596
  }
587
597
  ensureOutline() {
588
598
  if (this.outlineGo)
@@ -713,8 +723,8 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
713
723
  /** Auto-generated by scripts/build-package.mjs — do not edit. */
714
724
  Object.assign(CombosDevelopmentToolSystem$1, {
715
725
  packageName: "@combos-fun/plugin-development-tool",
716
- packageVersion: "0.0.18",
726
+ packageVersion: "0.0.20",
717
727
  });
718
728
 
719
- export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
729
+ export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, applyPropertyValue, applyPropertyWithHooks, buildGameObjectSnapshot, readPropertyValue, readSourceAnchor };
720
730
  //# sourceMappingURL=plugin-development-tool.esm.js.map