@combos-fun/engine 0.1.3 → 0.1.4-beta.1
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/engine.cjs.js +35 -8
- package/dist/engine.cjs.js.map +1 -1
- package/dist/engine.cjs.prod.js +1 -1
- package/dist/engine.d.ts +16 -5
- package/dist/engine.esm.js +35 -8
- package/dist/engine.esm.js.map +1 -1
- package/package.json +2 -2
- package/references/public-api.md +2 -2
package/dist/engine.cjs.prod.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("eventemitter3"),t=require("lodash-es"),s=require("resource-loader");function r(e){return e&&e.__esModule?e:{default:e}}var o,n=r(e);class a extends n.default{get game(){return this.gameObject?.scene?.game}constructor(e){super(),this.started=!1;const t=this.constructor;this.name=t.componentName,this.__componentDefaultParams=e}}exports.OBSERVER_TYPE=void 0,(o=exports.OBSERVER_TYPE||(exports.OBSERVER_TYPE={})).ADD="ADD",o.REMOVE="REMOVE",o.CHANGE="CHANGE";const i={},c={},p={},m={};function h(e,t){i[e.gameObject.id]||(i[e.gameObject.id]={});const s=i[e.gameObject.id],r=e.name+"_"+t.join(",");if(s[r])return s[r];const o=t.length-1;let n=e;for(let e=0;e<o;e++){if(void 0===n[t[e]]||null===n[t[e]])return{property:void 0,key:void 0};n=n[t[e]]}return s[r]={property:n,key:t[o]},s[r]}function u({systemName:e,componentName:t,component:s,prop:r,type:o,gameObject:n}){c[e]?.componentObserver?.add({component:s,prop:r,type:o,componentName:t,gameObject:n})}const l="GameObject";function d(e,t,s=exports.OBSERVER_TYPE.CHANGE){if(!e)return;const r={prop:[t],deep:!1};for(const o in p){const n=p[o]?.[l];n?.some(e=>e.prop[0]===t)&&u({systemName:o,componentName:l,component:void 0,gameObject:e,prop:r,type:s})}}function y({obj:e,key:s,prop:r,component:o,componentName:n}){if(void 0!==e)if(s in e){if(Object.defineProperty(e,`_${s}`,{enumerable:!1,writable:!0,value:e[s]}),r.deep&&t.isObject(e[s]))for(const t of Object.keys(e[s]))y({obj:e[s],key:t,prop:r,component:o,componentName:n});Object.defineProperty(e,s,{enumerable:!0,set(a){e[`_${s}`]!==a&&(e[`_${s}`]=a,function({prop:e,component:s,componentName:r}){for(const o in p){const n=(p[o]||{})[r];n&&(n.findIndex(s=>t.isEqual(s,e))>-1&&u({systemName:o,componentName:r,component:s,prop:e,type:exports.OBSERVER_TYPE.CHANGE}))}}({prop:r,component:o,componentName:n}))},get:()=>e[`_${s}`]})}else console.error(`prop ${s} not in component: ${n}, Can not observer`)}function f(e,t=e.name){for(const s in p){(p[s]||{})[t]&&c[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.REMOVE,componentName:t})}!function(e){e.gameObject&&delete i[e.gameObject.id]}(e)}let g=0;class E{constructor(e){this._parent=null,this._componentCache={},this.children=[],this.inScene=!1,this.components=[],this.destroyed=!1,this._name=e,this.id=++g}get parent(){return this._parent}get name(){return this._name}set scene(e){if(this._scene===e)return;const t=this._scene;this._scene=e;for(const t of this.children)t.scene=e;e?e.addGameObject(this):t&&t.removeGameObject(this)}get scene(){return this._scene}addChild(e){if(e&&e!==this){if(!(e instanceof E))throw new Error("addChild only receive GameObject");if(this.destroyed)throw new Error(`gameObject '${this.name}' has been destroy`);if(e.parent===this){const t=this.children.indexOf(e);return t>-1&&this.children.splice(t,1),void this.children.push(e)}e.parent&&e.parent.removeChild(e),e._parent=this,this.children.push(e),e.scene=this.scene,d(e,"parent",exports.OBSERVER_TYPE.CHANGE)}}removeChild(e){if(!(e instanceof E&&e.parent&&e.parent===this))return e;const t=this.children.indexOf(e);return t>-1&&this.children.splice(t,1),e._parent=null,e.scene=null,d(e,"parent",exports.OBSERVER_TYPE.CHANGE),e}addComponent(e,t){if(this.destroyed)return;const s=function(e){return e instanceof a?e.name:e instanceof Function?e.componentName:void 0}(e);if(this._componentCache[s])return;let r;if(e instanceof Function)r=new e(t);else{if(!(e instanceof a))throw new Error("addComponent recieve Component and Component Constructor");r=e}if(r.gameObject)throw new Error(`component has been added on gameObject ${r.gameObject.name}`);return r.gameObject=this,r.init&&r.init(r.__componentDefaultParams),function(e,t=e.name){for(const s in p)(p[s]||{})[t]&&c[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.ADD,componentName:t})}(r,r.name),function(e,t=e.name){if(t&&m[t]){if(!(e&&(s=e,s&&s.constructor&&"componentName"in s.constructor)))throw new Error("component param must be an instance of Component");var s;if(!e.gameObject||!e.gameObject.id)throw new Error("component should be add to a gameObject");for(const s of m[t]){const{property:r,key:o}=h(e,s.prop);y({obj:r,key:o,prop:s,component:e,componentName:t})}}}(r,r.name),this.components.push(r),this._componentCache[s]=r,r.awake&&r.awake(),r}removeComponent(e){let t;return"string"==typeof e?t=e:e instanceof a?t=e.name:e.componentName&&(t=e.componentName),this._removeComponent(t)}_removeComponent(e){const t=this.components.findIndex(({name:t})=>t===e);if(-1===t)return;const s=this.components.splice(t,1)[0];return delete this._componentCache[e],delete s.__componentDefaultParams,s.onDestroy&&s.onDestroy(),f(s,e),s.gameObject=void 0,s}getComponent(e){let t;return"string"==typeof e?t=e:e instanceof a?t=e.name:e.componentName&&(t=e.componentName),void 0!==this._componentCache[t]?this._componentCache[t]:void 0}remove(){if(this.parent)return this.parent.removeChild(this)}destroy(){if(this.destroyed)console.error("Cannot destroy gameObject that have already been destroyed.");else{Array.from(this.children).forEach(e=>{e.destroy()}),this.remove(),this.children.length=0;for(const e in this._componentCache)this._removeComponent(e);this.components.length=0,this.destroyed=!0}}}class S{constructor(){this.events=[]}add({component:e,prop:s,type:r,componentName:o,gameObject:n}){const a=n??e?.gameObject;if(r===exports.OBSERVER_TYPE.REMOVE){const t=t=>e?t.component===e:t.gameObject===a&&t.componentName===o;if(this.events.find(e=>t(e)&&e.type===exports.OBSERVER_TYPE.ADD))return void(this.events=this.events.filter(e=>!t(e)));this.events=this.events.filter(e=>!t(e))}const i=this.events.findIndex(n=>n.gameObject===a&&n.component===e&&n.componentName===o&&t.isEqual(n.prop,s)&&n.type===r);i>-1&&this.events.splice(i,1),this.events.push({gameObject:a,component:e,prop:s,type:r,componentName:o})}getChanged(){return this.events}get changed(){return this.events}clear(){const e=this.events;return this.events=[],e}}class b{constructor(e){this.started=!1,this.componentObserver=new S,this.__systemDefaultParams=e;const t=this.constructor;this.name=t.systemName}destroy(){this.componentObserver=null,this.__systemDefaultParams=null,this.onDestroy?.()}}const T=function(){let e=null;return e=Date.now?Date.now:()=>(new Date).getTime(),e}(),R={originTime:0,playbackRate:1};class O{constructor(e,t){e instanceof O&&(t=e,e={}),e=Object.assign({},R,e),t&&(this._parent=t),this._createTime=T(),this._timeMark=[{globalTime:this.globalTime,localTime:-e.originTime,entropy:-e.originTime,playbackRate:e.playbackRate,globalEntropy:0}],this._parent&&(this._timeMark[0].globalEntropy=this._parent.entropy),this._playbackRate=e.playbackRate}get globalTime(){return this.parent?this.parent.currentTime:T()-this._createTime}get parent(){return this._parent}get lastTimeMark(){return this._timeMark[this._timeMark.length-1]}markTime({time:e=this.currentTime,entropy:t=this.entropy,playbackRate:s=this.playbackRate}={}){const r={globalTime:this.globalTime,localTime:e,entropy:t,playbackRate:s,globalEntropy:this.globalEntropy};this._timeMark.push(r)}get currentTime(){const{localTime:e,globalTime:t}=this.lastTimeMark;return e+(this.globalTime-t)*this.playbackRate}set currentTime(e){this.markTime({time:e})}get globalEntropy(){return this._parent?this._parent.entropy:this.globalTime}get entropy(){const{entropy:e,globalEntropy:t}=this.lastTimeMark;return e+Math.abs((this.globalEntropy-t)*this.playbackRate)}set entropy(e){if(this.entropy>e){const t=this.seekTimeMark(e);this._timeMark.length=t+1}this.markTime({entropy:e})}fork(e){return new O(e,this)}seekGlobalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{entropy:r,playbackRate:o,globalTime:n}=s;return n+(e-r)/Math.abs(o)}seekLocalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{localTime:r,entropy:o,playbackRate:n}=s;return n>0?r+(e-o):r-(e-o)}seekTimeMark(e){const t=this._timeMark;let s=0,r=t.length-1;if(e<=t[s].entropy)return s;if(e>=t[r].entropy)return r;let o=Math.floor((s+r)/2);for(;o>s&&o<r;){if(e===t[o].entropy)return o;e<t[o].entropy?r=o:e>t[o].entropy&&(s=o),o=Math.floor((s+r)/2)}return s}get playbackRate(){return this._playbackRate}set playbackRate(e){e!==this.playbackRate&&(this.markTime({playbackRate:e}),this._playbackRate=e)}get paused(){if(0===this.playbackRate)return!0;let e=this.parent;for(;e;){if(0===e.playbackRate)return!0;e=e.parent}return!1}}const _={autoStart:!0,frameRate:60};class x{constructor(e){e=Object.assign({},_,e),this._frameCount=0,this._frameDuration=1e3/e.frameRate,this.autoStart=e.autoStart,this.frameRate=e.frameRate,this.timeline=new O({originTime:0,playbackRate:1}),this._lastFrameTime=this.timeline.currentTime,this._tickers=new Set,this._requestId=null,this._ticker=()=>{this._started&&(this._requestId=requestAnimationFrame(this._ticker),this.update())},this.autoStart&&this.start()}update(){const e=this.timeline.currentTime,t=e-this._lastFrameTime;if(t>=this._frameDuration){const s=e-t%this._frameDuration,r=s-this._lastFrameTime;this._lastFrameTime=s;const o={deltaTime:r,delta:r,time:s,currentTime:s,frameCount:++this._frameCount,fps:Math.round(1e3/r)};for(const e of this._tickers)"function"==typeof e&&e(o)}}add(e){this._tickers.add(e)}remove(e){this._tickers.delete(e)}start(){this._started||(this._started=!0,this.timeline.playbackRate=1,this._requestId=requestAnimationFrame(this._ticker))}pause(){this._started=!1,this.timeline.playbackRate=0}setPlaybackRate(e){this.timeline.playbackRate=e}}class L extends E{constructor(e){super(e),this.gameObjects=[],this.scene=this}addGameObject(e){this.gameObjects.push(e),e.inScene||(e.inScene=!0,d(e,"inScene",exports.OBSERVER_TYPE.CHANGE))}removeGameObject(e){const t=this.gameObjects.indexOf(e);-1!==t&&(e.inScene&&(e.inScene=!1,d(e,"inScene",exports.OBSERVER_TYPE.CHANGE)),this.gameObjects.splice(t,1))}destroy(){this.scene=null,super.destroy(),this.gameObjects=null,this.canvas=null}}const k="0.1.3",v="combos-game:plugin-init-success",w="combos-game:ready",A="combos-game:set-playing",M="combos-game:state-changed";function C(e,t){if("undefined"!=typeof window&&window.parent&&window.parent!==window)try{window.parent.postMessage(e,t)}catch{}}function N(e,t="*"){C({type:v,systemName:e.systemName,engineVersion:k,...e.packageName?{packageName:e.packageName}:{},...e.packageVersion?{packageVersion:e.packageVersion}:{}},t)}function j(e,t="*"){C({type:w,engineVersion:k,...void 0===e?{}:{error:e instanceof Error?e.message:String(e)}},t)}function X(e,t="*"){C({type:M,playing:e.playing,started:e.started},t)}function P(e){if(!e||"object"!=typeof e)return null;const t=e;return t.type!==A||"boolean"!=typeof t.playing?null:t.playing}const I=["knoffice.tech","converge.ai"];function D(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let s;try{s=new URL(e)}catch{return!1}const r=e.toLowerCase(),o=s.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(r===t.toLowerCase())return!0;continue}const s=t.toLowerCase().replace(/^\./,"");if(o===s||o.endsWith(`.${s}`))return!0}return!1}function V(e){if(!e?.length)return[...I];if(e.includes("*"))return["*"];const t=new Set,s=[];for(const r of[...I,...e]){const e=r.trim();e&&!t.has(e)&&(t.add(e),s.push(e))}return s}function G(e){if("systemName"in e){const t=e.systemName;if("string"==typeof t)return t}return"UnknownSystem"}function $(e){const t=e;return{packageName:"string"==typeof t.packageName?t.packageName:void 0,packageVersion:"string"==typeof t.packageVersion?t.packageVersion:void 0}}var B;exports.LOAD_SCENE_MODE=void 0,(B=exports.LOAD_SCENE_MODE||(exports.LOAD_SCENE_MODE={})).SINGLE="SINGLE",B.MULTI_CANVAS="MULTI_CANVAS";const U=e=>{if((e instanceof b||e instanceof a)&&!e.started){e.started=!0;try{e.start&&e.start()}catch(t){e instanceof a?console.error(`${function(e){if("componentName"in e){const t=e.componentName;if("string"==typeof t)return t}return"UnknownComponent"}(e.constructor)} start error`,t):console.error(`${G(e.constructor)} start error`,t)}}};class H extends n.default{constructor({systems:e,frameRate:t=60,autoStart:s=!0,needScene:r=!0,onSystemsBootstrapComplete:o,pluginInitNotifyTargetOrigin:n="*",allowedMessageOrigins:a}={}){if(super(),this.playing=!1,this.started=!1,this.multiScenes=[],this.systems=[],this.pluginInitNotifyTargetOrigin="*",this.allowedMessageOrigins=V(),this.onHostMessage=e=>{if(!D(e.origin,this.allowedMessageOrigins))return;const t=P(e.data);null!==t&&this.setPlaying(t)},this.pluginInitNotifyTargetOrigin=n,this.allowedMessageOrigins=V(a),this.ticker=new x({autoStart:!1,frameRate:t}),this.initTicker(),"undefined"!=typeof window&&window.addEventListener("message",this.onHostMessage),e&&e.length){const t=[...e];this.bootstrapSystemsAndMaybeStart(t,r,s,o)}else o?.(this),this.notifyReady()}setPlaying(e){e?this.started?this.resume():this.start():this.pause()}notifyReady(e){j(e,this.pluginInitNotifyTargetOrigin)}notifyStateChanged(){X({playing:this.playing,started:this.started},this.pluginInitNotifyTargetOrigin)}async bootstrapSystemsAndMaybeStart(e,t,s,r){let o;try{for(const t of e)await this.addSystem(t);t&&this.loadScene({scene:new L("scene")}),s&&this.start()}catch(e){o=e,console.error("Game bootstrap failed",e)}finally{r?.(this,o),this.notifyReady(o)}}get scene(){return this._scene}set scene(e){this._scene=e}get gameObjects(){return(e=>{const t=e?.scene?.gameObjects||[],s=e?.multiScenes.map(({gameObjects:e})=>e);let r=[];for(const e of s)r=[...r,...e];return[...t,...r]})(this)}async addSystem(e,s){let r;if(e instanceof Function)r=new e(s);else{if(!(e instanceof b))return void console.warn("can only add System");r=e}if(!this.systems.find(e=>e.constructor===r.constructor)){r.game=this,r.init&&await Promise.resolve(r.init(r.__systemDefaultParams)),N({systemName:G(r.constructor),...$(r.constructor)},this.pluginInitNotifyTargetOrigin),function(e,t){p[t.systemName]=t.observerInfo,c[t.systemName]=e}(r,r.constructor),function(e){const s=[];e instanceof Array?s.push(...e):s.push(e);for(const e of s)for(const s in e.observerInfo){m[s]=m[s]||[];const r=m[s];for(const o of e.observerInfo[s])-1===r.findIndex(e=>t.isEqual(e,o))&&m[s].push(o)}}(r.constructor);try{r.awake&&r.awake()}catch(e){console.error(`${G(r.constructor)} awake error`,e)}return this.systems.push(r),r}console.warn(`${G(r.constructor)} System has been added`)}removeSystem(e){if(!e)return;let t=-1;"string"==typeof e?t=this.systems.findIndex(t=>t.name===e):e instanceof Function?t=this.systems.findIndex(t=>t.constructor===e):e instanceof b&&(t=this.systems.findIndex(t=>t===e)),t>-1&&(this.systems[t].destroy&&this.systems[t].destroy(),this.systems.splice(t,1))}getSystem(e){return this.systems.find(t=>"string"==typeof e?t.name===e:t instanceof e)}pause(){this.playing&&(this.playing=!1,this.ticker.pause(),this.triggerPause(),this.notifyStateChanged())}start(){this.playing||(this.playing=!0,this.started=!0,this.ticker.start(),this.notifyStateChanged())}resume(){this.playing||(this.playing=!0,this.ticker.start(),this.triggerResume(),this.notifyStateChanged())}initTicker(){this.ticker.add(e=>{this.scene&&((e,t=[])=>{for(const s of t)for(const t of s.components)try{U(t),t.update&&t.update(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} update error`,e)}for(const s of t)for(const t of s.components)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} lateUpdate error`,e)}})(e,this.gameObjects);for(const t of this.systems)try{U(t),t.update&&t.update(e)}catch(e){console.error(`${G(t.constructor)} update error`,e)}for(const t of this.systems)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`${G(t.constructor)} lateUpdate error`,e)}})}triggerResume(){(e=>{for(const t of e)for(const e of t.components)try{e.onResume&&e.onResume()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onResume error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onResume&&e.onResume()}catch(t){console.error(`${G(e.constructor)}, onResume error`,t)}}triggerPause(){(e=>{for(const t of e)for(const e of t.components)try{e.onPause&&e.onPause()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onPause error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onPause&&e.onPause()}catch(t){console.error(`${G(e.constructor)}, onPause error`,t)}}destroySystems(){for(const e of[...this.systems])this.removeSystem(e);this.systems.length=0}destroy(){"undefined"!=typeof window&&window.removeEventListener("message",this.onHostMessage),this.removeAllListeners(),this.pause(),this.scene.destroy(),this.destroySystems(),this.ticker=null,this.scene=null,this.canvas=null,this.multiScenes=null}loadScene({scene:e,mode:t=exports.LOAD_SCENE_MODE.SINGLE,params:s={}}){if(e){switch(e.game=this,t){case exports.LOAD_SCENE_MODE.SINGLE:this.scene=e;break;case exports.LOAD_SCENE_MODE.MULTI_CANVAS:this.multiScenes.push(e)}this.emit("sceneChanged",{scene:e,mode:t,params:s})}}}function Y(e,t){e.constructor.IDEProps||(e.constructor.IDEProps=[]),e.constructor.IDEProps.push(t)}function F(e={}){return function(t){if(!t.observerInfo){for(const t in e)for(const s in e[t]){let r;"string"==typeof e[t][s]&&(e[t][s]=[e[t][s]]),Array.isArray(e[t][s])&&(r={prop:e[t][s],deep:!1},e[t][s]=r),r=e[t][s],"string"==typeof r.prop&&(r.prop=[r.prop])}t.observerInfo=e}}}var q;exports.LOAD_EVENT=void 0,(q=exports.LOAD_EVENT||(exports.LOAD_EVENT={})).START="start",q.PROGRESS="progress",q.LOADED="loaded",q.COMPLETE="complete",q.ERROR="error";class z extends n.default{constructor({resource:e,resourceTotal:t}){super(),this.progress=0,this.resourceTotal=0,this.resourceLoadedCount=0,this.resource=e,this.resourceTotal=t,0===t&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}onStart(){this.resource.emit(exports.LOAD_EVENT.START,this)}onProgress(e){this.resourceLoadedCount++,this.progress=Math.floor(this.resourceLoadedCount/this.resourceTotal*100)/100,e.success?this.resource.emit(exports.LOAD_EVENT.LOADED,this,e):this.resource.emit(exports.LOAD_EVENT.ERROR,this,e),this.resource.emit(exports.LOAD_EVENT.PROGRESS,this,e),this.resourceLoadedCount===this.resourceTotal&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}}const J={image:"png",json:"json",tex:"tex",ske:"ske",audio:"audio",video:"video",model:"glb",mtl:"mtl",bin:"bin",vertex:"vert",fragment:"frag"},W={png:"png",jpg:"jpg",jpeg:"jpeg",webp:"webp",json:"json",tex:"tex",ske:"ske",mp3:"audio",wav:"audio",aac:"audio",ogg:"audio",mp4:"video",webm:"video",glb:"glb",gltf:"gltf",fbx:"fbx",obj:"obj",mtl:"mtl",stl:"stl",dae:"dae",ply:"ply",bin:"bin",vert:"vert",frag:"frag",glsl:"glsl"};function K(e,t){return W[function(e){const t=e.split("?")[0].split("#")[0],s=t.lastIndexOf(".");return s<0?"":t.slice(s+1).toLowerCase()}(e)]||J[t]||"png"}function Q(e,t,s){if("string"==typeof t){const r=t.trim();if(!r)throw Z(s,e);return{type:K(r,e),url:r}}if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`Resource "${s}" src.${e} must be a url string or { type, url }.`);const r=t;if("data"===r.type)return r;const o="string"==typeof r.url?r.url.trim():"";if(!o)throw Z(s,e);return{...r,type:r.type||K(o,e),url:o}}function Z(e,t){return new Error(`Resource "${e}" src.${t}.url is required. Use { type, url } (e.g. { type: "webp", url: "https://..." }). A flat path string is also accepted and will be normalized.`)}function ee(e,t,s="(unnamed)"){if(null==e)throw new Error(`Resource "${s}" src is required.`);if("string"==typeof e){const r=function(e){return"AUDIO"===e?"audio":"VIDEO"===e?"video":"MODEL"===e||"GLB"===e?"model":"SHADER"===e?"fragment":"image"}(t);return{[r]:Q(r,e,s)}}if("object"!=typeof e||Array.isArray(e))throw new Error(`Resource "${s}" src must be a url string or a slot object.`);const r={};for(const[t,o]of Object.entries(e))null!=o&&(r[t]=Q(t,o,s));if(0===Object.keys(r).length)throw new Error(`Resource "${s}" src has no loadable slots.`);return r}const te={AbstractLoadStrategy:s.AbstractLoadStrategy,AudioLoadStrategy:s.AudioLoadStrategy,ImageLoadStrategy:s.ImageLoadStrategy,XhrResponseType:s.XhrResponseType,MediaElementLoadStrategy:s.MediaElementLoadStrategy,VideoLoadStrategy:s.VideoLoadStrategy,XhrLoadStrategy:s.XhrLoadStrategy,Loader:s.Loader,Resource:s.Resource,ResourceType:s.ResourceType,ResourceState:s.ResourceState};function se(e){const t=e.frame;return t&&"object"==typeof t?{...e,frame:t,rotated:Boolean(e.rotated),trimmed:Boolean(e.trimmed),spriteSourceSize:e.spriteSourceSize,sourceSize:e.sourceSize}:null}function re(e,t,s){for(const r of e){if(!r||"object"!=typeof r)continue;const e=r,o=String(e.filename||e.name||"");if(!o)continue;const n=se(e);if(!n)continue;t[o]=n;const a=o.lastIndexOf("/");if(a>0){const e=o.slice(0,a);s[e]||(s[e]=[]),s[e].includes(o)||s[e].push(o)}}}var oe;exports.RESOURCE_TYPE=void 0,(oe=exports.RESOURCE_TYPE||(exports.RESOURCE_TYPE={})).IMAGE="IMAGE",oe.SPRITE="SPRITE",oe.SPRITE_ANIMATION="SPRITE_ANIMATION",oe.AUDIO="AUDIO",oe.VIDEO="VIDEO",oe.GLB="GLB",oe.MODEL="MODEL",oe.SHADER="SHADER",s.XhrLoadStrategy.setExtensionXhrType("json",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("tex",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("ske",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("mp3",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("wav",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("aac",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("ogg",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("glb",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("gltf",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("fbx",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("stl",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("ply",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("bin",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("obj",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("mtl",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("dae",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("vert",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("frag",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("glsl",s.XhrResponseType.Text);const ne={png:s.ImageLoadStrategy,jpg:s.ImageLoadStrategy,jpeg:s.ImageLoadStrategy,webp:s.ImageLoadStrategy,json:s.XhrLoadStrategy,tex:s.XhrLoadStrategy,ske:s.XhrLoadStrategy,audio:s.XhrLoadStrategy,video:s.VideoLoadStrategy,glb:s.XhrLoadStrategy,gltf:s.XhrLoadStrategy,fbx:s.XhrLoadStrategy,obj:s.XhrLoadStrategy,mtl:s.XhrLoadStrategy,stl:s.XhrLoadStrategy,dae:s.XhrLoadStrategy,ply:s.XhrLoadStrategy,bin:s.XhrLoadStrategy,vert:s.XhrLoadStrategy,frag:s.XhrLoadStrategy,glsl:s.XhrLoadStrategy};class ae extends n.default{constructor(e){super(),this.timeout=6e3,this.preProcessResourceHandlers=[],this.resourcesMap={},this.makeInstanceFunctions={},this.destroyInstanceFunctions={},this.promiseMap={},this.loaders=[],e&&"number"==typeof e.timeout&&(this.timeout=e.timeout)}loadConfig(e){this.addResource(e),this.preload()}loadSingle(e){return this.addResource([e]),this.getResource(e.name)}addResource(e){if(!e||e.length<1)console.warn("no resources");else for(const t of e)this.resourcesMap[t.name]?console.warn(t.name+" was already added"):this.resourcesMap[t.name]={...t,src:ee(t.src,String(t.type),t.name),data:{}}}addPreProcessResourceHandler(e){this.preProcessResourceHandlers.push(e)}removePreProcessResourceHandler(e){this.preProcessResourceHandlers.splice(this.preProcessResourceHandlers.indexOf(e),1)}preload(){const e=[];for(const t in this.resourcesMap){const s=this.resourcesMap[t];!s.preload||s.complete||this.promiseMap[t]||e.push(s.name)}this.progress=new z({resource:this,resourceTotal:e.length}),this.loadResource({names:e,preload:!0})}async getResource(e){return this.loadResource({names:[e]}),this.promiseMap[e]||Promise.resolve({})}async instance(e){const t=this.resourcesMap[e];return this.makeInstanceFunctions[t.type]&&await this.makeInstanceFunctions[t.type](t)}async destroy(e){await this._destroy(e)}async _destroy(e,t=!1){const s=this.resourcesMap[e];if(s){if(!t)try{this.destroyInstanceFunctions[s.type]&&await this.destroyInstanceFunctions[s.type](s)}catch(e){console.warn(`destroy resource ${s.name} error with '${e.message}'`)}delete this.promiseMap[e],s.data={},s.complete=!1,s.instance=void 0}}registerResourceType(e,t=e){if(exports.RESOURCE_TYPE[e])throw new Error(`The type ${e} already exists in RESOURCE_TYPE`);exports.RESOURCE_TYPE[e]=t}registerInstance(e,t){this.makeInstanceFunctions[e]=t}registerDestroy(e,t){this.destroyInstanceFunctions[e]=t}loadResource({names:e=[],preload:t=!1}){const s=e.filter(e=>!this.promiseMap[e]&&this.resourcesMap[e]);if(!s.length)return;const r={},o=this.getLoader(t);s.forEach(e=>{this.promiseMap[e]=new Promise(t=>r[e]=t);const s=this.resourcesMap[e];for(const e of this.preProcessResourceHandlers)e(s);s.src=ee(s.src,String(s.type),s.name);for(const n in s.src){const a=s.src[n].type;"data"===a?(s.data[n]=s.src[n].data,this.doComplete(e,r[e],t)):o.add({url:s.src[n].url,name:`${s.name}_${n}`,strategy:ne[a],metadata:{key:n,name:s.name,resolves:r}})}}),o.load()}async doComplete(e,t,s=!1){const r=this.resourcesMap[e],o={name:e,resource:this.resourcesMap[e],success:!0};if(this.checkAllLoaded(e))try{r.instance=await this.instance(e),r.complete=!0,s&&this.progress.onProgress(o),t(r)}catch(e){console.error(e),r.complete=!1,s&&(o.errMsg=e.message,o.success=!1,this.progress.onProgress(o)),t({})}}checkAllLoaded(e){const t=this.resourcesMap[e];return Array.from(Object.keys(t.src)).every(e=>t.data[e])}getLoader(e=!1){let t=this.loaders.find(({loading:e})=>!e);return t||(t=new s.Loader,this.loaders.push(t)),e&&t.onStart.once(()=>{this.progress.onStart()}),t.onLoad.add((t,s)=>{this.onLoad({preload:e,resource:s})}),t.onError.add((t,s,r)=>{this.onError({errMsg:t,resource:r,preload:e})}),t.onComplete.once(()=>{t.onLoad.detachAll(),t.onError.detachAll(),t.reset()}),t}async onLoad({preload:e=!1,resource:t}){const{metadata:{key:s,name:r,resolves:o},data:n}=t;this.resourcesMap[r].data[s]=n,this.doComplete(r,o[r],e)}async onError({errMsg:e,preload:t=!1,resource:s}){const{metadata:{name:r,resolves:o}}=s;if(this._destroy(r,!0),o[r]({}),t){const t={name:r,resource:this.resourcesMap[r],success:!1,errMsg:e};this.progress.onProgress(t)}}}const ie=new ae;ie.registerInstance(exports.RESOURCE_TYPE.SHADER,e=>({vertex:"string"==typeof e.data?.vertex?e.data.vertex:"",fragment:"string"==typeof e.data?.fragment?e.data.fragment:""}));const ce={IDEProp:Y,componentObserver:F};console.log(`@combos-fun/engine version: ${k}`),exports.COMBOS_GAME_PLUGIN_INIT_SUCCESS=v,exports.COMBOS_GAME_READY=w,exports.COMBOS_GAME_SET_PLAYING=A,exports.COMBOS_GAME_STATE_CHANGED=M,exports.Component=a,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=I,exports.Game=H,exports.GameObject=E,exports.IDEProp=Y,exports.RESOURCE_TYPE_STRATEGY=ne,exports.Scene=L,exports.System=b,exports.componentObserver=F,exports.decorators=ce,exports.isAllowedMessageOrigin=D,exports.mergeAllowedMessageOrigins=V,exports.normalizeResourceSrc=ee,exports.normalizeSpritesheetData=function(e){if(!e||"object"!=typeof e)return{frames:{},animations:{},meta:{scale:1}};const t=e;if(function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(t.frames))return{...t,frames:t.frames,animations:{...t.animations||{}},meta:{scale:1,...t.meta||{}}};const s={},r={...t.animations||{}};if(Array.isArray(t.textures)){for(const e of t.textures)e&&"object"==typeof e&&Array.isArray(e.frames)&&re(e.frames,s,r);const e=t.textures[0]||{},o=e.scale??t.meta?.scale??1;return{frames:s,animations:r,meta:{scale:"number"==typeof o||"string"==typeof o?o:1,image:"string"==typeof e.image?e.image:void 0,size:e.size,format:e.format,...t.meta||{}}}}return Array.isArray(t.frames)?(re(t.frames,s,r),{frames:s,animations:r,meta:{scale:1,...t.meta||{}}}):{frames:{},animations:r,meta:{scale:1,...t.meta||{}}}},exports.parseSetPlayingMessage=P,exports.postParentGameReady=j,exports.postParentGameState=X,exports.postParentPluginInitSuccess=N,exports.resource=ie,exports.resourceLoader=te,exports.version=k;
|
|
1
|
+
"use strict";var e=require("eventemitter3"),t=require("lodash-es"),s=require("resource-loader");function r(e){return e&&e.__esModule?e:{default:e}}var o,n=r(e);class a extends n.default{get game(){return this.gameObject?.scene?.game}constructor(e){super(),this.started=!1;const t=this.constructor;this.name=t.componentName,this.__componentDefaultParams=e}}exports.OBSERVER_TYPE=void 0,(o=exports.OBSERVER_TYPE||(exports.OBSERVER_TYPE={})).ADD="ADD",o.REMOVE="REMOVE",o.CHANGE="CHANGE";const i={},c={},p={},m={};function h(e,t){i[e.gameObject.id]||(i[e.gameObject.id]={});const s=i[e.gameObject.id],r=e.name+"_"+t.join(",");if(s[r])return s[r];const o=t.length-1;let n=e;for(let e=0;e<o;e++){if(void 0===n[t[e]]||null===n[t[e]])return{property:void 0,key:void 0};n=n[t[e]]}return s[r]={property:n,key:t[o]},s[r]}function u({systemName:e,componentName:t,component:s,prop:r,type:o,gameObject:n}){c[e]?.componentObserver?.add({component:s,prop:r,type:o,componentName:t,gameObject:n})}const l="GameObject";function d(e,t,s=exports.OBSERVER_TYPE.CHANGE){if(!e)return;const r={prop:[t],deep:!1};for(const o in p){const n=p[o]?.[l];n?.some(e=>e.prop[0]===t)&&u({systemName:o,componentName:l,component:void 0,gameObject:e,prop:r,type:s})}}function y({obj:e,key:s,prop:r,component:o,componentName:n}){if(void 0!==e)if(s in e){if(Object.defineProperty(e,`_${s}`,{enumerable:!1,writable:!0,value:e[s]}),r.deep&&t.isObject(e[s]))for(const t of Object.keys(e[s]))y({obj:e[s],key:t,prop:r,component:o,componentName:n});Object.defineProperty(e,s,{enumerable:!0,set(a){e[`_${s}`]!==a&&(e[`_${s}`]=a,function({prop:e,component:s,componentName:r}){for(const o in p){const n=(p[o]||{})[r];n&&(n.findIndex(s=>t.isEqual(s,e))>-1&&u({systemName:o,componentName:r,component:s,prop:e,type:exports.OBSERVER_TYPE.CHANGE}))}}({prop:r,component:o,componentName:n}))},get:()=>e[`_${s}`]})}else console.error(`prop ${s} not in component: ${n}, Can not observer`)}function f(e,t=e.name){for(const s in p){(p[s]||{})[t]&&c[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.REMOVE,componentName:t})}!function(e){e.gameObject&&delete i[e.gameObject.id]}(e)}let g=0;class E{constructor(e){this._parent=null,this._componentCache={},this.children=[],this.inScene=!1,this.components=[],this.destroyed=!1,this._name=e,this.id=++g}get parent(){return this._parent}get name(){return this._name}set scene(e){if(this._scene===e)return;const t=this._scene;this._scene=e;for(const t of this.children)t.scene=e;e?e.addGameObject(this):t&&t.removeGameObject(this)}get scene(){return this._scene}addChild(e){if(e&&e!==this){if(!(e instanceof E))throw new Error("addChild only receive GameObject");if(this.destroyed)throw new Error(`gameObject '${this.name}' has been destroy`);if(e.parent===this){const t=this.children.indexOf(e);return t>-1&&this.children.splice(t,1),void this.children.push(e)}e.parent&&e.parent.removeChild(e),e._parent=this,this.children.push(e),e.scene=this.scene,d(e,"parent",exports.OBSERVER_TYPE.CHANGE)}}removeChild(e){if(!(e instanceof E&&e.parent&&e.parent===this))return e;const t=this.children.indexOf(e);return t>-1&&this.children.splice(t,1),e._parent=null,e.scene=null,d(e,"parent",exports.OBSERVER_TYPE.CHANGE),e}addComponent(e,t){if(this.destroyed)return;const s=function(e){return e instanceof a?e.name:e instanceof Function?e.componentName:void 0}(e);if(this._componentCache[s])return;let r;if(e instanceof Function)r=new e(t);else{if(!(e instanceof a))throw new Error("addComponent recieve Component and Component Constructor");r=e}if(r.gameObject)throw new Error(`component has been added on gameObject ${r.gameObject.name}`);return r.gameObject=this,r.init&&r.init(r.__componentDefaultParams),function(e,t=e.name){for(const s in p)(p[s]||{})[t]&&c[s]?.componentObserver?.add({component:e,type:exports.OBSERVER_TYPE.ADD,componentName:t})}(r,r.name),function(e,t=e.name){if(t&&m[t]){if(!(e&&(s=e,s&&s.constructor&&"componentName"in s.constructor)))throw new Error("component param must be an instance of Component");var s;if(!e.gameObject||!e.gameObject.id)throw new Error("component should be add to a gameObject");for(const s of m[t]){const{property:r,key:o}=h(e,s.prop);y({obj:r,key:o,prop:s,component:e,componentName:t})}}}(r,r.name),this.components.push(r),this._componentCache[s]=r,r.awake&&r.awake(),r}removeComponent(e){let t;return"string"==typeof e?t=e:e instanceof a?t=e.name:e.componentName&&(t=e.componentName),this._removeComponent(t)}_removeComponent(e){const t=this.components.findIndex(({name:t})=>t===e);if(-1===t)return;const s=this.components.splice(t,1)[0];return delete this._componentCache[e],delete s.__componentDefaultParams,s.onDestroy&&s.onDestroy(),f(s,e),s.gameObject=void 0,s}getComponent(e){let t;return"string"==typeof e?t=e:e instanceof a?t=e.name:e.componentName&&(t=e.componentName),void 0!==this._componentCache[t]?this._componentCache[t]:void 0}remove(){if(this.parent)return this.parent.removeChild(this)}destroy(){if(this.destroyed)console.error("Cannot destroy gameObject that have already been destroyed.");else{Array.from(this.children).forEach(e=>{e.destroy()}),this.remove(),this.children.length=0;for(const e in this._componentCache)this._removeComponent(e);this.components.length=0,this.destroyed=!0}}}class b{constructor(){this.events=[]}add({component:e,prop:s,type:r,componentName:o,gameObject:n}){const a=n??e?.gameObject;if(r===exports.OBSERVER_TYPE.REMOVE){const t=t=>e?t.component===e:t.gameObject===a&&t.componentName===o;if(this.events.find(e=>t(e)&&e.type===exports.OBSERVER_TYPE.ADD))return void(this.events=this.events.filter(e=>!t(e)));this.events=this.events.filter(e=>!t(e))}const i=this.events.findIndex(n=>n.gameObject===a&&n.component===e&&n.componentName===o&&t.isEqual(n.prop,s)&&n.type===r);i>-1&&this.events.splice(i,1),this.events.push({gameObject:a,component:e,prop:s,type:r,componentName:o})}getChanged(){return this.events}get changed(){return this.events}clear(){const e=this.events;return this.events=[],e}}class S{constructor(e){this.started=!1,this.componentObserver=new b,this.__systemDefaultParams=e;const t=this.constructor;this.name=t.systemName}destroy(){this.componentObserver=null,this.__systemDefaultParams=null,this.onDestroy?.()}}const R=function(){let e=null;return e=Date.now?Date.now:()=>(new Date).getTime(),e}(),T={originTime:0,playbackRate:1};class O{constructor(e,t){e instanceof O&&(t=e,e={}),e=Object.assign({},T,e),t&&(this._parent=t),this._createTime=R(),this._timeMark=[{globalTime:this.globalTime,localTime:-e.originTime,entropy:-e.originTime,playbackRate:e.playbackRate,globalEntropy:0}],this._parent&&(this._timeMark[0].globalEntropy=this._parent.entropy),this._playbackRate=e.playbackRate}get globalTime(){return this.parent?this.parent.currentTime:R()-this._createTime}get parent(){return this._parent}get lastTimeMark(){return this._timeMark[this._timeMark.length-1]}markTime({time:e=this.currentTime,entropy:t=this.entropy,playbackRate:s=this.playbackRate}={}){const r={globalTime:this.globalTime,localTime:e,entropy:t,playbackRate:s,globalEntropy:this.globalEntropy};this._timeMark.push(r)}get currentTime(){const{localTime:e,globalTime:t}=this.lastTimeMark;return e+(this.globalTime-t)*this.playbackRate}set currentTime(e){this.markTime({time:e})}get globalEntropy(){return this._parent?this._parent.entropy:this.globalTime}get entropy(){const{entropy:e,globalEntropy:t}=this.lastTimeMark;return e+Math.abs((this.globalEntropy-t)*this.playbackRate)}set entropy(e){if(this.entropy>e){const t=this.seekTimeMark(e);this._timeMark.length=t+1}this.markTime({entropy:e})}fork(e){return new O(e,this)}seekGlobalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{entropy:r,playbackRate:o,globalTime:n}=s;return n+(e-r)/Math.abs(o)}seekLocalTime(e){const t=this.seekTimeMark(e),s=this._timeMark[t],{localTime:r,entropy:o,playbackRate:n}=s;return n>0?r+(e-o):r-(e-o)}seekTimeMark(e){const t=this._timeMark;let s=0,r=t.length-1;if(e<=t[s].entropy)return s;if(e>=t[r].entropy)return r;let o=Math.floor((s+r)/2);for(;o>s&&o<r;){if(e===t[o].entropy)return o;e<t[o].entropy?r=o:e>t[o].entropy&&(s=o),o=Math.floor((s+r)/2)}return s}get playbackRate(){return this._playbackRate}set playbackRate(e){e!==this.playbackRate&&(this.markTime({playbackRate:e}),this._playbackRate=e)}get paused(){if(0===this.playbackRate)return!0;let e=this.parent;for(;e;){if(0===e.playbackRate)return!0;e=e.parent}return!1}}const _={autoStart:!0,frameRate:60};class x{constructor(e){e=Object.assign({},_,e),this._frameCount=0,this._frameDuration=1e3/e.frameRate,this.autoStart=e.autoStart,this.frameRate=e.frameRate,this.timeline=new O({originTime:0,playbackRate:1}),this._lastFrameTime=this.timeline.currentTime,this._tickers=new Set,this._requestId=null,this._ticker=()=>{this._started&&(this._requestId=requestAnimationFrame(this._ticker),this.update())},this.autoStart&&this.start()}update(){const e=this.timeline.currentTime,t=e-this._lastFrameTime;if(t>=this._frameDuration){const s=e-t%this._frameDuration,r=s-this._lastFrameTime;this._lastFrameTime=s;const o={deltaTime:r,delta:r,time:s,currentTime:s,frameCount:++this._frameCount,fps:Math.round(1e3/r)};for(const e of this._tickers)"function"==typeof e&&e(o)}}add(e){this._tickers.add(e)}remove(e){this._tickers.delete(e)}start(){this._started||(this._started=!0,this.timeline.playbackRate=1,this._requestId=requestAnimationFrame(this._ticker))}pause(){this._started=!1,this.timeline.playbackRate=0}setPlaybackRate(e){this.timeline.playbackRate=e}}class L extends E{constructor(e){super(e),this.gameObjects=[],this.scene=this}addGameObject(e){this.gameObjects.push(e),e.inScene||(e.inScene=!0,d(e,"inScene",exports.OBSERVER_TYPE.CHANGE))}removeGameObject(e){const t=this.gameObjects.indexOf(e);-1!==t&&(e.inScene&&(e.inScene=!1,d(e,"inScene",exports.OBSERVER_TYPE.CHANGE)),this.gameObjects.splice(t,1))}destroy(){this.scene=null,super.destroy(),this.gameObjects=null,this.canvas=null}}const k="0.1.4-beta.1",v="combos-game:plugin-init-success",w="combos-game:ready",A="combos-game:set-playing",M="combos-game:state-changed";function C(e,t){if("undefined"!=typeof window&&window.parent&&window.parent!==window)try{window.parent.postMessage(e,t)}catch{}}function N(e,t="*"){C({type:v,systemName:e.systemName,engineVersion:k,...e.packageName?{packageName:e.packageName}:{},...e.packageVersion?{packageVersion:e.packageVersion}:{}},t)}function j(e,t="*"){C({type:w,engineVersion:k,...void 0===e?{}:{error:e instanceof Error?e.message:String(e)}},t)}function P(e,t="*"){C({type:M,playing:e.playing,started:e.started},t)}function X(e){if(!e||"object"!=typeof e)return null;const t=e;return t.type!==A||"boolean"!=typeof t.playing?null:t.playing}const I=["knoffice.tech","converge.ai"];function D(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let s;try{s=new URL(e)}catch{return!1}const r=e.toLowerCase(),o=s.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(r===t.toLowerCase())return!0;continue}const s=t.toLowerCase().replace(/^\./,"");if(o===s||o.endsWith(`.${s}`))return!0}return!1}function V(e){if(!e?.length)return[...I];if(e.includes("*"))return["*"];const t=new Set,s=[];for(const r of[...I,...e]){const e=r.trim();e&&!t.has(e)&&(t.add(e),s.push(e))}return s}function G(e){if("systemName"in e){const t=e.systemName;if("string"==typeof t)return t}return"UnknownSystem"}function $(e){const t=e;return{packageName:"string"==typeof t.packageName?t.packageName:void 0,packageVersion:"string"==typeof t.packageVersion?t.packageVersion:void 0}}var B;exports.LOAD_SCENE_MODE=void 0,(B=exports.LOAD_SCENE_MODE||(exports.LOAD_SCENE_MODE={})).SINGLE="SINGLE",B.MULTI_CANVAS="MULTI_CANVAS";const U=e=>{if((e instanceof S||e instanceof a)&&!e.started){e.started=!0;try{e.start&&e.start()}catch(t){e instanceof a?console.error(`${function(e){if("componentName"in e){const t=e.componentName;if("string"==typeof t)return t}return"UnknownComponent"}(e.constructor)} start error`,t):console.error(`${G(e.constructor)} start error`,t)}}};class H extends n.default{constructor({systems:e,frameRate:t=60,autoStart:s=!0,needScene:r=!0,onSystemsBootstrapComplete:o,pluginInitNotifyTargetOrigin:n="*",allowedMessageOrigins:a}={}){if(super(),this.playing=!1,this.started=!1,this.multiScenes=[],this.systems=[],this.pluginInitNotifyTargetOrigin="*",this.allowedMessageOrigins=V(),this.onHostMessage=e=>{if(!D(e.origin,this.allowedMessageOrigins))return;const t=X(e.data);null!==t&&this.setPlaying(t)},this.pluginInitNotifyTargetOrigin=n,this.allowedMessageOrigins=V(a),this.ticker=new x({autoStart:!1,frameRate:t}),this.initTicker(),"undefined"!=typeof window&&window.addEventListener("message",this.onHostMessage),e&&e.length){const t=[...e];this.bootstrapSystemsAndMaybeStart(t,r,s,o)}else o?.(this),this.notifyReady()}setPlaying(e){e?this.started?this.resume():this.start():this.pause()}notifyReady(e){j(e,this.pluginInitNotifyTargetOrigin)}flushObservedComponents(){for(const e of this.systems)try{e.update?.()}catch(t){console.error(`${G(e.constructor)} update error`,t)}}notifyStateChanged(){P({playing:this.playing,started:this.started},this.pluginInitNotifyTargetOrigin)}async bootstrapSystemsAndMaybeStart(e,t,s,r){let o;try{for(const t of e)await this.addSystem(t);t&&this.loadScene({scene:new L("scene")})}catch(e){o=e,console.error("Game bootstrap failed",e)}try{await Promise.resolve(r?.(this,o))}catch(e){o=o??e,console.error("onSystemsBootstrapComplete failed",e)}if(!o)try{this.flushObservedComponents();for(const e of this.systems)await Promise.resolve(e.beforeReady?.())}catch(e){o=e,console.error("Game beforeReady failed",e)}!o&&s&&this.start(),this.notifyReady(o)}get scene(){return this._scene}set scene(e){this._scene=e}get gameObjects(){return(e=>{const t=e?.scene?.gameObjects||[],s=e?.multiScenes.map(({gameObjects:e})=>e);let r=[];for(const e of s)r=[...r,...e];return[...t,...r]})(this)}async addSystem(e,s){let r;if(e instanceof Function)r=new e(s);else{if(!(e instanceof S))return void console.warn("can only add System");r=e}if(!this.systems.find(e=>e.constructor===r.constructor)){r.game=this,r.init&&await Promise.resolve(r.init(r.__systemDefaultParams)),N({systemName:G(r.constructor),...$(r.constructor)},this.pluginInitNotifyTargetOrigin),function(e,t){p[t.systemName]=t.observerInfo,c[t.systemName]=e}(r,r.constructor),function(e){const s=[];e instanceof Array?s.push(...e):s.push(e);for(const e of s)for(const s in e.observerInfo){m[s]=m[s]||[];const r=m[s];for(const o of e.observerInfo[s])-1===r.findIndex(e=>t.isEqual(e,o))&&m[s].push(o)}}(r.constructor);try{r.awake&&r.awake()}catch(e){console.error(`${G(r.constructor)} awake error`,e)}return this.systems.push(r),r}console.warn(`${G(r.constructor)} System has been added`)}removeSystem(e){if(!e)return;let t=-1;"string"==typeof e?t=this.systems.findIndex(t=>t.name===e):e instanceof Function?t=this.systems.findIndex(t=>t.constructor===e):e instanceof S&&(t=this.systems.findIndex(t=>t===e)),t>-1&&(this.systems[t].destroy&&this.systems[t].destroy(),this.systems.splice(t,1))}getSystem(e){return this.systems.find(t=>"string"==typeof e?t.name===e:t instanceof e)}pause(){this.playing&&(this.playing=!1,this.ticker.pause(),this.triggerPause(),this.notifyStateChanged())}start(){this.playing||(this.playing=!0,this.started=!0,this.ticker.start(),this.notifyStateChanged())}resume(){this.playing||(this.playing=!0,this.ticker.start(),this.triggerResume(),this.notifyStateChanged())}initTicker(){this.ticker.add(e=>{this.scene&&((e,t=[])=>{for(const s of t)for(const t of s.components)try{U(t),t.update&&t.update(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} update error`,e)}for(const s of t)for(const t of s.components)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`gameObject: ${s.name} ${t.name} lateUpdate error`,e)}})(e,this.gameObjects);for(const t of this.systems)try{U(t),t.update&&t.update(e)}catch(e){console.error(`${G(t.constructor)} update error`,e)}for(const t of this.systems)try{t.lateUpdate&&t.lateUpdate(e)}catch(e){console.error(`${G(t.constructor)} lateUpdate error`,e)}})}triggerResume(){(e=>{for(const t of e)for(const e of t.components)try{e.onResume&&e.onResume()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onResume error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onResume&&e.onResume()}catch(t){console.error(`${G(e.constructor)}, onResume error`,t)}}triggerPause(){(e=>{for(const t of e)for(const e of t.components)try{e.onPause&&e.onPause()}catch(s){console.error(`gameObject: ${t.name}, ${e.name}, onPause error`,s)}})(this.gameObjects);for(const e of this.systems)try{e.onPause&&e.onPause()}catch(t){console.error(`${G(e.constructor)}, onPause error`,t)}}destroySystems(){for(const e of[...this.systems])this.removeSystem(e);this.systems.length=0}destroy(){"undefined"!=typeof window&&window.removeEventListener("message",this.onHostMessage),this.removeAllListeners(),this.pause(),this.scene.destroy(),this.destroySystems(),this.ticker=null,this.scene=null,this.canvas=null,this.multiScenes=null}loadScene({scene:e,mode:t=exports.LOAD_SCENE_MODE.SINGLE,params:s={}}){if(e){switch(e.game=this,t){case exports.LOAD_SCENE_MODE.SINGLE:this.scene=e;break;case exports.LOAD_SCENE_MODE.MULTI_CANVAS:this.multiScenes.push(e)}this.emit("sceneChanged",{scene:e,mode:t,params:s})}}}function Y(e,t){e.constructor.IDEProps||(e.constructor.IDEProps=[]),e.constructor.IDEProps.push(t)}function F(e={}){return function(t){if(!t.observerInfo){for(const t in e)for(const s in e[t]){let r;"string"==typeof e[t][s]&&(e[t][s]=[e[t][s]]),Array.isArray(e[t][s])&&(r={prop:e[t][s],deep:!1},e[t][s]=r),r=e[t][s],"string"==typeof r.prop&&(r.prop=[r.prop])}t.observerInfo=e}}}var q;exports.LOAD_EVENT=void 0,(q=exports.LOAD_EVENT||(exports.LOAD_EVENT={})).START="start",q.PROGRESS="progress",q.LOADED="loaded",q.COMPLETE="complete",q.ERROR="error";class z extends n.default{constructor({resource:e,resourceTotal:t}){super(),this.progress=0,this.resourceTotal=0,this.resourceLoadedCount=0,this.resource=e,this.resourceTotal=t,0===t&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}onStart(){this.resource.emit(exports.LOAD_EVENT.START,this)}onProgress(e){this.resourceLoadedCount++,this.progress=Math.floor(this.resourceLoadedCount/this.resourceTotal*100)/100,e.success?this.resource.emit(exports.LOAD_EVENT.LOADED,this,e):this.resource.emit(exports.LOAD_EVENT.ERROR,this,e),this.resource.emit(exports.LOAD_EVENT.PROGRESS,this,e),this.resourceLoadedCount===this.resourceTotal&&this.resource.emit(exports.LOAD_EVENT.COMPLETE,this)}}const J={image:"png",json:"json",tex:"tex",ske:"ske",audio:"audio",video:"video",model:"glb",mtl:"mtl",bin:"bin",vertex:"vert",fragment:"frag"},W={png:"png",jpg:"jpg",jpeg:"jpeg",webp:"webp",json:"json",tex:"tex",ske:"ske",mp3:"audio",wav:"audio",aac:"audio",ogg:"audio",mp4:"video",webm:"video",glb:"glb",gltf:"gltf",fbx:"fbx",obj:"obj",mtl:"mtl",stl:"stl",dae:"dae",ply:"ply",bin:"bin",vert:"vert",frag:"frag",glsl:"glsl"};function K(e,t){return W[function(e){const t=e.split("?")[0].split("#")[0],s=t.lastIndexOf(".");return s<0?"":t.slice(s+1).toLowerCase()}(e)]||J[t]||"png"}function Q(e,t,s){if("string"==typeof t){const r=t.trim();if(!r)throw Z(s,e);return{type:K(r,e),url:r}}if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`Resource "${s}" src.${e} must be a url string or { type, url }.`);const r=t;if("data"===r.type)return r;const o="string"==typeof r.url?r.url.trim():"";if(!o)throw Z(s,e);return{...r,type:r.type||K(o,e),url:o}}function Z(e,t){return new Error(`Resource "${e}" src.${t}.url is required. Use { type, url } (e.g. { type: "webp", url: "https://..." }). A flat path string is also accepted and will be normalized.`)}function ee(e,t,s="(unnamed)"){if(null==e)throw new Error(`Resource "${s}" src is required.`);if("string"==typeof e){const r=function(e){return"AUDIO"===e?"audio":"VIDEO"===e?"video":"MODEL"===e||"GLB"===e?"model":"SHADER"===e?"fragment":"image"}(t);return{[r]:Q(r,e,s)}}if("object"!=typeof e||Array.isArray(e))throw new Error(`Resource "${s}" src must be a url string or a slot object.`);const r={};for(const[t,o]of Object.entries(e))null!=o&&(r[t]=Q(t,o,s));if(0===Object.keys(r).length)throw new Error(`Resource "${s}" src has no loadable slots.`);return r}const te={AbstractLoadStrategy:s.AbstractLoadStrategy,AudioLoadStrategy:s.AudioLoadStrategy,ImageLoadStrategy:s.ImageLoadStrategy,XhrResponseType:s.XhrResponseType,MediaElementLoadStrategy:s.MediaElementLoadStrategy,VideoLoadStrategy:s.VideoLoadStrategy,XhrLoadStrategy:s.XhrLoadStrategy,Loader:s.Loader,Resource:s.Resource,ResourceType:s.ResourceType,ResourceState:s.ResourceState};function se(e){const t=e.frame;return t&&"object"==typeof t?{...e,frame:t,rotated:Boolean(e.rotated),trimmed:Boolean(e.trimmed),spriteSourceSize:e.spriteSourceSize,sourceSize:e.sourceSize}:null}function re(e,t,s){for(const r of e){if(!r||"object"!=typeof r)continue;const e=r,o=String(e.filename||e.name||"");if(!o)continue;const n=se(e);if(!n)continue;t[o]=n;const a=o.lastIndexOf("/");if(a>0){const e=o.slice(0,a);s[e]||(s[e]=[]),s[e].includes(o)||s[e].push(o)}}}var oe;exports.RESOURCE_TYPE=void 0,(oe=exports.RESOURCE_TYPE||(exports.RESOURCE_TYPE={})).IMAGE="IMAGE",oe.SPRITE="SPRITE",oe.SPRITE_ANIMATION="SPRITE_ANIMATION",oe.AUDIO="AUDIO",oe.VIDEO="VIDEO",oe.GLB="GLB",oe.MODEL="MODEL",oe.SHADER="SHADER",s.XhrLoadStrategy.setExtensionXhrType("json",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("tex",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("ske",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("mp3",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("wav",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("aac",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("ogg",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("glb",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("gltf",s.XhrResponseType.Json),s.XhrLoadStrategy.setExtensionXhrType("fbx",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("stl",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("ply",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("bin",s.XhrResponseType.Buffer),s.XhrLoadStrategy.setExtensionXhrType("obj",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("mtl",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("dae",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("vert",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("frag",s.XhrResponseType.Text),s.XhrLoadStrategy.setExtensionXhrType("glsl",s.XhrResponseType.Text);const ne={png:s.ImageLoadStrategy,jpg:s.ImageLoadStrategy,jpeg:s.ImageLoadStrategy,webp:s.ImageLoadStrategy,json:s.XhrLoadStrategy,tex:s.XhrLoadStrategy,ske:s.XhrLoadStrategy,audio:s.XhrLoadStrategy,video:s.VideoLoadStrategy,glb:s.XhrLoadStrategy,gltf:s.XhrLoadStrategy,fbx:s.XhrLoadStrategy,obj:s.XhrLoadStrategy,mtl:s.XhrLoadStrategy,stl:s.XhrLoadStrategy,dae:s.XhrLoadStrategy,ply:s.XhrLoadStrategy,bin:s.XhrLoadStrategy,vert:s.XhrLoadStrategy,frag:s.XhrLoadStrategy,glsl:s.XhrLoadStrategy};class ae extends n.default{constructor(e){super(),this.timeout=6e3,this.preProcessResourceHandlers=[],this.resourcesMap={},this.makeInstanceFunctions={},this.destroyInstanceFunctions={},this.promiseMap={},this.loaders=[],e&&"number"==typeof e.timeout&&(this.timeout=e.timeout)}loadConfig(e){this.addResource(e),this.preload()}loadSingle(e){return this.addResource([e]),this.getResource(e.name)}addResource(e){if(!e||e.length<1)console.warn("no resources");else for(const t of e)this.resourcesMap[t.name]?console.warn(t.name+" was already added"):this.resourcesMap[t.name]={...t,src:ee(t.src,String(t.type),t.name),data:{}}}addPreProcessResourceHandler(e){this.preProcessResourceHandlers.push(e)}removePreProcessResourceHandler(e){this.preProcessResourceHandlers.splice(this.preProcessResourceHandlers.indexOf(e),1)}preload(){const e=[];for(const t in this.resourcesMap){const s=this.resourcesMap[t];!s.preload||s.complete||this.promiseMap[t]||e.push(s.name)}this.progress=new z({resource:this,resourceTotal:e.length}),this.loadResource({names:e,preload:!0})}async getResource(e){return this.loadResource({names:[e]}),this.promiseMap[e]||Promise.resolve({})}async instance(e){const t=this.resourcesMap[e];return this.makeInstanceFunctions[t.type]&&await this.makeInstanceFunctions[t.type](t)}async destroy(e){await this._destroy(e)}async _destroy(e,t=!1){const s=this.resourcesMap[e];if(s){if(!t)try{this.destroyInstanceFunctions[s.type]&&await this.destroyInstanceFunctions[s.type](s)}catch(e){console.warn(`destroy resource ${s.name} error with '${e.message}'`)}delete this.promiseMap[e],s.data={},s.complete=!1,s.instance=void 0}}registerResourceType(e,t=e){if(exports.RESOURCE_TYPE[e])throw new Error(`The type ${e} already exists in RESOURCE_TYPE`);exports.RESOURCE_TYPE[e]=t}registerInstance(e,t){this.makeInstanceFunctions[e]=t}registerDestroy(e,t){this.destroyInstanceFunctions[e]=t}loadResource({names:e=[],preload:t=!1}){const s=e.filter(e=>!this.promiseMap[e]&&this.resourcesMap[e]);if(!s.length)return;const r={},o=this.getLoader(t);s.forEach(e=>{this.promiseMap[e]=new Promise(t=>r[e]=t);const s=this.resourcesMap[e];for(const e of this.preProcessResourceHandlers)e(s);s.src=ee(s.src,String(s.type),s.name);for(const n in s.src){const a=s.src[n].type;"data"===a?(s.data[n]=s.src[n].data,this.doComplete(e,r[e],t)):o.add({url:s.src[n].url,name:`${s.name}_${n}`,strategy:ne[a],metadata:{key:n,name:s.name,resolves:r}})}}),o.load()}async doComplete(e,t,s=!1){const r=this.resourcesMap[e],o={name:e,resource:this.resourcesMap[e],success:!0};if(this.checkAllLoaded(e))try{r.instance=await this.instance(e),r.complete=!0,s&&this.progress.onProgress(o),t(r)}catch(e){console.error(e),r.complete=!1,s&&(o.errMsg=e.message,o.success=!1,this.progress.onProgress(o)),t({})}}checkAllLoaded(e){const t=this.resourcesMap[e];return Array.from(Object.keys(t.src)).every(e=>t.data[e])}getLoader(e=!1){let t=this.loaders.find(({loading:e})=>!e);return t||(t=new s.Loader,this.loaders.push(t)),e&&t.onStart.once(()=>{this.progress.onStart()}),t.onLoad.add((t,s)=>{this.onLoad({preload:e,resource:s})}),t.onError.add((t,s,r)=>{this.onError({errMsg:t,resource:r,preload:e})}),t.onComplete.once(()=>{t.onLoad.detachAll(),t.onError.detachAll(),t.reset()}),t}async onLoad({preload:e=!1,resource:t}){const{metadata:{key:s,name:r,resolves:o},data:n}=t;this.resourcesMap[r].data[s]=n,this.doComplete(r,o[r],e)}async onError({errMsg:e,preload:t=!1,resource:s}){const{metadata:{name:r,resolves:o}}=s;if(this._destroy(r,!0),o[r]({}),t){const t={name:r,resource:this.resourcesMap[r],success:!1,errMsg:e};this.progress.onProgress(t)}}}const ie=new ae;ie.registerInstance(exports.RESOURCE_TYPE.SHADER,e=>({vertex:"string"==typeof e.data?.vertex?e.data.vertex:"",fragment:"string"==typeof e.data?.fragment?e.data.fragment:""}));const ce={IDEProp:Y,componentObserver:F};console.log(`@combos-fun/engine version: ${k}`),exports.COMBOS_GAME_PLUGIN_INIT_SUCCESS=v,exports.COMBOS_GAME_READY=w,exports.COMBOS_GAME_SET_PLAYING=A,exports.COMBOS_GAME_STATE_CHANGED=M,exports.Component=a,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=I,exports.Game=H,exports.GameObject=E,exports.IDEProp=Y,exports.RESOURCE_TYPE_STRATEGY=ne,exports.Scene=L,exports.System=S,exports.componentObserver=F,exports.decorators=ce,exports.isAllowedMessageOrigin=D,exports.mergeAllowedMessageOrigins=V,exports.normalizeResourceSrc=ee,exports.normalizeSpritesheetData=function(e){if(!e||"object"!=typeof e)return{frames:{},animations:{},meta:{scale:1}};const t=e;if(function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(t.frames))return{...t,frames:t.frames,animations:{...t.animations||{}},meta:{scale:1,...t.meta||{}}};const s={},r={...t.animations||{}};if(Array.isArray(t.textures)){for(const e of t.textures)e&&"object"==typeof e&&Array.isArray(e.frames)&&re(e.frames,s,r);const e=t.textures[0]||{},o=e.scale??t.meta?.scale??1;return{frames:s,animations:r,meta:{scale:"number"==typeof o||"string"==typeof o?o:1,image:"string"==typeof e.image?e.image:void 0,size:e.size,format:e.format,...t.meta||{}}}}return Array.isArray(t.frames)?(re(t.frames,s,r),{frames:s,animations:r,meta:{scale:1,...t.meta||{}}}):{frames:{},animations:r,meta:{scale:1,...t.meta||{}}}},exports.parseSetPlayingMessage=X,exports.postParentGameReady=j,exports.postParentGameState=P,exports.postParentPluginInitSuccess=N,exports.resource=ie,exports.resourceLoader=te,exports.version=k;
|
package/dist/engine.d.ts
CHANGED
|
@@ -182,6 +182,13 @@ declare class System<T extends {} = {}> {
|
|
|
182
182
|
* @override
|
|
183
183
|
*/
|
|
184
184
|
start?(): void;
|
|
185
|
+
/**
|
|
186
|
+
* Called once after scene bootstrap (`onSystemsBootstrapComplete`) and
|
|
187
|
+
* observed component changes have been flushed, before `start` / `ready`.
|
|
188
|
+
* May return a Promise to hold the game from entering play (e.g. first i18n).
|
|
189
|
+
* @override
|
|
190
|
+
*/
|
|
191
|
+
beforeReady?(): void | Promise<void>;
|
|
185
192
|
/**
|
|
186
193
|
* Called in each tick
|
|
187
194
|
* @example
|
|
@@ -250,10 +257,12 @@ interface GameParams {
|
|
|
250
257
|
allowedMessageOrigins?: string[];
|
|
251
258
|
/**
|
|
252
259
|
* Called after async system bootstrap finishes (constructor path with non-empty `systems`),
|
|
253
|
-
* i.e. after all `addSystem`/`init` work and optional `loadScene
|
|
254
|
-
*
|
|
260
|
+
* i.e. after all `addSystem`/`init` work and optional `loadScene`.
|
|
261
|
+
* Scene objects should be added here. The game then flushes observers, awaits
|
|
262
|
+
* each System `beforeReady`, then optional `start`, then `combos-game:ready`.
|
|
263
|
+
* May return a Promise. Second argument is set if bootstrap threw.
|
|
255
264
|
*/
|
|
256
|
-
onSystemsBootstrapComplete?: (game: Game, error?: unknown) => void
|
|
265
|
+
onSystemsBootstrapComplete?: (game: Game, error?: unknown) => void | Promise<void>;
|
|
257
266
|
}
|
|
258
267
|
declare enum LOAD_SCENE_MODE {
|
|
259
268
|
SINGLE = "SINGLE",
|
|
@@ -316,8 +325,10 @@ declare class Game extends EventEmitter {
|
|
|
316
325
|
*/
|
|
317
326
|
setPlaying(playing: boolean): void;
|
|
318
327
|
private notifyReady;
|
|
328
|
+
/** Drain queued component observer events without starting the ticker. */
|
|
329
|
+
private flushObservedComponents;
|
|
319
330
|
private notifyStateChanged;
|
|
320
|
-
/** When `systems` is passed in the constructor, run async `init` for each before `loadScene` / `start`. */
|
|
331
|
+
/** When `systems` is passed in the constructor, run async `init` for each before `loadScene` / `beforeReady` / `start`. */
|
|
321
332
|
private bootstrapSystemsAndMaybeStart;
|
|
322
333
|
/**
|
|
323
334
|
* Get scene on this game
|
|
@@ -927,7 +938,7 @@ declare function isAllowedMessageOrigin(origin: string, allowed: readonly string
|
|
|
927
938
|
declare function mergeAllowedMessageOrigins(extra?: string[]): string[];
|
|
928
939
|
|
|
929
940
|
/** Generated at build from package.json */
|
|
930
|
-
declare const version = "0.1.
|
|
941
|
+
declare const version = "0.1.4-beta.1";
|
|
931
942
|
|
|
932
943
|
/** Decorators util */
|
|
933
944
|
declare const decorators: {
|
package/dist/engine.esm.js
CHANGED
|
@@ -885,7 +885,7 @@ class Scene extends GameObject {
|
|
|
885
885
|
}
|
|
886
886
|
|
|
887
887
|
/** Generated at build from package.json */
|
|
888
|
-
const version = "0.1.
|
|
888
|
+
const version = "0.1.4-beta.1";
|
|
889
889
|
|
|
890
890
|
/**
|
|
891
891
|
* Sent to `window.parent` after each `System.init` completes during `Game.addSystem`
|
|
@@ -1202,10 +1202,21 @@ class Game extends EventEmitter {
|
|
|
1202
1202
|
notifyReady(error) {
|
|
1203
1203
|
postParentGameReady(error, this.pluginInitNotifyTargetOrigin);
|
|
1204
1204
|
}
|
|
1205
|
+
/** Drain queued component observer events without starting the ticker. */
|
|
1206
|
+
flushObservedComponents() {
|
|
1207
|
+
for (const system of this.systems) {
|
|
1208
|
+
try {
|
|
1209
|
+
system.update?.();
|
|
1210
|
+
}
|
|
1211
|
+
catch (e) {
|
|
1212
|
+
console.error(`${systemClassName(system.constructor)} update error`, e);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1205
1216
|
notifyStateChanged() {
|
|
1206
1217
|
postParentGameState({ playing: this.playing, started: this.started }, this.pluginInitNotifyTargetOrigin);
|
|
1207
1218
|
}
|
|
1208
|
-
/** When `systems` is passed in the constructor, run async `init` for each before `loadScene` / `start`. */
|
|
1219
|
+
/** When `systems` is passed in the constructor, run async `init` for each before `loadScene` / `beforeReady` / `start`. */
|
|
1209
1220
|
async bootstrapSystemsAndMaybeStart(systemsToAdd, needScene, autoStart, onComplete) {
|
|
1210
1221
|
let error;
|
|
1211
1222
|
try {
|
|
@@ -1215,18 +1226,34 @@ class Game extends EventEmitter {
|
|
|
1215
1226
|
if (needScene) {
|
|
1216
1227
|
this.loadScene({ scene: new Scene("scene") });
|
|
1217
1228
|
}
|
|
1218
|
-
if (autoStart) {
|
|
1219
|
-
this.start();
|
|
1220
|
-
}
|
|
1221
1229
|
}
|
|
1222
1230
|
catch (e) {
|
|
1223
1231
|
error = e;
|
|
1224
1232
|
console.error("Game bootstrap failed", e);
|
|
1225
1233
|
}
|
|
1226
|
-
|
|
1227
|
-
onComplete?.(this, error);
|
|
1228
|
-
|
|
1234
|
+
try {
|
|
1235
|
+
await Promise.resolve(onComplete?.(this, error));
|
|
1236
|
+
}
|
|
1237
|
+
catch (e) {
|
|
1238
|
+
error = error ?? e;
|
|
1239
|
+
console.error("onSystemsBootstrapComplete failed", e);
|
|
1240
|
+
}
|
|
1241
|
+
if (!error) {
|
|
1242
|
+
try {
|
|
1243
|
+
this.flushObservedComponents();
|
|
1244
|
+
for (const system of this.systems) {
|
|
1245
|
+
await Promise.resolve(system.beforeReady?.());
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
catch (e) {
|
|
1249
|
+
error = e;
|
|
1250
|
+
console.error("Game beforeReady failed", e);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (!error && autoStart) {
|
|
1254
|
+
this.start();
|
|
1229
1255
|
}
|
|
1256
|
+
this.notifyReady(error);
|
|
1230
1257
|
}
|
|
1231
1258
|
/**
|
|
1232
1259
|
* Get scene on this game
|