Browse Source

Android: preparation of android tree for jme input integration

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7547 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
kim..ng 14 years ago
parent
commit
dd100bed74

+ 304 - 198
engine/src/android/com/jme3/input/android/AndroidInput.java

@@ -1,9 +1,7 @@
 package com.jme3.input.android;
 package com.jme3.input.android;
 
 
-import java.util.List;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
-
 import android.content.Context;
 import android.content.Context;
 import android.opengl.GLSurfaceView;
 import android.opengl.GLSurfaceView;
 import android.util.AttributeSet;
 import android.util.AttributeSet;
@@ -11,35 +9,37 @@ import android.view.GestureDetector;
 import android.view.KeyEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector;
-import com.jme3.input.android.TouchEvent;
 import com.jme3.input.KeyInput;
 import com.jme3.input.KeyInput;
-import com.jme3.input.MouseInput;
 import com.jme3.input.RawInputListener;
 import com.jme3.input.RawInputListener;
-import com.jme3.input.event.KeyInputEvent;
+import com.jme3.input.TouchInput;
 import com.jme3.input.event.MouseButtonEvent;
 import com.jme3.input.event.MouseButtonEvent;
 import com.jme3.input.event.MouseMotionEvent;
 import com.jme3.input.event.MouseMotionEvent;
