Android Input system integration

Hi all



I would be ready to commit the changes needed for the AndroidInput integration into the Jme input system.

Core changes are in RawInputListener, JmeContext, Application and InputManager with the diffs below.



New files are TouchInput interface, TouchListener interface, TouchTrigger class, TouchEvent class (source at the end)



Please have a look. Its compiling on my local copy and i think it should not break the compilation process.

It could break android applications which are not using AndroidHarness.





[patch]Index: src/core/com/jme3/input/RawInputListener.java

===================================================================

— src/core/com/jme3/input/RawInputListener.java (revision 7546)

+++ src/core/com/jme3/input/RawInputListener.java (working copy)

@@ -37,6 +37,7 @@

import com.jme3.input.event.KeyInputEvent;

import com.jme3.input.event.MouseButtonEvent;

import com.jme3.input.event.MouseMotionEvent;

+import com.jme3.input.event.TouchEvent;



/**

  • An interface used for receiving raw input from devices.

    @@ -51,4 +52,7 @@

    public void onMouseMotionEvent(MouseMotionEvent evt);

    public void onMouseButtonEvent(MouseButtonEvent evt);

    public void onKeyEvent(KeyInputEvent evt);

    +
  • // Generic Smartphone input event, used by the Android platform currently
  • public void onTouchEvent(TouchEvent evt);

    }

    [/patch]



    [patch]Index: src/core/com/jme3/system/JmeContext.java

    ===================================================================

    — src/core/com/jme3/system/JmeContext.java (revision 7546)

    +++ src/core/com/jme3/system/JmeContext.java (working copy)

    @@ -35,6 +35,7 @@

    import com.jme3.input.JoyInput;

    import com.jme3.input.KeyInput;

    import com.jme3.input.MouseInput;

    +import com.jme3.input.TouchInput;

    import com.jme3.renderer.Renderer;



    /**

    @@ -124,7 +125,12 @@
  • @return Joystick input implementation. May be null if not available.

    */

    public JoyInput getJoyInput();

    -

    +
  • /**
  • * @return Touch device input implementation. May be null if not available.<br />
    
  • */<br />
    
  • public TouchInput getTouchInput();

    +

    /**
  • @return The timer for this context, or null if not created yet.

    */

    [/patch]



    [patch]Index: src/core/com/jme3/input/InputManager.java

    ===================================================================

    — src/core/com/jme3/input/InputManager.java (revision 7546)

    +++ src/core/com/jme3/input/InputManager.java (working copy)

    @@ -39,6 +39,7 @@

    import com.jme3.input.controls.KeyTrigger;



    import com.jme3.input.controls.MouseAxisTrigger;



    import com.jme3.input.controls.MouseButtonTrigger;



    +import com.jme3.input.controls.TouchListener;



    import com.jme3.input.controls.Trigger;



    import com.jme3.input.event.InputEvent;



    import com.jme3.input.event.JoyAxisEvent;



    @@ -46,6 +47,7 @@

    import com.jme3.input.event.KeyInputEvent;



    import com.jme3.input.event.MouseButtonEvent;



    import com.jme3.input.event.MouseMotionEvent;



    +import com.jme3.input.event.TouchEvent;



    import com.jme3.math.FastMath;



    import com.jme3.math.Vector2f;



    import com.jme3.util.IntMap;



    @@ -70,6 +72,7 @@

    private final KeyInput keys;



    private final MouseInput mouse;



    private final JoyInput joystick;


  • private final TouchInput touch;



    private float frameTPF;



    private long lastLastUpdateTime = 0;



    private long lastUpdateTime = 0;



    @@ -108,7 +111,7 @@
  • @param joyInput


  • @throws IllegalArgumentException If either mouseInput or keyInput are null.



    */


  • public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick) {


  • public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) {



    if (keys == null || mouse == null) {



    throw new NullPointerException("Mouse or keyboard cannot be null");



    }



    @@ -116,6 +119,7 @@

    this.keys = keys;



    this.mouse = mouse;



    this.joystick = joystick;


  •    this.touch = touch;<br />
    



keys.setInputListener(this);

mouse.setInputListener(this);

@@ -123,6 +127,9 @@
joystick.setInputListener(this);

joysticks = joystick.loadJoysticks(this);

}

+ if (touch != null) {

+ touch.setInputListener(this);

+ }



firstTime = keys.getInputTimeNanos();

}

@@ -528,6 +535,22 @@
rawListenerArray = rawListeners.toArray(new RawInputListener[rawListeners.size()]);

return rawListenerArray;

}

+

+ public TouchInput getTouchInput() {

+ return touch;

+ }

+

+ public void setSimulateMouse(boolean value) {

+ if (touch != null) {

+ touch.setSimulateMouse(value);

+ }

+ }

+

+ public void setSimulateKeyboard(boolean value) {

+ if (touch != null) {

+ touch.setSimulateKeyboard(value);

+ }

+ }



private void processQueue() {

int queueSize = inputQueue.size();

@@ -552,6 +575,8 @@
listener.onJoyAxisEvent((JoyAxisEvent) event);

} else if (event instanceof JoyButtonEvent) {

listener.onJoyButtonEvent((JoyButtonEvent) event);

+ } else if (event instanceof TouchEvent) {

+ listener.onTouchEvent((TouchEvent) event);

} else {

assert false;

}

@@ -576,6 +601,8 @@
onJoyAxisEventQueued((JoyAxisEvent) event);

} else if (event instanceof JoyButtonEvent) {

onJoyButtonEventQueued((JoyButtonEvent) event);

+ } else if (event instanceof TouchEvent) {

+ onTouchEventQueued((TouchEvent) event);

} else {

assert false;

}

