1 package com.badlogic.gdx.controllers.android;
\r
3 import android.content.Context;
\r
4 import android.hardware.input.InputManager;
\r
5 import android.hardware.input.InputManager.InputDeviceListener;
\r
6 import android.view.InputDevice;
\r
7 import android.view.KeyEvent;
\r
8 import android.view.MotionEvent;
\r
9 import android.view.View;
\r
10 import android.view.View.OnKeyListener;
\r
11 import android.view.View.OnGenericMotionListener;
\r
13 import com.badlogic.gdx.Gdx;
\r
14 import com.badlogic.gdx.backends.android.AndroidApplication;
\r
15 import com.badlogic.gdx.backends.android.AndroidInput;
\r
16 import com.badlogic.gdx.backends.android.AndroidInput.PauseResumeListener;
\r
17 import com.badlogic.gdx.backends.android.AndroidInputThreePlus;
\r
18 import com.badlogic.gdx.controllers.Controller;
\r
19 import com.badlogic.gdx.controllers.ControllerListener;
\r
20 import com.badlogic.gdx.controllers.ControllerManager;
\r
21 import com.badlogic.gdx.utils.Array;
\r
22 import com.badlogic.gdx.utils.IntMap;
\r
23 import com.badlogic.gdx.utils.IntMap.Entry;
\r
24 import com.badlogic.gdx.utils.Pool;
\r
26 public class AndroidControllers implements PauseResumeListener, InputDeviceListener, ControllerManager, OnKeyListener, OnGenericMotionListener {
\r
27 private final static String TAG = "AndroidControllers";
\r
28 private final InputManager inputManager;
\r
29 private final IntMap<AndroidController> controllerMap = new IntMap<AndroidController>();
\r
30 private final Array<Controller> controllers = new Array<Controller>();
\r
31 private final Array<ControllerListener> listeners = new Array<ControllerListener>();
\r
32 private final Array<AndroidControllerEvent> eventQueue = new Array<AndroidControllerEvent>();
\r
33 private final Pool<AndroidControllerEvent> eventPool = new Pool<AndroidControllerEvent>() {
\r
35 protected AndroidControllerEvent newObject () {
\r
36 return new AndroidControllerEvent();
\r
40 public AndroidControllers() {
\r
41 this.inputManager = (InputManager)((Context)Gdx.app).getSystemService(Context.INPUT_SERVICE);
\r
43 // register this instance with pause/resume events and call
\r
44 // resume so that the currently attached devices are initialized
\r
45 ((AndroidInput)Gdx.input).addPauseResumeListener(this);
\r
48 ((AndroidInput)Gdx.input).addKeyListener(this);
\r
49 ((AndroidInputThreePlus)Gdx.input).addGenericMotionListener(this);
\r
50 Gdx.app.log(TAG, "controllers: " + inputManager.getInputDeviceIds().length);
\r
53 private void setupEventQueue() {
\r
56 public void run () {
\r
57 synchronized(eventQueue) {
\r
58 for(AndroidControllerEvent event: eventQueue) {
\r
61 eventPool.freeAll(eventQueue);
\r
64 Gdx.app.postRunnable(this);
\r
70 public boolean onGenericMotion (View view, MotionEvent motionEvent) {
\r
71 AndroidController controller = controllerMap.get(motionEvent.getDeviceId());
\r
72 if(controller != null) {
\r
73 synchronized(eventQueue) {
\r
74 AndroidControllerEvent event = eventPool.obtain();
\r
82 public boolean onKey (View view, int keyCode, KeyEvent keyEvent) {
\r
83 AndroidController controller = controllerMap.get(keyEvent.getDeviceId());
\r
84 if(controller != null) {
\r
85 synchronized(eventQueue) {
\r
86 AndroidControllerEvent event = eventPool.obtain();
\r
87 event.controller = controller;
\r
88 if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
\r
89 event.type = AndroidControllerEvent.BUTTON_DOWN;
\r
91 event.type = AndroidControllerEvent.BUTTON_UP;
\r
93 event.code = keyCode;
\r
94 eventQueue.add(event);
\r
102 private void addController(int deviceId) {
\r
103 InputDevice device = inputManager.getInputDevice(deviceId);
\r
104 if(!isController(device)) return;
\r
105 String name = device.getName();
\r
106 AndroidController controller = new AndroidController(deviceId, name);
\r
107 controllerMap.put(deviceId, controller);
\r
108 synchronized(eventQueue) {
\r
109 AndroidControllerEvent event = eventPool.obtain();
\r
110 event.type = AndroidControllerEvent.CONNECTED;
\r
111 event.controller = controller;
\r
112 eventQueue.add(event);
\r
116 private void removeController(int deviceId) {
\r
117 AndroidController controller = controllerMap.remove(deviceId);
\r
118 if(controller != null) {
\r
119 synchronized(eventQueue) {
\r
120 AndroidControllerEvent event = eventPool.obtain();
\r
121 event.type = AndroidControllerEvent.DISCONNECTED;
\r
122 event.controller = controller;
\r
123 eventQueue.add(event);
\r
128 private boolean isController(InputDevice device) {
\r
129 return ((device.getSources() & InputDevice.SOURCE_GAMEPAD) |
\r
130 (device.getSources() & InputDevice.SOURCE_JOYSTICK)) != 0;
\r
134 public void resume () {
\r
135 inputManager.registerInputDeviceListener(this, ((AndroidApplication)Gdx.app).handler);
\r
137 // gather all joysticks and gamepads, remove any disconnected ones
\r
138 IntMap<AndroidController> removedControllers = new IntMap<AndroidController>();
\r
139 removedControllers.putAll(controllerMap);
\r
141 for(int deviceId: inputManager.getInputDeviceIds()) {
\r
142 InputDevice device = inputManager.getInputDevice(deviceId);
\r
143 AndroidController controller = controllerMap.get(deviceId);
\r
144 if(controller != null) {
\r
145 removedControllers.remove(deviceId);
\r
147 addController(deviceId);
\r
151 for(Entry<AndroidController> entry: removedControllers.entries()) {
\r
152 removeController(entry.key);
\r
157 public void pause () {
\r
158 inputManager.unregisterInputDeviceListener(this);
\r
159 Gdx.app.log(TAG, "controllers paused");
\r
163 public void onInputDeviceAdded (int deviceId) {
\r
164 addController(deviceId);
\r
165 Gdx.app.log(TAG, "device " + deviceId + " added");
\r
169 public void onInputDeviceRemoved (int deviceId) {
\r
170 removeController(deviceId);
\r
171 Gdx.app.log(TAG, "device " + deviceId + " removed");
\r
175 public void onInputDeviceChanged (int deviceId) {
\r
179 public Array<Controller> getControllers () {
\r
180 return controllers;
\r
184 public void addListener (ControllerListener listener) {
\r
185 synchronized(eventQueue) {
\r
186 listeners.add(listener);
\r
191 public void removeListener (ControllerListener listener) {
\r
192 synchronized(eventQueue) {
\r
193 listeners.removeValue(listener, true);
\r