@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 2.87 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{addFrameTask as e}from"../../../core/scheduling.js";import t from"./GamepadInputDevice.js";import{extractState as s,stateIdle as n,stateEqual as i}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,n=t.index,i=this._inputDevices[n];i&&(this._emitGamepadEvent(t,s(i),!1),this._inputDevices.splice(n,1),this._latestUpdate.splice(n,1),this._input.gamepad.devices.remove(i),this.ensurePollingState())},this._frameTask=null,this._latestUpdate=new Array,this._inputDevices=new Array,this._callback=null;const n="getGamepads"in window.navigator,i=window.isSecureContext;this.supported=n&&i,this.supported&&(o(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({gamepad: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;o(e=>{const t=this._inputDevices[e.index];if(!t)return;const d=this._latestUpdate[e.index],o=s(t),c=a||n(o);if(d){if(d.timestamp===e.timestamp)return;if(!d.active&&c)return;if(i(d.state,o))return}this._emitGamepadEvent(e,o,!c)})}_emitGamepadEvent(e,t,s){const n=this._latestUpdate[e.index],i=n&&n.active;if(!i&&!s)return;const a=!i&&s?"start":i&&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})}}function d(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}function o(e){for(const t of navigator.getGamepads())d(t)&&e(t)}export{a as GamepadSource};