@@ -603,6 +630,9 @@
if (joystick != null) {

joystick.update();

}

+ if (touch != null) {

+ touch.update();

+ }



eventsPermitted = false;



@@ -612,4 +642,25 @@
lastLastUpdateTime = lastUpdateTime;

lastUpdateTime = currentTime;

}

+

+ /**

+ * Dispatches touch events to touch listeners

+ * @param evt

+ */

+ public void onTouchEventQueued(TouchEvent evt) {

+ for (Mapping mapping : mappings.values()) {

+ for (InputListener listener : mapping.listeners) {

+ if (listener instanceof TouchListener) {

+ ((TouchListener) listener).onTouch(mapping.name, evt, frameTPF);

+ }

+ }

+ }

+ }

+ @Override

+ public void onTouchEvent(TouchEvent evt) {

+ if (!eventsPermitted) {

+ throw new UnsupportedOperationException("TouchInput has raised an event at an illegal time.");

+ }

+ inputQueue.add(evt);

+ }

}

[/patch]

[patch]Index: src/core/com/jme3/app/Application.java
===================================================================
--- src/core/com/jme3/app/Application.java (revision 7546)
+++ src/core/com/jme3/app/Application.java (working copy)
@@ -36,6 +36,7 @@
import com.jme3.input.JoyInput;

import com.jme3.input.KeyInput;

import com.jme3.input.MouseInput;

+import com.jme3.input.TouchInput;

import com.jme3.system.*;

import com.jme3.math.Vector3f;

import com.jme3.renderer.Camera;

@@ -90,6 +91,7 @@
protected MouseInput mouseInput;

protected KeyInput keyInput;

protected JoyInput joyInput;

+ protected TouchInput touchInput;

protected InputManager inputManager;

protected AppStateManager stateManager;



@@ -222,6 +224,10 @@
keyInput = context.getKeyInput();

if (keyInput != null)

keyInput.initialize();

+

+ touchInput = context.getTouchInput();

+ if (touchInput != null)

+ touchInput.initialize();



if (!settings.getBoolean("DisableJoysticks")){

joyInput = context.getJoyInput();

@@ -229,7 +235,7 @@
joyInput.initialize();

}



- inputManager = new InputManager(mouseInput, keyInput, joyInput);

+ inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);

}



private void initStateManager(){

@@ -479,6 +485,9 @@


if (joyInput != null)

joyInput.destroy();

+

+ if (touchInput != null)

+ touchInput.destroy();



inputManager = null;

}

[/patch]

[java]public class TouchEvent extends InputEvent
{
public static enum Type
{
/**
* Touch down event, fields: posX, posY
*/
DOWN,

/**
* Move/Drag event, fields: posX, posY, deltaX, deltaY
*/
MOVE,

/**
* Touch up event, fields: posX, posY
*/
UP,

/**
* Virtual keyboard or hardware key event down, fields: keyCode, characters
*/
KEY_DOWN,

/**
* Virtual keyboard or hardware key event up, fields: keyCode, characters
*/
KEY_UP,

// Single finger gestures
FLING,
TAP,
DOUBLETAP,
LONGPRESSED,

// Two finger scale events
/**
* Two finger scale event start, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
*/
SCALE_START,
/**
* Two finger scale event, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
*/
SCALE_MOVE,
/**
* Two finger scale event end, fields: posX/posY = getFocusX/Y, scaleFactor, scaleSpan
*/
SCALE_END,

/**
* Scroll event
*/
SCROLL,

/**
* The user has performed a down MotionEvent and not performed a move or up yet. This event is commonly used to provide visual feedback to the user to let them know that their action has been recognized i.e. highlight an element.
*/
SHOWPRESS,

// Others
OUTSIDE,
IDLE}

private Type type = Type.IDLE;


private int pointerId;
private float posX;
private float posY;
private float deltaX;
private float deltaY;

// Used only with KEY* events
private int keyCode;
private String characters;

// Used only with SCALE* events
private float scaleFactor;
private float scaleSpan;


public TouchEvent()
{
set(Type.IDLE, 0f, 0f, 0f, 0f);
}
public TouchEvent(Type type, float x, float y, float deltax, float deltay)
{
set(type, x, y, deltax, deltay);
}

public void set(Type type)
{
this.type = type;
this.posX = 0f;
this.posY = 0f;
this.deltaX = 0f;
this.deltaY = 0f;
}

public void set(Type type, float x, float y, float deltax, float deltay)
{
this.type = type;
this.posX = x;
this.posY = y;
this.deltaX = deltax;
this.deltaY = deltay;
}


public Type getType()
{
return type;
}

public float getX()
{
return posX;
}

public float getY()
{
return posY;
}

public float getDeltaX()
{
return deltaX;
}

public float getDeltaY()
{
return deltaY;
}

public Vector2f getDelta()
{
return new Vector2f(deltaX,deltaY);
}

public int getPointerId()
{
return pointerId;
}

public void setPointerId(int pointerId)
{
this.pointerId = pointerId;
}

public int getKeyCode()
{
return keyCode;
}

public void setKeyCode(int keyCode)
{
this.keyCode = keyCode;
}

public String getCharacters()
{
return characters;
}

public void setCharacters(String characters)
{
this.characters = characters;
}

public float getScaleFactor()
{
return scaleFactor;
}

public void setScaleFactor(float scaleFactor)
{
this.scaleFactor = scaleFactor;
}

public float getScaleSpan()
{
return scaleSpan;
}

public void setScaleSpan(float scaleSpan)
{
this.scaleSpan = scaleSpan;
}
}
[/java]

Source is committed. Pls do a svn update, clean, compile and tell me what i have broken.