+import com.jme3.input.event.TouchEvent;
+import com.jme3.input.event.TouchEvent.Type;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector2f;
+import com.jme3.util.RingBuffer;
 
 
 
 
-public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput, 
+public class AndroidInput extends GLSurfaceView implements TouchInput, 
                                                            GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener
                                                            GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener
 {
 {
     private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
     private final static Logger logger = Logger.getLogger(AndroidInput.class.getName());
+    private boolean isInitialized = false;
+    private RawInputListener listener = null;
+    
+    final private static int MAX_EVENTS = 1024;
     
     
-    private RawInputListener listenerRaw = null;
-    private AndroidTouchInputListener listenerTouch = null;
+    final private RingBuffer<TouchEvent> eventQueue = new RingBuffer<TouchEvent>(MAX_EVENTS);
+    final private RingBuffer<TouchEvent> eventPool = new RingBuffer<TouchEvent>(MAX_EVENTS);
+    final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
+     
+    public boolean fireMouseEvents = true;
+    public boolean fireKeyboardEvents = false;
+
     private ScaleGestureDetector scaledetector;
     private ScaleGestureDetector scaledetector;
     private GestureDetector detector;
     private GestureDetector detector;
     private int lastX;
     private int lastX;
     private int lastY;
     private int lastY;
-    private boolean dragging = false;
-    
-    private List<Object> currentEvents = new ArrayList<Object>();
-
-    private final static int MAX_EVENTS = 1024;
-
-    
-    private boolean FIRE_MOUSE_EVENTS = true;
 
 
    
    
     private static final int[] ANDROID_TO_JME = {
     private static final int[] ANDROID_TO_JME = {
@@ -158,7 +158,41 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
         detector=new GestureDetector(this);
         detector=new GestureDetector(this);
         scaledetector=new ScaleGestureDetector(ctx, this);
         scaledetector=new ScaleGestureDetector(ctx, this);
     }
     }
+    
+    private TouchEvent getNextFreeTouchEvent()
+    {
+        return getNextFreeTouchEvent(false);
+    }
 
 
+    private TouchEvent getNextFreeTouchEvent(boolean wait)
+    {
+        TouchEvent evt;
+        if (eventPool.isEmpty() && wait)
+        {
+            logger.warning("eventPool buffer underrun");
+            boolean isEmpty;
+            do
+            {
+                synchronized(eventPool)
+                {
+                    isEmpty = eventPool.isEmpty();
+                }
+                try { Thread.sleep(50); } catch (InterruptedException e) { }
+            }
+            while (isEmpty);
+            evt = eventPool.pop();
+        }
+        else if (eventPool.isEmpty())
+        {
+            evt = new TouchEvent(); 
+            logger.warning("eventPool buffer underrun");
+        }
+        else
+        {
+            evt = eventPool.pop();    
+        }
+        return evt;
+    }
     /**
     /**
      * onTouchEvent gets called from android thread on touchpad events
      * onTouchEvent gets called from android thread on touchpad events
      */
      */
@@ -166,94 +200,62 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
     public boolean onTouchEvent(MotionEvent event)
     public boolean onTouchEvent(MotionEvent event)
     {
     {
         boolean bWasHandled = false;
         boolean bWasHandled = false;
-        MouseButtonEvent btn;
         TouchEvent touch;
         TouchEvent touch;
-
-        // Send the raw event
-        processEvent(event);
         
         
         // Try to detect gestures
         // Try to detect gestures
         this.detector.onTouchEvent(event);
         this.detector.onTouchEvent(event);
         this.scaledetector.onTouchEvent(event);
         this.scaledetector.onTouchEvent(event);
 
 
-        int newX = getWidth() - (int) event.getX();
-        int newY = (int) event.getY();
         
         
         switch (event.getAction())
         switch (event.getAction())
         {
         {
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_DOWN:
-                                
-                if (FIRE_MOUSE_EVENTS)
-                {
-                   // Handle mouse events 
-                    btn = new MouseButtonEvent(0, true, newX, newY);
-                    btn.setTime(event.getEventTime());
-                    processEvent(btn);
+                
+                // Convert all pointers into events
+                for (int p = 0; p < event.getPointerCount(); p++)
+                {                              
+                    touch = getNextFreeTouchEvent();
+                    touch.set(Type.DOWN, event.getX(p), event.getY(p), 0, 0);
+                    touch.setPointerId(event.getPointerId(p));
+                    touch.setTime(event.getEventTime());
+                    processEvent(touch);
                 }
                 }
-                // Store current pos
-                lastX = -1;
-                lastY = -1;
-
-                // Handle gesture events
-                touch = new TouchEvent(TouchEvent.Type.GRABBED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
-                processEvent(touch);
                 
                 
                 bWasHandled = true;
                 bWasHandled = true;
                 break;
                 break;
                 
                 
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_UP:
                 
                 
-                if (FIRE_MOUSE_EVENTS)
-                {                
-                    // Handle mouse events 
-                    btn = new MouseButtonEvent(0, false, newX, newY);
-                    btn.setTime(event.getEventTime());
-                    processEvent(btn);
-                }         
-                // Store current pos
-                lastX = -1;
-                lastY = -1;
-                
-                // Handle gesture events             
-                if(dragging)
-                {
-                    touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.STOPPED,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
+                // Convert all pointers into events
+                for (int p = 0; p < event.getPointerCount(); p++)
+                {                              
+                    touch = getNextFreeTouchEvent();
+                    touch.set(Type.UP, event.getX(p), event.getY(p), 0, 0);
+                    touch.setPointerId(event.getPointerId(p));
+                    touch.setTime(event.getEventTime());
                     processEvent(touch);
                     processEvent(touch);
                 }
                 }
-                touch = new TouchEvent(TouchEvent.Type.RELEASED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
-                processEvent(touch);
-                dragging=false;
+                                
                 bWasHandled = true;
                 bWasHandled = true;
                 break;
                 break;
             case MotionEvent.ACTION_MOVE:
             case MotionEvent.ACTION_MOVE:
-                if(!scaledetector.isInProgress())
-                {
-                    if(!dragging)
-                        touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.STARTED,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
-                    else
-                        touch = new TouchEvent(TouchEvent.Type.DRAGGED, TouchEvent.Operation.RUNNING,event.getX(),event.getY(),event.getX()-lastX,event.getY()-lastY,null);
-                        
+                
+                // Convert all pointers into events
+                for (int p = 0; p < event.getPointerCount(); p++)
+                {                      
+                    Vector2f lastPos = lastPositions.get(event.getPointerId(p));
+                    if (lastPos == null)
+                    {
+                        lastPos = new Vector2f(event.getX(p), event.getY(p));
+                        lastPositions.put(event.getPointerId(p), lastPos);
+                    }
+                    touch = getNextFreeTouchEvent();
+                    touch.set(Type.MOVE, event.getX(p), event.getY(p), event.getX(p) - lastPos.x, event.getY(p) - lastPos.y);
+                    touch.setPointerId(event.getPointerId(p));
+                    touch.setTime(event.getEventTime());
                     processEvent(touch);
                     processEvent(touch);
-                    dragging=true;
+                    lastPos.set(event.getX(p), event.getY(p));
                 }
                 }
-                if (FIRE_MOUSE_EVENTS)
-                {
-
-                    int dx;
-                    int dy;
-                    if (lastX != -1){
-                        dx = newX - lastX;
-                        dy = newY - lastY;
-                    }else{
-                        dx = 0;
-                        dy = 0;
-                    }                    
-                    MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
-                    mot.setTime(event.getEventTime());
-                    processEvent(mot);
-                }
-                lastX = newX;
-                lastY = newY;
                 bWasHandled = true;
                 bWasHandled = true;
                 break;
                 break;
                 
                 
@@ -274,20 +276,18 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
     }
     }
 
 
     @Override
     @Override
-    public boolean onKeyDown (int keyCode, KeyEvent event) {
-
-        // Send the raw event
-        processEvent(event);
+    public boolean onKeyDown (int keyCode, KeyEvent event) 
+    {
+        TouchEvent evt;
+        evt = getNextFreeTouchEvent();
+        evt.set(TouchEvent.Type.KEY_DOWN);
+        evt.setKeyCode(keyCode);
+        evt.setCharacters(event.getCharacters());
+        evt.setTime(event.getEventTime());
+
+        // Send the event
+        processEvent(evt);
         
         
-        int jmeCode  = ANDROID_TO_JME[keyCode];
-        if (jmeCode != 0)
-        {
-            String str =  event.getCharacters();
-            char c = str != null && str.length() > 0 ? str.charAt(0) : 0x0;
-            KeyInputEvent evt = new KeyInputEvent(jmeCode, c, true, false);
-            logger.info("onKeyDown " + evt);
-            processEvent(evt);
-        }
         // Handle all keys ourself, except the back button (4)
         // Handle all keys ourself, except the back button (4)
         if (keyCode == 4)
         if (keyCode == 4)
             return false;
             return false;
@@ -296,20 +296,17 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
     }
     }
 
 
     @Override
     @Override
-    public boolean onKeyUp (int keyCode, KeyEvent event) {
+    public boolean onKeyUp (int keyCode, KeyEvent event) 
+    {       
+        TouchEvent evt;        
+        evt = getNextFreeTouchEvent();        
+        evt.set(TouchEvent.Type.KEY_UP);
+        evt.setKeyCode(keyCode);
+        evt.setCharacters(event.getCharacters());
+        evt.setTime(event.getEventTime());
         
         
-        // Send the raw event
-        processEvent(event);
-        
-        int jmeCode  = ANDROID_TO_JME[keyCode];
-        if (jmeCode != 0)
-        {            
-            String str =  event.getCharacters();
-            char c = str != null && str.length() > 0 ? str.charAt(0) : 0x0;
-            KeyInputEvent evt = new KeyInputEvent(jmeCode, c, false, false);
-            logger.info("onKeyUp " + evt);
-            processEvent(evt);
-        }
+        // Send the event
+        processEvent(evt);
         
         
         // Handle all keys ourself, except the back button (4)
         // Handle all keys ourself, except the back button (4)
         if (keyCode == 4)
         if (keyCode == 4)
@@ -318,80 +315,142 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
             return true;
             return true;
     }
     }
 
 
-    public void setCursorVisible(boolean visible){
-    }
 
 
-    public int getButtonCount(){
-        return 255;
+    // -----------------------------------------
+    // JME3 Input interface
+    @Override
+    public void initialize() 
+    {       
+        TouchEvent item;
+        for (int i = 0; i < MAX_EVENTS; i++)
+        {
+            item = new TouchEvent();
+            eventPool.push(item);
+        }
+        isInitialized = true;
     }
     }
-
-    public void initialize() {
+    
+    @Override
+    public void destroy() 
+    {
+        isInitialized = false;
+        
+        // Clean up queues
+        while (! eventPool.isEmpty())
+        {
+            eventPool.pop();
+        }
+        while (! eventQueue.isEmpty())
+        {
+            eventQueue.pop();
+        }
     }
     }
-
-    public void update() {
-		generateEvents();
+    
+    @Override
+    public boolean isInitialized() 
+    {
+        return isInitialized;
     }
     }
-
-    public void destroy() {
+    
+    @Override
+    public void setInputListener(RawInputListener listener) 
+    {
+        this.listener = listener;
     }
     }
-
-    public boolean isInitialized() {
-        return true;
+    
+    @Override
+    public long getInputTimeNanos() 
+    {
+        return System.nanoTime();
     }
     }
+    // -----------------------------------------
 
 
-
-
-	private void processEvent(Object event) 
+	private void processEvent(TouchEvent event) 
 	{
 	{
-		synchronized (currentEvents) {
-			if (currentEvents.size() < MAX_EVENTS)
-				currentEvents.add(event);
+		synchronized (eventQueue) 
+		{
+		    eventQueue.push(event);
 		}
 		}
 	}
 	}
 
 
-	Object event;
-	private void generateEvents() {
-	    if (listenerRaw != null)
-	    {
-    		synchronized (currentEvents) {
-    			//for (Object event: currentEvents) {
-    			for (int i = 0; i < currentEvents.size(); i++) {
-    			    event = currentEvents.get(i);
-    				if (event instanceof MouseButtonEvent) {
-    				    listenerRaw.onMouseButtonEvent((MouseButtonEvent) event);
-    				} else if (event instanceof MouseMotionEvent) {
-    					listenerRaw.onMouseMotionEvent((MouseMotionEvent) event);
-    				} else if (event instanceof KeyInputEvent) {
-    					listenerRaw.onKeyEvent((KeyInputEvent) event);				
-                    } else if (event instanceof TouchEvent) {
-                        if (listenerTouch != null)
-                            listenerTouch.onTouchEvent((TouchEvent) event);
-                    } else if (event instanceof MotionEvent) {
-                        if (listenerTouch != null)
-                            listenerTouch.onMotionEvent((MotionEvent) event);                                                                        
-                    } else if (event instanceof KeyEvent) {
-                        if (listenerTouch != null)
-                            listenerTouch.onAndroidKeyEvent((KeyEvent) event);
-                    }    				    				    				
-    			}
-    			currentEvents.clear();
-    		}
-	    }
-	}
-
-    public void setInputListener(RawInputListener listener) {
-        this.listenerRaw = listener;
-    }
-    
-    public void setInputListener(AndroidTouchInputListener listener) {
-        this.listenerRaw = listener;
-        this.listenerTouch = listener;
-    }
-
-    public long getInputTimeNanos() {
-        return System.nanoTime();
+	@Override
+    public void update() 
+    {
+        generateEvents();
     }
     }
+	
+	private void generateEvents() 
+	{
+	    if (listener != null)
+	    {	        
+	        TouchEvent event;
+	        MouseButtonEvent btn;
+	        int newX;
+	        int newY;
+	        
+	        while (!eventQueue.isEmpty())
+	        {
+	            synchronized (eventQueue) 
+	            {
+	                event = eventQueue.pop();
+	            }
+	            if (event != null)
+	            {
+	                listener.onTouchEvent(event);
+
+                    if (fireMouseEvents)
+                    {
+    	                newX = getWidth() - (int) event.getX();
+    	                newY = (int) event.getY();
+    	                switch (event.getType())
+    	                {
+    	                    case DOWN:    	                  
+         	                    // Handle mouse events 
+        	                    btn = new MouseButtonEvent(0, true, newX, newY);
+        	                    btn.setTime(event.getTime());
+        	                    listener.onMouseButtonEvent(btn);
+        	                    // Store current pos
+        	                    lastX = -1;
+        	                    lastY = -1;
+        	                    break;
+        	                    
+    	                    case UP:
+    	                        // Handle mouse events 
+    	                        btn = new MouseButtonEvent(0, false, newX, newY);
+    	                        btn.setTime(event.getTime());
+    	                        listener.onMouseButtonEvent(btn);
+    	                        // Store current pos
+    	                        lastX = -1;
+    	                        lastY = -1;
+    	                        break;
+    	                        
+    	                    case MOVE:
+    	                        int dx;
+    	                        int dy;
+    	                        if (lastX != -1){
+    	                            dx = newX - lastX;
+    	                            dy = newY - lastY;
+    	                        }else{
+    	                            dx = 0;
+    	                            dy = 0;
+    	                        }                    
+    	                        MouseMotionEvent mot = new MouseMotionEvent(newX, newY, dx, dy, 0, 0);
+    	                        mot.setTime(event.getTime());
+    	                        listener.onMouseMotionEvent(mot);
+    	                        lastX = newX;
+    	                        lastY = newY;
+    	                        break;
+            	        }	                
+                    }
+	            }
+	            synchronized (eventPool) 
+	            {
+	                eventPool.push(event);
+	            }	            
+	        }
 
 
+	    }
+	}
     
     
     // --------------- Gesture detected callback events ----------------------------------
     // --------------- Gesture detected callback events ----------------------------------
     
     
@@ -401,75 +460,122 @@ public class AndroidInput extends GLSurfaceView implements KeyInput, MouseInput,
     }
     }
 
 
     public void onLongPress(MotionEvent event)
     public void onLongPress(MotionEvent event)
-    {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.LONGPRESSED, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
+    {        
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.LONGPRESSED, event.getX(), event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
         processEvent(touch);
         processEvent(touch);
     }
     }
 
 
     public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy)
     public boolean onFling(MotionEvent event, MotionEvent event2, float vx, float vy)
     {
     {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.FLING, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.FLING, event.getX(), event.getY(), vx, vy);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
         processEvent(touch);
         processEvent(touch);
+        
         return true;
         return true;
     }
     }
 
 
     public boolean onSingleTapConfirmed(MotionEvent event)
     public boolean onSingleTapConfirmed(MotionEvent event)
-    {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.TAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
+    {        
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
         processEvent(touch);
         processEvent(touch);
+        
         return true;
         return true;
     }
     }
 
 
     public boolean onDoubleTap(MotionEvent event)
     public boolean onDoubleTap(MotionEvent event)
     {
     {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.DOUBLETAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
-        processEvent(touch);
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.DOUBLETAP, event.getX(), event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);        
         return true;
         return true;
     }
     }
 
 
     public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector)
     public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector)
