From 5b84be227af63e4a0dd0d1d2820a541bbcc237e2 Mon Sep 17 00:00:00 2001 From: Mayank Sharma Date: Sat, 29 Mar 2014 16:40:12 +0530 Subject: [PATCH 1/6] end application when TestChooser dialog is closed added a WindowListener in the constructor that overrides the windowsClosing method to dispose the TestChooser dialog. code tested with positive result for issue#85. --- jme3-examples/src/main/java/jme3test/TestChooser.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jme3-examples/src/main/java/jme3test/TestChooser.java b/jme3-examples/src/main/java/jme3test/TestChooser.java index b72ab725a..043c3e6d5 100644 --- a/jme3-examples/src/main/java/jme3test/TestChooser.java +++ b/jme3-examples/src/main/java/jme3test/TestChooser.java @@ -84,6 +84,16 @@ public class TestChooser extends JDialog { */ public TestChooser() throws HeadlessException { super((JFrame) null, "TestChooser"); + /** This listener ends application when window is closed (x button on top right corner of test chooser). + * @see issue#85 https://github.com/jMonkeyEngine/jmonkeyengine/issues/85 + */ + addWindowListener(new WindowAdapter(){ + @Override + public void windowClosing(WindowEvent e) + { + dispose(); + } + }); } /** From 4c320f686dbef4a6eba8bc5de201cf86c5f2d6ac Mon Sep 17 00:00:00 2001 From: Mayank Sharma Date: Mon, 31 Mar 2014 16:15:54 +0530 Subject: [PATCH 2/6] issue#85 short approach - setDefaultCloseOperation --- jme3-examples/src/main/java/jme3test/TestChooser.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/jme3-examples/src/main/java/jme3test/TestChooser.java b/jme3-examples/src/main/java/jme3test/TestChooser.java index 043c3e6d5..a2251945e 100644 --- a/jme3-examples/src/main/java/jme3test/TestChooser.java +++ b/jme3-examples/src/main/java/jme3test/TestChooser.java @@ -87,13 +87,7 @@ public class TestChooser extends JDialog { /** This listener ends application when window is closed (x button on top right corner of test chooser). * @see issue#85 https://github.com/jMonkeyEngine/jmonkeyengine/issues/85 */ - addWindowListener(new WindowAdapter(){ - @Override - public void windowClosing(WindowEvent e) - { - dispose(); - } - }); + setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); } /** From 7df0b41585a107014c288d8724b1653c0c88426a Mon Sep 17 00:00:00 2001 From: sploreg Date: Wed, 2 Apr 2014 14:49:29 -0700 Subject: [PATCH 3/6] TerrainLodControl no longer caches camera positions. Issue #121 --- .../com/jme3/terrain/geomipmap/TerrainLodControl.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java index 96bedc21f..f52eaee01 100644 --- a/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java +++ b/jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java @@ -160,11 +160,10 @@ public class TerrainLodControl extends AbstractControl { } if (cameras != null) { - if (cameraLocations.isEmpty() && !cameras.isEmpty()) { - for (Camera c : cameras) // populate them - { - cameraLocations.add(c.getLocation()); - } + cameraLocations.clear(); + for (Camera c : cameras) // populate them + { + cameraLocations.add(c.getLocation()); } updateLOD(cameraLocations, lodCalculator); } From 10af945f362c2d642c01e89159270ce80663e9ea Mon Sep 17 00:00:00 2001 From: Normen Hansen Date: Thu, 3 Apr 2014 00:47:46 +0200 Subject: [PATCH 4/6] set buildNativeProjects to false for now --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d8edbb788..2ce238e65 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ jmeVersionSuffix = -pre-alpha-svn # specify if SDK and Native libraries get built buildSdkProject = true -buildNativeProjects = true +buildNativeProjects = false # Path to android NDK for building native libraries #ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7 From 625264b6d89490d6092b209d4ecb07fd517040ba Mon Sep 17 00:00:00 2001 From: Kostyantyn Hushchyn Date: Thu, 3 Apr 2014 04:27:43 +0300 Subject: [PATCH 5/6] Added base input handler - touch and simulated mouse --- .../com/jme3/input/ios/IosInputHandler.java | 203 ++++++++++++++++++ .../com/jme3/input/ios/IosTouchHandler.java | 191 ++++++++++++++++ .../com/jme3/input/ios/TouchEventPool.java | 121 +++++++++++ .../com/jme3/system/ios/IGLESContext.java | 13 +- .../main/java/com/jme3/util/RingBuffer.java | 76 +++++++ 5 files changed, 597 insertions(+), 7 deletions(-) create mode 100644 jme3-ios/src/main/java/com/jme3/input/ios/IosInputHandler.java create mode 100644 jme3-ios/src/main/java/com/jme3/input/ios/IosTouchHandler.java create mode 100644 jme3-ios/src/main/java/com/jme3/input/ios/TouchEventPool.java create mode 100644 jme3-ios/src/main/java/com/jme3/util/RingBuffer.java diff --git a/jme3-ios/src/main/java/com/jme3/input/ios/IosInputHandler.java b/jme3-ios/src/main/java/com/jme3/input/ios/IosInputHandler.java new file mode 100644 index 000000000..19b08fd61 --- /dev/null +++ b/jme3-ios/src/main/java/com/jme3/input/ios/IosInputHandler.java @@ -0,0 +1,203 @@ +package com.jme3.input.ios; + +import com.jme3.input.RawInputListener; +import com.jme3.input.TouchInput; +import com.jme3.input.event.InputEvent; +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.system.AppSettings; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class IosInputHandler implements TouchInput { + private static final Logger logger = Logger.getLogger(IosInputHandler.class.getName()); + + private final static int MAX_TOUCH_EVENTS = 1024; + + // Custom settings + private boolean mouseEventsEnabled = true; + private boolean mouseEventsInvertX = false; + private boolean mouseEventsInvertY = false; + private boolean keyboardEventsEnabled = false; + private boolean dontSendHistory = false; + + // Internal + private boolean initialized = false; + private RawInputListener listener = null; + private ConcurrentLinkedQueue inputEventQueue = new ConcurrentLinkedQueue(); + private final TouchEventPool touchEventPool = new TouchEventPool(MAX_TOUCH_EVENTS); + private IosTouchHandler touchHandler; + private float scaleX = 1f; + private float scaleY = 1f; + private int width = 0; + private int height = 0; + + public IosInputHandler() { + touchHandler = new IosTouchHandler(this); + } + @Override + public void initialize() { + touchEventPool.initialize(); + if (touchHandler != null) { + touchHandler.initialize(); + } + initialized = true; + } + + @Override + public void update() { + logger.log(Level.FINE, "InputEvent update : {0}", + new Object[]{listener}); + if (listener != null) { + InputEvent inputEvent; + + while ((inputEvent = inputEventQueue.poll()) != null) { + if (inputEvent instanceof TouchEvent) { + listener.onTouchEvent((TouchEvent)inputEvent); + } else if (inputEvent instanceof MouseButtonEvent) { + listener.onMouseButtonEvent((MouseButtonEvent)inputEvent); + } else if (inputEvent instanceof MouseMotionEvent) { + listener.onMouseMotionEvent((MouseMotionEvent)inputEvent); + } else if (inputEvent instanceof KeyInputEvent) { + listener.onKeyEvent((KeyInputEvent)inputEvent); + } + } + } + } + + @Override + public void destroy() { + initialized = false; + touchEventPool.destroy(); + if (touchHandler != null) { + touchHandler.destroy(); + } + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public void setInputListener(RawInputListener listener) { + this.listener = listener; + } + + @Override + public long getInputTimeNanos() { + return System.nanoTime(); + } + + @Override + public void setSimulateMouse(boolean simulate) { + this.mouseEventsEnabled = simulate; + } + + @Override + public boolean getSimulateMouse() { + return mouseEventsEnabled; + } + + @Override + public boolean isSimulateMouse() { + return mouseEventsEnabled; + } + + @Override + public void setSimulateKeyboard(boolean simulate) { + this.keyboardEventsEnabled = simulate; + } + + @Override + public void setOmitHistoricEvents(boolean dontSendHistory) { + this.dontSendHistory = dontSendHistory; + } + + @Override + public void showVirtualKeyboard(boolean visible) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + // ---------------- + + public void loadSettings(AppSettings settings) { + // TODO: add simulate keyboard to settings +// keyboardEventsEnabled = true; + mouseEventsEnabled = true;//settings.isEmulateMouse(); + mouseEventsInvertX = settings.isEmulateMouseFlipX(); + mouseEventsInvertY = settings.isEmulateMouseFlipY(); + + // view width and height are 0 until the view is displayed on the screen + //if (view.getWidth() != 0 && view.getHeight() != 0) { + // scaleX = (float)settings.getWidth() / (float)view.getWidth(); + // scaleY = (float)settings.getHeight() / (float)view.getHeight(); + //} + scaleX = 1.0f; + scaleY = 1.0f; + width = settings.getWidth(); + height = settings.getHeight(); + logger.log(Level.FINE, "Setting input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}", + new Object[]{scaleX, scaleY, width, height}); + } + + public boolean isMouseEventsInvertX() { + return mouseEventsInvertX; + } + + public boolean isMouseEventsInvertY() { + return mouseEventsInvertY; + } + + public float invertX(float origX) { + return getJmeX(width) - origX; + } + + public float invertY(float origY) { + return getJmeY(height) - origY; + } + + public float getJmeX(float origX) { + return origX * scaleX; + } + + public float getJmeY(float origY) { + return origY * scaleY; + } + + public TouchEvent getFreeTouchEvent() { + return touchEventPool.getNextFreeEvent(); + } + + public void addEvent(InputEvent event) { + inputEventQueue.add(event); + if (event instanceof TouchEvent) { + touchEventPool.storeEvent((TouchEvent)event); + } + } + + // ---------------- + + public void injectTouchDown(int pointerId, long time, float x, float y) { + logger.log(Level.FINE, "Using input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}", + new Object[]{scaleX, scaleY, width, height}); + if (touchHandler != null) { + touchHandler.actionDown(pointerId, time, x, y); + } + } + + public void injectTouchUp(int pointerId, long time, float x, float y) { + if (touchHandler != null) { + touchHandler.actionUp(pointerId, time, x, y); + } + } + + public void injectTouchMove(int pointerId, long time, float x, float y) { + if (touchHandler != null) { + touchHandler.actionMove(pointerId, time, x, y); + } + } +} diff --git a/jme3-ios/src/main/java/com/jme3/input/ios/IosTouchHandler.java b/jme3-ios/src/main/java/com/jme3/input/ios/IosTouchHandler.java new file mode 100644 index 000000000..ea157e250 --- /dev/null +++ b/jme3-ios/src/main/java/com/jme3/input/ios/IosTouchHandler.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.input.ios; + +import com.jme3.input.event.InputEvent; +import com.jme3.input.event.MouseButtonEvent; +import com.jme3.input.event.MouseMotionEvent; +import com.jme3.input.event.TouchEvent; +import static com.jme3.input.event.TouchEvent.Type.DOWN; +import static com.jme3.input.event.TouchEvent.Type.MOVE; +import static com.jme3.input.event.TouchEvent.Type.UP; +import com.jme3.math.Vector2f; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * AndroidTouchHandler is the base class that receives touch inputs from the + * Android system and creates the TouchEvents for jME. This class is designed + * to handle the base touch events for Android rev 9 (Android 2.3). This is + * extended by other classes to add features that were introducted after + * Android rev 9. + * + * @author iwgeric + */ +public class IosTouchHandler { + private static final Logger logger = Logger.getLogger(IosTouchHandler.class.getName()); + + final private HashMap lastPositions = new HashMap(); + + protected int numPointers = 1; + + protected IosInputHandler iosInput; + + public IosTouchHandler(IosInputHandler iosInput) { + this.iosInput = iosInput; + } + + public void initialize() { + } + + public void destroy() { + } + + public void actionDown(int pointerId, long time, float x, float y) { + logger.log(Level.FINE, "Inject input pointer: {0}, time: {1}, x: {2}, y: {3}", + new Object[]{pointerId, time, x, y}); + float jmeX = iosInput.getJmeX(x); + float jmeY = iosInput.invertY(iosInput.getJmeY(y)); + TouchEvent touch = iosInput.getFreeTouchEvent(); + touch.set(TouchEvent.Type.DOWN, jmeX, jmeY, 0, 0); + touch.setPointerId(pointerId);//TODO: pointer ID + touch.setTime(time); + touch.setPressure(1.0f); + //touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure + + lastPositions.put(pointerId, new Vector2f(jmeX, jmeY)); + + processEvent(touch); + } + + public void actionUp(int pointerId, long time, float x, float y) { + float jmeX = iosInput.getJmeX(x); + float jmeY = iosInput.invertY(iosInput.getJmeY(y)); + TouchEvent touch = iosInput.getFreeTouchEvent(); + touch.set(TouchEvent.Type.UP, jmeX, jmeY, 0, 0); + touch.setPointerId(pointerId);//TODO: pointer ID + touch.setTime(time); + touch.setPressure(1.0f); + //touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure + lastPositions.remove(pointerId); + + processEvent(touch); + } + + public void actionMove(int pointerId, long time, float x, float y) { + float jmeX = iosInput.getJmeX(x); + float jmeY = iosInput.invertY(iosInput.getJmeY(y)); + Vector2f lastPos = lastPositions.get(pointerId); + if (lastPos == null) { + lastPos = new Vector2f(jmeX, jmeY); + lastPositions.put(pointerId, lastPos); + } + + float dX = jmeX - lastPos.x; + float dY = jmeY - lastPos.y; + if (dX != 0 || dY != 0) { + TouchEvent touch = iosInput.getFreeTouchEvent(); + touch.set(TouchEvent.Type.MOVE, jmeX, jmeY, dX, dY); + touch.setPointerId(pointerId); + touch.setTime(time); + touch.setPressure(1.0f); + //touch.setPressure(event.getPressure(p)); + lastPos.set(jmeX, jmeY); + + processEvent(touch); + } + } + + protected void processEvent(TouchEvent event) { + // Add the touch event + iosInput.addEvent(event); + // MouseEvents do not support multi-touch, so only evaluate 1 finger pointer events + if (iosInput.isSimulateMouse() && numPointers == 1) { + InputEvent mouseEvent = generateMouseEvent(event); + if (mouseEvent != null) { + // Add the mouse event + iosInput.addEvent(mouseEvent); + } + } + + } + + // TODO: Ring Buffer for mouse events? + protected InputEvent generateMouseEvent(TouchEvent event) { + InputEvent inputEvent = null; + int newX; + int newY; + int newDX; + int newDY; + + if (iosInput.isMouseEventsInvertX()) { + newX = (int) (iosInput.invertX(event.getX())); + newDX = (int)event.getDeltaX() * -1; + } else { + newX = (int) event.getX(); + newDX = (int)event.getDeltaX(); + } + + if (iosInput.isMouseEventsInvertY()) { + newY = (int) (iosInput.invertY(event.getY())); + newDY = (int)event.getDeltaY() * -1; + } else { + newY = (int) event.getY(); + newDY = (int)event.getDeltaY(); + } + + switch (event.getType()) { + case DOWN: + // Handle mouse down event + inputEvent = new MouseButtonEvent(0, true, newX, newY); + inputEvent.setTime(event.getTime()); + break; + + case UP: + // Handle mouse up event + inputEvent = new MouseButtonEvent(0, false, newX, newY); + inputEvent.setTime(event.getTime()); + break; + + case HOVER_MOVE: + case MOVE: + inputEvent = new MouseMotionEvent(newX, newY, newDX, newDY, (int)event.getScaleSpan(), (int)event.getDeltaScaleSpan()); + inputEvent.setTime(event.getTime()); + break; + } + + return inputEvent; + } + +} diff --git a/jme3-ios/src/main/java/com/jme3/input/ios/TouchEventPool.java b/jme3-ios/src/main/java/com/jme3/input/ios/TouchEventPool.java new file mode 100644 index 000000000..f986db155 --- /dev/null +++ b/jme3-ios/src/main/java/com/jme3/input/ios/TouchEventPool.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.input.ios; + +import com.jme3.input.event.TouchEvent; +import com.jme3.util.RingBuffer; +import java.util.logging.Logger; + +/** + * TouchEventPool provides a RingBuffer of jME TouchEvents to help with garbage + * collection on Android. Each TouchEvent is stored in the RingBuffer and is + * reused if the TouchEvent has been consumed. + * + * If a TouchEvent has not been consumed, it is placed back into the pool at the + * end for later use. If a TouchEvent has been consumed, it is reused to avoid + * creating lots of little objects. + * + * If the pool is full of unconsumed events, then a new event is created and provided. + * + * + * @author iwgeric + */ +public class TouchEventPool { + private static final Logger logger = Logger.getLogger(TouchEventPool.class.getName()); + private final RingBuffer eventPool; + private final int maxEvents; + + public TouchEventPool (int maxEvents) { + eventPool = new RingBuffer(maxEvents); + this.maxEvents = maxEvents; + } + + public void initialize() { + TouchEvent newEvent; + while (!eventPool.isEmpty()) { + eventPool.pop(); + } + for (int i = 0; i < maxEvents; i++) { + newEvent = new TouchEvent(); + newEvent.setConsumed(); + eventPool.push(newEvent); + } + } + + public void destroy() { + // Clean up queues + while (!eventPool.isEmpty()) { + eventPool.pop(); + } + } + + /** + * Fetches a touch event from the reuse pool + * + * @return a usable TouchEvent + */ + public TouchEvent getNextFreeEvent() { + TouchEvent evt = null; + int curSize = eventPool.size(); + while (curSize > 0) { + evt = (TouchEvent)eventPool.pop(); + if (evt.isConsumed()) { + break; + } else { + eventPool.push(evt); + evt = null; + } + curSize--; + } + + if (evt == null) { + logger.warning("eventPool full of unconsumed events"); + evt = new TouchEvent(); + } + return evt; + } + + /** + * Stores the TouchEvent back in the pool for later reuse. It is only reused + * if the TouchEvent has been consumed. + * + * @param event TouchEvent to store for later use if consumed. + */ + public void storeEvent(TouchEvent event) { + if (eventPool.size() < maxEvents) { + eventPool.push(event); + } else { + logger.warning("eventPool full"); + } + } + +} diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java index d96962244..90d786244 100644 --- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java +++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java @@ -37,6 +37,7 @@ import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; import com.jme3.renderer.ios.IGLESShaderRenderer; import com.jme3.system.*; +import com.jme3.input.ios.IosInputHandler; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -56,6 +57,7 @@ public class IGLESContext implements JmeContext { protected IGLESShaderRenderer renderer; protected Timer timer; protected SystemListener listener; + protected IosInputHandler input; protected int minFrameDuration = 0; // No FPS cap public IGLESContext() { @@ -71,12 +73,9 @@ public class IGLESContext implements JmeContext { public void setSettings(AppSettings settings) { logger.log(Level.FINE, "IGLESContext setSettings"); this.settings.copyFrom(settings); - /* - if (androidInput != null) { - androidInput.loadSettings(settings); + if (input != null) { + input.loadSettings(settings); } - */ - } @Override @@ -119,8 +118,7 @@ public class IGLESContext implements JmeContext { @Override public TouchInput getTouchInput() { - //return androidInput; - return null;// new DummyTouchInput(); + return input; } @Override @@ -153,6 +151,7 @@ public class IGLESContext implements JmeContext { public void create(boolean waitFor) { logger.log(Level.FINE, "IGLESContext create"); renderer = new IGLESShaderRenderer(); + input = new IosInputHandler(); timer = new NanoTimer(); //synchronized (createdLock){ diff --git a/jme3-ios/src/main/java/com/jme3/util/RingBuffer.java b/jme3-ios/src/main/java/com/jme3/util/RingBuffer.java new file mode 100644 index 000000000..1d3c22d7e --- /dev/null +++ b/jme3-ios/src/main/java/com/jme3/util/RingBuffer.java @@ -0,0 +1,76 @@ +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 implements Iterable { + + private T[] 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 = (T[]) new Object[capacity]; + } + + public boolean isEmpty() { + return count == 0; + } + + public int size() { + return count; + } + + public void push(T item) { + if (count == buffer.length) { + throw new RuntimeException("Ring buffer overflow"); + } + buffer[indexIn] = item; + indexIn = (indexIn + 1) % buffer.length; // wrap-around + count++; + } + + public T pop() { + if (isEmpty()) { + throw new RuntimeException("Ring buffer underflow"); + } + T item = buffer[indexOut]; + buffer[indexOut] = null; // to help with garbage collection + count--; + indexOut = (indexOut + 1) % buffer.length; // wrap-around + return item; + } + + public Iterator iterator() { + return new RingBufferIterator(); + } + + // an iterator, doesn't implement remove() since it's optional + private class RingBufferIterator implements Iterator { + + private int i = 0; + + public boolean hasNext() { + return i < count; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public T next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return buffer[i++]; + } + } +} From 75bc62764a65e5e76583990f07cb8e24914eab4e Mon Sep 17 00:00:00 2001 From: Erlend Sogge Heggen Date: Sat, 5 Apr 2014 14:09:06 +0200 Subject: [PATCH 6/6] Update CONTRIBUTING.md many updates. basic tips about github use, bug reporting and code style. --- CONTRIBUTING.md | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d560c17a5..80ead170a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,32 +1,57 @@ # How to contribute to jMonkeyEngine First and foremost, you have to familiarize yourself with Git & GitHub. Dig through -[help.github.com](https://help.github.com/) and [try.github.io](http://try.github.io/) if these are new topics for you. +[help.github.com](https://help.github.com/) and [try.github.io](http://try.github.io/) if these are new topics for you. If you'd like to contribute with something other than code, just tell us about it and we'll figure something out. -If you'd like to contribute with something other than code, read this (WIP). +## Communication -## Getting Started +Communication always comes first. **All** code changes and other contributions should start with the [forum](http://hub.jmonkeyengine.org/forum/). Make a thread to explain your change and show us the important bits of your code. If the code is too long to be posted within the forum’s code tags, please paste your code in a Gist or pastebin and link to the submission in your thread. You are required to register on our website in order to create threads. -Communication always comes first. All code changes should start with the [forum](http://hub.jmonkeyengine.org/forum/). Make a thread to explain your change and show us your code. If the code is too long to be posted within the forum’s code tags, please paste your code in a Gist or pastebin and link to the submission in your thread. You are required to register on our website in order to create threads. +### New Contributors When you're ready to submit your code, just make a [pull request](https://help.github.com/articles/using-pull-requests). -## Core Contributors - -Developers in the Contributors team can push directly to Main instead of submitting pull requests. However: -- Do not commit your code until you have received proper feedback. In the case of jME3, explicit permission from a core developer is mandatory. -- In your commit log message, please refer back to the originating forum thread (example) for a ‘full circle’ reference. +- Do not commit your code until you have received proper feedback. +- In your commit log message, please refer back to the originating forum thread (example) for a ‘full circle’ reference. Also please [reference related issues](https://help.github.com/articles/closing-issues-via-commit-messages) by typing the issue hashtag. - When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing. - If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks! +**Note to Eclipse users:** The Eclipse [git client does not support https](http://hub.jmonkeyengine.org/forum/topic/problem-cloning-the-new-git-repository/#post-265594). The current workaround is to use the command line to clone the repository and then add local repository in Eclipse. + +#### Core Contributors + +Developers in the Contributors team can push directly to Main instead of submitting pull requests, however for new features it is often a good idea to do a pull request as a means to get a last code review. + +## Building the engine + +NEEDS ATTENTION: Gradle and whatnot. + +## Best Practices + ### Git essentials rebase... -### Code style +### Testing -### Reporting bugs +general testing tips? -### Testing +### Code Quality + +We generally abide by the standard Java Code Conventions. Besides that, just make an effort to write elegant code: + + 1. Handles errors gracefully + 2. Only reinvents the wheel when there is a measurable benefit in doing so. + 3. Has consistent naming conventions. + 4. Has comments around ugly code explaining why it is ugly. + 5. Compiles (or runs if interpreted) without warnings. + +## Reporting bugs + + 1. Start by searching the forum and issue tracker for duplicates. + 2. Create a new issue, explaining the problem in proper detail (templates pending). ## Documentation + +- Edit the wiki +- Edit JavaDocs