@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 2.94 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
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&&(d((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;d((e=>{const t=this._inputDevices[e.index];if(!t)return;const o=this._latestUpdate[e.index],d=s(t),c=a||n(d);if(o){if(o.timestamp===e.timestamp)return;if(!o.active&&c)return;if(i(o.state,d))return}this._emitGamepadEvent(e,d,!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 o(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 d(e){for(const t of navigator.getGamepads())o(t)&&e(t)}export{a as GamepadSource};