@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 2.9 kB
JavaScript
import{addFrameTask as e}from"../../../core/scheduling.js";import t from"./GamepadInputDevice.js";import{extractState as s,stateIdle as i,stateEqual as n}from"./GamepadState.js";class a{constructor(e,t){this._element=e,this._input=t,this._hasEventListeners=!1,this._onConnectGamepad=e=>{this._connectGamepad(e.gamepad)},this._onDisconnectGamepad=e=>{const t=e.gamepad,i=t.index,n=this._inputDevices[i];n&&(this._emitGamepadEvent(t,s(n),!1),this._inputDevices.splice(i,1),this._latestUpdate.splice(i,1),this._input.gamepad.devices.remove(n),this.ensurePollingState())},this._frameTask=null,this._latestUpdate=new Array,this._inputDevices=new Array,this._callback=null;const i="getGamepads"in window.navigator,n=window.isSecureContext;this.supported=i&&n,this.supported&&(this._forEachGamepad((e=>this._connectGamepad(e))),window.addEventListener("gamepadconnected",this._onConnectGamepad),window.addEventListener("gamepaddisconnected",this._onDisconnectGamepad),this.ensurePollingState())}destroy(){this.hasEventListeners=!1,this.supported&&(window.removeEventListener("gamepadconnected",this._onConnectGamepad),window.removeEventListener("gamepaddisconnected",this._onDisconnectGamepad))}set hasEventListeners(e){this._hasEventListeners!==e&&(this._hasEventListeners=e,this.ensurePollingState())}get _eventsEnabled(){return this.supported&&this._inputDevices.length>0&&this._hasEventListeners}set onEvent(e){this._callback=e}_connectGamepad(e){const s=new t(e);"unknown"!==s.deviceType&&(this._inputDevices[e.index]=s,this._input.gamepad.devices.add(s)),this.ensurePollingState()}ensurePollingState(){this._eventsEnabled?this._startPolling():this._stopPolling()}_startPolling(){null==this._frameTask&&(this._frameTask=e({update:()=>this._readGamepadState()}))}_stopPolling(){null!=this._frameTask&&(this._frameTask.remove(),this._frameTask=null,this._latestUpdate=new Array)}_readGamepadState(){const e=document.hasFocus(),t=this._element.contains(document.activeElement),a="document"===this._input.gamepad.enabledFocusMode&&!e||"view"===this._input.gamepad.enabledFocusMode&&!t;this._forEachGamepad((e=>{const t=this._inputDevices[e.index];if(!t)return;const d=this._latestUpdate[e.index],o=s(t),r=a||i(o);if(d){if(d.timestamp===e.timestamp)return;if(!d.active&&r)return;if(n(d.state,o))return}this._emitGamepadEvent(e,o,!r)}))}_forEachGamepad(e){const t=window.navigator.getGamepads();for(let s=0;s<t.length;s++){const i=t[s];this._validate(i)&&e(i)}}_emitGamepadEvent(e,t,s){const i=this._latestUpdate[e.index],n=i&&i.active;if(!n&&!s)return;const a=!n&&s?"start":n&&s?"update":"end";this._latestUpdate[e.index]={timestamp:e.timestamp,state:t,active:s},this._callback&&this._callback({device:this._inputDevices[e.index],state:t,action:a})}_validate(e){if(!e)return!1;if(!e.connected)return!1;for(let t=0;t<e.axes.length;t++)if(isNaN(e.axes[t]))return!1;return!0}}export{a as GamepadSource};