@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 6.72 kB
JavaScript
import{EventHandler as t}from"../../../core/event-handler.js";import{math as s}from"../../../core/math/math.js";import{Vec3 as e}from"../../../core/math/vec3.js";import{Asset as i}from"../../asset/asset.js";import{SoundInstance as n}from"../../../platform/sound/instance.js";import{SoundInstance3d as o}from"../../../platform/sound/instance3d.js";const a={volume:0,pitch:0,loop:!1,startTime:0,duration:0,position:new e,maxDistance:0,refDistance:0,rollOffFactor:0,distanceModel:0,onPlay:null,onPause:null,onResume:null,onStop:null,onEnd:null};class h extends t{constructor(t,e="Untitled",n={}){super(),this.name=void 0,this.instances=[],this._component=t,this._assets=t.system.app.assets,this._manager=t.system.manager,this.name=e,this._volume=void 0!==n.volume?s.clamp(Number(n.volume)||0,0,1):1,this._pitch=void 0!==n.pitch?Math.max(.01,Number(n.pitch)||0):1,this._loop=!(void 0===n.loop||!n.loop),this._duration=n.duration>0?n.duration:null,this._startTime=Math.max(0,Number(n.startTime)||0),this._overlap=!!n.overlap,this._autoPlay=!!n.autoPlay,this._firstNode=null,this._lastNode=null,this._asset=n.asset,this._asset instanceof i&&(this._asset=this._asset.id),this._onInstancePlayHandler=this._onInstancePlay.bind(this),this._onInstancePauseHandler=this._onInstancePause.bind(this),this._onInstanceResumeHandler=this._onInstanceResume.bind(this),this._onInstanceStopHandler=this._onInstanceStop.bind(this),this._onInstanceEndHandler=this._onInstanceEnd.bind(this)}play(){if(this.overlap||this.stop(),!this.isLoaded&&!this._hasAsset())return;const t=this._createInstance();if(this.instances.push(t),this.isLoaded)t.play();else{const s=function(s){const e=t._playWhenLoaded;t.sound=s,e&&t.play()};this.off("load",s),this.once("load",s),this.load()}return t}pause(){let t=!1;const s=this.instances;for(let e=0,i=s.length;e<i;e++)s[e].pause()&&(t=!0);return t}resume(){let t=!1;const s=this.instances;for(let e=0,i=s.length;e<i;e++)s[e].resume()&&(t=!0);return t}stop(){let t=!1;const s=this.instances;let e=s.length;for(;e--;)s[e].stop(),t=!0;return s.length=0,t}load(){if(!this._hasAsset())return;const t=this._assets.get(this._asset);return t?(t.off("remove",this._onAssetRemoved,this),t.on("remove",this._onAssetRemoved,this),t.resource?void this.fire("load",t.resource):(t.off("load",this._onAssetLoad,this),t.once("load",this._onAssetLoad,this),void this._assets.load(t))):(this._assets.off(`add:${this._asset}`,this._onAssetAdd,this),void this._assets.once(`add:${this._asset}`,this._onAssetAdd,this))}setExternalNodes(t,s){if(t){if(s||(s=t),this._firstNode=t,this._lastNode=s,!this._overlap){const e=this.instances;for(let i=0,n=e.length;i<n;i++)e[i].setExternalNodes(t,s)}}else console.error("The firstNode must have a valid AudioNode")}clearExternalNodes(){if(this._firstNode=null,this._lastNode=null,!this._overlap){const t=this.instances;for(let s=0,e=t.length;s<e;s++)t[s].clearExternalNodes()}}getExternalNodes(){return[this._firstNode,this._lastNode]}_hasAsset(){return null!=this._asset}_createInstance(){let t=null;const s=this._component;let e=null;if(this._hasAsset()){const t=this._assets.get(this._asset);t&&(e=t.resource)}const i=a;return i.volume=this._volume*s.volume,i.pitch=this._pitch*s.pitch,i.loop=this._loop,i.startTime=this._startTime,i.duration=this._duration,i.onPlay=this._onInstancePlayHandler,i.onPause=this._onInstancePauseHandler,i.onResume=this._onInstanceResumeHandler,i.onStop=this._onInstanceStopHandler,i.onEnd=this._onInstanceEndHandler,s.positional?(i.position.copy(s.entity.getPosition()),i.maxDistance=s.maxDistance,i.refDistance=s.refDistance,i.rollOffFactor=s.rollOffFactor,i.distanceModel=s.distanceModel,t=new o(this._manager,e,i)):t=new n(this._manager,e,i),this._firstNode&&t.setExternalNodes(this._firstNode,this._lastNode),t}_onInstancePlay(t){this.fire("play",t),this._component.fire("play",this,t)}_onInstancePause(t){this.fire("pause",t),this._component.fire("pause",this,t)}_onInstanceResume(t){this.fire("resume",t),this._component.fire("resume",this,t)}_onInstanceStop(t){const s=this.instances.indexOf(t);-1!==s&&this.instances.splice(s,1),this.fire("stop",t),this._component.fire("stop",this,t)}_onInstanceEnd(t){const s=this.instances.indexOf(t);-1!==s&&this.instances.splice(s,1),this.fire("end",t),this._component.fire("end",this,t)}_onAssetAdd(t){this.load()}_onAssetLoad(t){this.load()}_onAssetRemoved(t){t.off("remove",this._onAssetRemoved,this),this._assets.off(`add:${t.id}`,this._onAssetAdd,this),this.stop()}updatePosition(t){const s=this.instances;for(let e=0,i=s.length;e<i;e++)s[e].position=t}set asset(t){const s=this._asset;if(s){this._assets.off(`add:${s}`,this._onAssetAdd,this);const t=this._assets.get(s);t&&t.off("remove",this._onAssetRemoved,this)}this._asset=t,this._asset instanceof i&&(this._asset=this._asset.id),this._hasAsset()&&this._component.enabled&&this._component.entity.enabled&&this.load()}get asset(){return this._asset}set autoPlay(t){this._autoPlay=!!t}get autoPlay(){return this._autoPlay}set duration(t){if(this._duration=Math.max(0,Number(t)||0)||null,!this._overlap){const t=this.instances;for(let s=0,e=t.length;s<e;s++)t[s].duration=this._duration}}get duration(){let t=0;if(this._hasAsset()){const s=this._assets.get(this._asset);t=null!=s&&s.resource?s.resource.duration:0}return null!=this._duration?this._duration%(t||1):t}get isLoaded(){if(this._hasAsset()){const t=this._assets.get(this._asset);if(t)return!!t.resource}return!1}get isPaused(){const t=this.instances,s=t.length;if(0===s)return!1;for(let e=0;e<s;e++)if(!t[e].isPaused)return!1;return!0}get isPlaying(){const t=this.instances;for(let s=0,e=t.length;s<e;s++)if(t[s].isPlaying)return!0;return!1}get isStopped(){const t=this.instances;for(let s=0,e=t.length;s<e;s++)if(!t[s].isStopped)return!1;return!0}set loop(t){this._loop=!!t;const s=this.instances;for(let t=0,e=s.length;t<e;t++)s[t].loop=this._loop}get loop(){return this._loop}set overlap(t){this._overlap=!!t}get overlap(){return this._overlap}set pitch(t){if(this._pitch=Math.max(Number(t)||0,.01),!this._overlap){const t=this.instances;for(let s=0,e=t.length;s<e;s++)t[s].pitch=this.pitch*this._component.pitch}}get pitch(){return this._pitch}set startTime(t){if(this._startTime=Math.max(0,Number(t)||0),!this._overlap){const t=this.instances;for(let s=0,e=t.length;s<e;s++)t[s].startTime=this._startTime}}get startTime(){return this._startTime}set volume(t){if(this._volume=s.clamp(Number(t)||0,0,1),!this._overlap){const t=this.instances;for(let s=0,e=t.length;s<e;s++)t[s].volume=this._volume*this._component.volume}}get volume(){return this._volume}}h.EVENT_PLAY="play",h.EVENT_PAUSE="pause",h.EVENT_RESUME="resume",h.EVENT_STOP="stop",h.EVENT_LOAD="load";export{h as SoundSlot};