-    {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.STARTED,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
-        processEvent(touch);
+    {     
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.SCALE_START, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan()); 
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch); 
+        
         return true;
         return true;
     }
     }
 
 
     public boolean onScale(ScaleGestureDetector scaleGestureDetector)
     public boolean onScale(ScaleGestureDetector scaleGestureDetector)
     {        
     {        
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.RUNNING,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
-        processEvent(touch);
-        
-        if (FIRE_MOUSE_EVENTS)
-        {                                
-            MouseMotionEvent mot = new MouseMotionEvent(0, 0, 0, 0, 0, (int)scaleGestureDetector.getScaleFactor());
-            mot.setTime(scaleGestureDetector.getEventTime());
-            processEvent(mot);
-        }
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.SCALE_MOVE, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan()); 
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch); 
+             
         return false;
         return false;
     }
     }
 
 
     public void onScaleEnd(ScaleGestureDetector scaleGestureDetector)
     public void onScaleEnd(ScaleGestureDetector scaleGestureDetector)
-    {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.SCALE, TouchEvent.Operation.STOPPED,scaleGestureDetector.getFocusX(),scaleGestureDetector.getFocusY(),0,0,new float[]{scaleGestureDetector.getCurrentSpan(),scaleGestureDetector.getScaleFactor()});
-        processEvent(touch);        
+    {        
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.SCALE_END, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(scaleGestureDetector.getEventTime());
+        touch.setScaleSpan(scaleGestureDetector.getCurrentSpan()); 
+        touch.setScaleFactor(scaleGestureDetector.getScaleFactor());
+        processEvent(touch);      
     }
     }
 
 
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
-            float distanceY) {
-        // TODO Auto-generated method stub
+    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) 
+    {
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.SCROLL, e1.getX(), e1.getY(), distanceX, distanceY);
+        touch.setPointerId(0);
+        touch.setTime(e1.getEventTime());
+        processEvent(touch);
         return false;
         return false;
     }
     }
 
 
