Skip to content

Commit 1b4aa0c

Browse files
committed
fixes
1 parent 0d5efb5 commit 1b4aa0c

6 files changed

Lines changed: 166 additions & 61 deletions

File tree

jme3-android/src/main/java/com/jme3/input/android/AndroidJoyInput.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public class AndroidJoyInput implements JoyInput {
9797
private boolean useAndroidSensorJoystick = false;
9898
private boolean physicalJoystickAvailable = false;
9999
private boolean keyboardSuppressedAutoJoystick = false;
100-
private VirtualJoystick virtualJoystick;
100+
private volatile VirtualJoystick virtualJoystick;
101101
private GLSurfaceView view;
102102

103103
public AndroidJoyInput(AndroidInputHandler inputHandler) {
@@ -222,7 +222,8 @@ public Joystick[] loadJoysticks(InputManager inputManager) {
222222
}
223223

224224
public boolean onTouch(MotionEvent event) {
225-
if (virtualJoystick == null || inputHandler.getView() == null) {
225+
VirtualJoystick joystick = virtualJoystick;
226+
if (joystick == null || inputHandler.getView() == null) {
226227
return false;
227228
}
228229

@@ -235,20 +236,20 @@ public boolean onTouch(MotionEvent event) {
235236
switch (action) {
236237
case MotionEvent.ACTION_POINTER_DOWN:
237238
case MotionEvent.ACTION_DOWN:
238-
consumed = virtualJoystick.onPointerDown(event.getPointerId(pointerIndex),
239+
consumed = joystick.onPointerDown(event.getPointerId(pointerIndex),
239240
toJmeX(event.getX(pointerIndex)), toJmeY(event.getY(pointerIndex)), time);
240241
break;
241242
case MotionEvent.ACTION_POINTER_UP:
242243
case MotionEvent.ACTION_UP:
243-
consumed = virtualJoystick.onPointerUp(event.getPointerId(pointerIndex),
244+
consumed = joystick.onPointerUp(event.getPointerId(pointerIndex),
244245
toJmeX(event.getX(pointerIndex)), toJmeY(event.getY(pointerIndex)), time);
245246
break;
246247
case MotionEvent.ACTION_CANCEL:
247-
consumed = virtualJoystick.onPointerCancel(time);
248+
consumed = joystick.onPointerCancel(time);
248249
break;
249250
case MotionEvent.ACTION_MOVE:
250251
for (int i = 0; i < event.getPointerCount(); i++) {
251-
consumed = virtualJoystick.onPointerMove(event.getPointerId(i),
252+
consumed = joystick.onPointerMove(event.getPointerId(i),
252253
toJmeX(event.getX(i)), toJmeY(event.getY(i)), time) || consumed;
253254
}
254255
break;

jme3-core/src/main/java/com/jme3/input/virtual/VirtualJoystick.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ public class VirtualJoystick extends AbstractJoystick {
7474
private final Map<String, JoystickAxis> axesByLogicalId = new HashMap<>();
7575
private final Map<String, JoystickButton> buttonsByLogicalId = new HashMap<>();
7676
private final Map<Integer, Capture> captures = new HashMap<>();
77-
private final ArrayDeque<InputEvent> events = new ArrayDeque<>();
78-
private final ArrayDeque<InputEvent> auxiliaryEvents = new ArrayDeque<>();
77+
private ArrayDeque<InputEvent> events = new ArrayDeque<>();
78+
private ArrayDeque<InputEvent> readyEvents = new ArrayDeque<>();
7979
private final float[] axisValues = new float[8];
8080
private final boolean[] buttonValues = new boolean[16];
8181
private final Object inputLock = new Object();
82+
private final Element.BoundsSnapshot inputBounds = new Element.BoundsSnapshot();
8283

8384
private JoystickAxis xAxis;
8485
private JoystickAxis yAxis;
@@ -189,8 +190,9 @@ public void reset() {
189190
*/
190191
public boolean onPointerDown(int pointerId, float x, float y, long time) {
191192
synchronized (inputLock) {
192-
if (!enabled || captures.containsKey(pointerId)) {
193-
return captures.containsKey(pointerId);
193+
Capture existingCapture = captures.get(pointerId);
194+
if (!enabled || existingCapture != null) {
195+
return existingCapture != null;
194196
}
195197

196198
Element toggleElement = layout.getToggleElement();
@@ -305,16 +307,14 @@ public void dispatchEvents(RawInputListener listener) {
305307
hasEvents = false;
306308
return;
307309
}
308-
auxiliaryEvents.clear();
309-
InputEvent event;
310-
while ((event = events.poll()) != null) {
311-
auxiliaryEvents.add(event);
312-
}
310+
ArrayDeque<InputEvent> pendingEvents = events;
311+
events = readyEvents;
312+
readyEvents = pendingEvents;
313313
hasEvents = false;
314314
}
315315

316316
InputEvent event;
317-
while ((event = auxiliaryEvents.poll()) != null) {
317+
while ((event = readyEvents.poll()) != null) {
318318
if (event instanceof JoyAxisEvent) {
319319
listener.onJoyAxisEvent((JoyAxisEvent) event);
320320
} else if (event instanceof JoyButtonEvent) {
@@ -465,12 +465,13 @@ private void addButton(InputManager inputManager, int id, String name, String lo
465465
}
466466

467467
private void updateAxisCapture(Element element, float x, float y, long time) {
468-
float radius = element.pixelSize * 0.5f;
468+
element.copyBoundsTo(inputBounds);
469+
float radius = inputBounds.size * 0.5f;
469470
if (radius <= 0f) {
470471
return;
471472
}
472-
float dx = x - element.pixelX;
473-
float dy = y - element.pixelY;
473+
float dx = x - inputBounds.x;
474+
float dy = y - inputBounds.y;
474475
float length = FastMath.sqrt(dx * dx + dy * dy);
475476
if (length > radius && length > 0f) {
476477
dx *= radius / length;

jme3-core/src/main/java/com/jme3/input/virtual/VirtualJoystickLayout.java

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public synchronized void setButtonPosition(String logicalId, float x, float y) {
183183
markUpdateNeeded();
184184
}
185185

186-
public Vector2f getButtonPosition(String logicalId) {
186+
public synchronized Vector2f getButtonPosition(String logicalId) {
187187
Element element = element(buttons, logicalId);
188188
return new Vector2f(element.positionX, element.positionY);
189189
}
@@ -194,7 +194,7 @@ public synchronized void setButtonVisible(String logicalId, boolean visible) {
194194
markUpdateNeeded();
195195
}
196196

197-
public boolean isButtonVisible(String logicalId) {
197+
public synchronized boolean isButtonVisible(String logicalId) {
198198
return element(buttons, logicalId).visible;
199199
}
200200

@@ -203,7 +203,7 @@ public synchronized void setAxisPosition(String logicalId, float x, float y) {
203203
markUpdateNeeded();
204204
}
205205

206-
public Vector2f getAxisPosition(String logicalId) {
206+
public synchronized Vector2f getAxisPosition(String logicalId) {
207207
Element element = axisElement(logicalId);
208208
return new Vector2f(element.positionX, element.positionY);
209209
}
@@ -214,7 +214,7 @@ public synchronized void setAxisVisible(String logicalId, boolean visible) {
214214
markUpdateNeeded();
215215
}
216216

217-
public boolean isAxisVisible(String logicalId) {
217+
public synchronized boolean isAxisVisible(String logicalId) {
218218
return axisElement(logicalId).visible;
219219
}
220220

@@ -287,11 +287,11 @@ public Element getToggleElement() {
287287
return toggleElement;
288288
}
289289

290-
public Element getButtonElement(String logicalId) {
290+
public synchronized Element getButtonElement(String logicalId) {
291291
return buttons.get(logicalId);
292292
}
293293

294-
public Element getAxisElement(String logicalId) {
294+
public synchronized Element getAxisElement(String logicalId) {
295295
return findAxisElement(logicalId);
296296
}
297297

@@ -386,11 +386,7 @@ public static class Element implements Savable {
386386
volatile float shortOffsetX;
387387
volatile float shortOffsetY;
388388
volatile boolean visible = true;
389-
transient volatile float pixelX;
390-
transient volatile float pixelY;
391-
transient volatile float pixelSize;
392-
transient volatile float pixelWidth;
393-
transient volatile float pixelHeight;
389+
private transient volatile Bounds bounds = Bounds.EMPTY;
394390
transient volatile float nubX;
395391
transient volatile float nubY;
396392
transient Node node;
@@ -465,18 +461,28 @@ public synchronized Element setIconTextureKey(TextureKey iconTextureKey) {
465461
}
466462

467463
boolean contains(float x, float y) {
468-
return Math.abs(x - pixelX) <= pixelWidth * 0.5f
469-
&& Math.abs(y - pixelY) <= pixelHeight * 0.5f;
464+
Bounds current = bounds;
465+
return Math.abs(x - current.x) <= current.width * 0.5f
466+
&& Math.abs(y - current.y) <= current.height * 0.5f;
467+
}
468+
469+
void copyBoundsTo(BoundsSnapshot target) {
470+
Bounds current = bounds;
471+
target.x = current.x;
472+
target.y = current.y;
473+
target.size = current.size;
474+
target.width = current.width;
475+
target.height = current.height;
470476
}
471477

472478
void sync(int width, int height, float scale, boolean pressed) {
473479
float shortSide = Math.min(width, height);
474480
float scaledShortSide = shortSide * scale;
475-
pixelSize = Math.max(scaledShortSide * size, 1f);
476-
pixelWidth = pixelSize * aspect;
477-
pixelHeight = pixelSize;
478-
pixelX = positionX * width + shortOffsetX * scaledShortSide;
479-
pixelY = positionY * height + shortOffsetY * scaledShortSide;
481+
float pixelSize = Math.max(scaledShortSide * size, 1f);
482+
float pixelWidth = pixelSize * aspect;
483+
float pixelHeight = pixelSize;
484+
float pixelX = positionX * width + shortOffsetX * scaledShortSide;
485+
float pixelY = positionY * height + shortOffsetY * scaledShortSide;
480486
if (pixelWidth < width) {
481487
pixelX = FastMath.clamp(pixelX, pixelWidth * 0.5f, width - pixelWidth * 0.5f);
482488
} else {
@@ -562,6 +568,11 @@ void sync(int width, int height, float scale, boolean pressed) {
562568
lastNodeY = pixelY;
563569
nodePositionSynced = true;
564570
}
571+
Bounds current = bounds;
572+
if (current.x != pixelX || current.y != pixelY || current.size != pixelSize
573+
|| current.width != pixelWidth || current.height != pixelHeight) {
574+
publishBounds(pixelX, pixelY, pixelSize, pixelWidth, pixelHeight);
575+
}
565576
}
566577

567578
synchronized void clearVisuals() {
@@ -573,6 +584,7 @@ synchronized void clearVisuals() {
573584
nub = null;
574585
icon = null;
575586
text = null;
587+
publishBounds(0f, 0f, 0f, 0f, 0f);
576588
clearSyncState();
577589
}
578590

@@ -593,6 +605,38 @@ private void clearSyncState() {
593605
nodePositionSynced = false;
594606
}
595607

608+
private void publishBounds(float x, float y, float size, float width, float height) {
609+
bounds = x == 0f && y == 0f && size == 0f && width == 0f && height == 0f
610+
? Bounds.EMPTY
611+
: new Bounds(x, y, size, width, height);
612+
}
613+
614+
private static final class Bounds {
615+
static final Bounds EMPTY = new Bounds(0f, 0f, 0f, 0f, 0f);
616+
617+
final float x;
618+
final float y;
619+
final float size;
620+
final float width;
621+
final float height;
622+
623+
Bounds(float x, float y, float size, float width, float height) {
624+
this.x = x;
625+
this.y = y;
626+
this.size = size;
627+
this.width = width;
628+
this.height = height;
629+
}
630+
}
631+
632+
static final class BoundsSnapshot {
633+
float x;
634+
float y;
635+
float size;
636+
float width;
637+
float height;
638+
}
639+
596640
@Override
597641
public synchronized void write(JmeExporter ex) throws IOException {
598642
OutputCapsule capsule = ex.getCapsule(this);

jme3-core/src/main/java/com/jme3/input/virtual/VirtualJoystickTheme.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public VirtualJoystickTheme() {
7373
resetToDefault();
7474
}
7575

76-
public final void resetToDefault() {
76+
public synchronized final void resetToDefault() {
7777
textures.clear();
7878
fontPath = DEFAULT_FONT;
7979
textures.put(TextureKey.BUTTON, "Common/VirtualJoystick/button_circle.png");
@@ -103,11 +103,11 @@ public void setFontPath(String fontPath) {
103103
markUpdateNeeded();
104104
}
105105

106-
public String getTexture(TextureKey key) {
106+
public synchronized String getTexture(TextureKey key) {
107107
return textures.get(key);
108108
}
109109

110-
public void setTexture(TextureKey key, String texturePath) {
110+
public synchronized void setTexture(TextureKey key, String texturePath) {
111111
if (key == null) {
112112
throw new IllegalArgumentException("Texture key cannot be null.");
113113
}
@@ -132,7 +132,7 @@ void clearUpdateNeeded() {
132132
}
133133

134134
@Override
135-
public void write(JmeExporter ex) throws IOException {
135+
public synchronized void write(JmeExporter ex) throws IOException {
136136
OutputCapsule capsule = ex.getCapsule(this);
137137
capsule.write(fontPath, "fontPath", DEFAULT_FONT);
138138
String[] keys = new String[textures.size()];
@@ -145,7 +145,7 @@ public void write(JmeExporter ex) throws IOException {
145145
}
146146

147147
@Override
148-
public void read(JmeImporter im) throws IOException {
148+
public synchronized void read(JmeImporter im) throws IOException {
149149
InputCapsule capsule = im.getCapsule(this);
150150
fontPath = capsule.readString("fontPath", DEFAULT_FONT);
151151
String[] keys = capsule.readStringArray("keys", null);

0 commit comments

Comments
 (0)