/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.controllers.gwt.support; import com.badlogic.gdx.utils.IntMap; import com.google.gwt.animation.client.AnimationScheduler; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; public class GamepadSupport { private static Ticker ticker = new Ticker(); private static GamepadSupportListener listener; private static IntMap<Gamepad> gamepads = new IntMap<Gamepad>(); private static IntMap<Gamepad> gamepadsTemp = new IntMap<Gamepad>(); public static void init(GamepadSupportListener listener) { GamepadSupport.listener = listener; nativeInit(); } public static void startPolling() { consoleLog("startPolling"); ticker.start(); } public static void stopPolling() { ticker.stop(); } public static void pollGamepads() { JsArray<Gamepad> currentGamepads = nativePollGamepads(); if (currentGamepads != null) { gamepadsTemp.clear(); gamepadsTemp.putAll(gamepads); for (int i = 0, j = currentGamepads.length(); i < j; i++) { Gamepad gamepad = currentGamepads.get(i); if (gamepad != null) { if (!gamepadsTemp.containsKey(gamepad.getIndex())) { onGamepadConnect(gamepad); } gamepadsTemp.remove(gamepad.getIndex()); } } for (Gamepad gamepad : gamepadsTemp.values()) { onGamepadDisconnect(gamepad); } } } public static void pollGamepadsStatus() { for (Gamepad gamepad : gamepads.values()) { if (gamepad.getPreviousTimestamp() != gamepad.getTimestamp()) { fireGamepadUpdated(gamepad.getIndex()); } gamepad.setPreviousTimestamp(gamepad.getTimestamp()); } } public static Gamepad getGamepad(int index) { return gamepads.get(index); } private static void onGamepadConnect(Gamepad gamepad) { consoleLog("onGamepadConnect: " + gamepad.getId()); gamepads.put(gamepad.getIndex(), gamepad); fireGamepadConnected(gamepad.getIndex()); } private static void onGamepadDisconnect(Gamepad gamepad) { consoleLog("onGamepadDisconnect: " + gamepad.getId()); gamepads.remove(gamepad.getIndex()); fireGamepadDisconnected(gamepad.getIndex()); } private static void fireGamepadConnected(int index) { if (listener != null) { listener.onGamepadConnected(index); } } private static void fireGamepadDisconnected(int index) { if (listener != null) { listener.onGamepadDisconnected(index); } } private static void fireGamepadUpdated(int index) { if (listener != null) { listener.onGamepadUpdated(index); } } private static void handleGamepadConnect(GamepadEvent event) { onGamepadConnect(event.getGamepad()); } private static void handleGamepadDisconnect(GamepadEvent event) { onGamepadDisconnect(event.getGamepad()); } private static native void nativeInit() /*-{ var gamepadSupportAvailable = !! navigator.getGamepads || !! navigator.webkitGetGamepads || !! navigator.webkitGamepads || (navigator.userAgent.indexOf('Firefox/') != -1); if (gamepadSupportAvailable) { $wnd.addEventListener('MozGamepadConnected', @com.badlogic.gdx.controllers.gwt.support.GamepadSupport::handleGamepadConnect(Lcom/badlogic/gdx/controllers/gwt/support/GamepadSupport$GamepadEvent;), false); $wnd.addEventListener('MozGamepadDisconnected', @com.badlogic.gdx.controllers.gwt.support.GamepadSupport::handleGamepadDisconnect(Lcom/badlogic/gdx/controllers/gwt/support/GamepadSupport$GamepadEvent;), false); if ( !! navigator.getGamepads || !! navigator.webkitGamepads || !! navigator.webkitGetGamepads) { @com.badlogic.gdx.controllers.gwt.support.GamepadSupport::startPolling()(); } } }-*/; private static native JsArray<Gamepad> nativePollGamepads() /*-{ return rawGamepads = (navigator.webkitGetGamepads && navigator.webkitGetGamepads()) || navigator.webkitGamepads; }-*/; public static native void consoleLog(String message) /*-{ $wnd.console.log(message); }-*/; private static class Ticker implements AnimationScheduler.AnimationCallback { private boolean ticking = false; public void start() { if (!ticking) { ticking = true; AnimationScheduler.get().requestAnimationFrame(this); } } public void stop() { ticking = false; } @Override public void execute(double timestamp) { if (ticking) { GamepadSupport.pollGamepads(); GamepadSupport.pollGamepadsStatus(); AnimationScheduler.get().requestAnimationFrame(this); } } } private static final class GamepadEvent extends JavaScriptObject { protected GamepadEvent() { // Required by GWT } public native Gamepad getGamepad() /*-{ return this.gamepad; }-*/; } }