-    public void onShowPress(MotionEvent e) {
-        // TODO Auto-generated method stub
-        
+    public void onShowPress(MotionEvent event) 
+    {
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.SHOWPRESS, event.getX(), event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
+        processEvent(touch);
     }
     }
 
 
     public boolean onSingleTapUp(MotionEvent event) 
     public boolean onSingleTapUp(MotionEvent event) 
-    {
-        TouchEvent touch = new TouchEvent(TouchEvent.Type.TAP, TouchEvent.Operation.NOP,event.getX(),event.getY(),0,0,null);
+    {       
+        TouchEvent touch = getNextFreeTouchEvent(); 
+        touch.set(Type.TAP, event.getX(), event.getY(), 0f, 0f);
+        touch.setPointerId(0);
+        touch.setTime(event.getEventTime());
         processEvent(touch);
         processEvent(touch);
         return true;
         return true;
     }
     }
 
 
+    @Override
+    public void setSimulateMouse(boolean simulate) 
+    {
+        fireMouseEvents = simulate;       
+    }
+
+    @Override
+    public void setSimulateKeyboard(boolean simulate) 
+    {
+        fireKeyboardEvents = simulate;        
+    }
+
 }
 }

+ 1 - 0
engine/src/android/com/jme3/input/android/AndroidTouchInputListener.java

@@ -1,6 +1,7 @@
 package com.jme3.input.android;
 package com.jme3.input.android;
 
 
 import com.jme3.input.RawInputListener;
 import com.jme3.input.RawInputListener;
+import com.jme3.input.event.TouchEvent;
 
 
 import android.view.KeyEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent;

+ 0 - 76
engine/src/android/com/jme3/input/android/TouchEvent.java

@@ -1,76 +0,0 @@
-package com.jme3.input.android;
-
-import com.jme3.math.Vector2f;
-
-public class TouchEvent
-{
-    public static enum Type {GRABBED,DRAGGED,RELEASED,FLING,TAP,DOUBLETAP,LONGPRESSED,SCALE,OUTSIDE,IDLE}
-    public Type type=Type.IDLE;
-
-    public static enum Operation {NOP,STARTED,RUNNING,STOPPED,CANCELED}
-    private Operation operation=Operation.NOP;
-
-    public float x;
-    public float y;
-    public float deltax;
-    public float deltay;
-    public float[] extra;
-
-    public TouchEvent(Type type, Operation operation, float x, float y, float deltax, float deltay, float[] extra)
-    {
-        set(type, operation, x, y, deltax, deltay, extra);
-    }
-
-    public void set( Type type, Operation operation, float x, float y, float deltax, float deltay, float[] extra)
-    {
-        this.type=type;
-        this.operation=operation;
-        this.x=x;
-        this.y=y;
-        this.deltax=deltax;
-        this.deltay=deltay;
-        this.extra=extra;
-    }
-
-
-    public Type getType()
-    {
-        return type;
-    }
-
-    public Operation getOperation()
-    {
-        return operation;
-    }
-
-
-    public float getX()
-    {
-        return x;
-    }
-
-    public float getY()
-    {
-        return y;
-    }
-
-    public float getDeltaX()
-    {
-        return deltax;
-    }
-
-    public float getDeltaY()
-    {
-        return deltay;
-    }
-
-    public float[] getExtra()
-    {
-        return extra;
-    }
-
-    public Vector2f getDelta()
-    {
-        return new Vector2f(deltax,deltay);
-    }
-}

+ 11 - 2
engine/src/android/com/jme3/system/android/OGLESContext.java

@@ -41,7 +41,10 @@ import com.jme3.app.AndroidHarness;
 import com.jme3.input.JoyInput;
 import com.jme3.input.JoyInput;
 import com.jme3.input.KeyInput;
 import com.jme3.input.KeyInput;
 import com.jme3.input.MouseInput;
 import com.jme3.input.MouseInput;
+import com.jme3.input.TouchInput;
 import com.jme3.input.android.AndroidInput;
 import com.jme3.input.android.AndroidInput;
+import com.jme3.input.dummy.DummyKeyInput;
+import com.jme3.input.dummy.DummyMouseInput;
 import com.jme3.renderer.android.OGLESShaderRenderer;
 import com.jme3.renderer.android.OGLESShaderRenderer;
 import com.jme3.system.AppSettings;
 import com.jme3.system.AppSettings;
 import com.jme3.system.JmeContext;
 import com.jme3.system.JmeContext;
@@ -231,18 +234,23 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
 
 
     @Override
     @Override
     public MouseInput getMouseInput() {
     public MouseInput getMouseInput() {
-        return view;
+        return new DummyMouseInput();
     }
     }
 
 
     @Override
     @Override
     public KeyInput getKeyInput() {
     public KeyInput getKeyInput() {
-        return view;
+        return new DummyKeyInput();
     }
     }
     
     
     @Override
     @Override
     public JoyInput getJoyInput() {
     public JoyInput getJoyInput() {
         return null;
         return null;
     }
     }
+
+    @Override
+    public TouchInput getTouchInput() {
+        return view;
+    }
     
     
     @Override
     @Override
     public Timer getTimer() 
     public Timer getTimer() 
@@ -386,4 +394,5 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
         }
         }
     }
     }
 
 
+
 }
 }

+ 63 - 0
engine/src/android/com/jme3/util/RingBuffer.java

@@ -0,0 +1,63 @@
+package com.jme3.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Ring buffer (fixed size queue) implementation using a circular array (array with wrap-around).
+ */
+// suppress unchecked warnings in Java 1.5.0_6 and later
+@SuppressWarnings("unchecked")
+public class RingBuffer<Item> implements Iterable<Item> 
+{
+    private Item[] buffer;          // queue elements
+    private int count = 0;          // number of elements on queue
+    private int indexOut = 0;       // index of first element of queue
+    private int indexIn  = 0;       // index of next available slot
+
+    // cast needed since no generic array creation in Java
+    public RingBuffer(int capacity) 
+    {
+        buffer = (Item[]) new Object[capacity];
+    }
+
+    public boolean isEmpty() { return count == 0; }
+    public int size()        { return count;      }
+
+    public void push(Item item) 
+    {
+        if (count == buffer.length) { throw new RuntimeException("Ring buffer overflow"); }
+        buffer[indexIn] = item;
+        indexIn = (indexIn + 1) % buffer.length;     // wrap-around
+        count++;
+    }
+
+    public Item pop() 
+    {
+        if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
+        Item item = buffer[indexOut];
+        buffer[indexOut] = null;                  // to help with garbage collection
+        count--;
+        indexOut = (indexOut + 1) % buffer.length; // wrap-around
+        return item;
+    }
+
+    public Iterator<Item> iterator() { return new RingBufferIterator(); }
+
+    // an iterator, doesn't implement remove() since it's optional
+    private class RingBufferIterator implements Iterator<Item> {
+        private int i = 0;
+        public boolean hasNext()  { return i < count; }
+        public void remove()      { throw new UnsupportedOperationException();  }
+
+        public Item next() {
+            if (!hasNext()) throw new NoSuchElementException();
+            return buffer[i++];
+        }
+    }
+
+
+
+
+}
+