You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-06 12:20:30 +00:00
Switch to input buffering on Android
Key, touch and joystick events will be passed directly from the UI thread to Godot, so they can benefit from agile input flushing. As another consequence of this new way of passing events, less Java object are created at runtime (`Runnable`), which is good since the garbage collector needs to run less. `AndroidInputHandler` is introduced to have a smaller cross-thread surface. `main_loop_request_go_back()` is removed in favor just inline calling `notification()` on the `MainLoop` at the most caller's convenience. Lastly, `get_mouse_position()` and `get_mouse_button_state()` now just call through `InputDefault` to avoid the need of sync of mouse data tracked on the UI thread.
This commit is contained in:
@@ -75,7 +75,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
|
||||
final int x = Math.round(event.getX());
|
||||
final int y = Math.round(event.getY());
|
||||
final int buttonMask = event.getButtonState();
|
||||
queueEvent(() -> GodotLib.doubleTap(buttonMask, x, y));
|
||||
GodotLib.doubleTap(buttonMask, x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
|
||||
//Log.i("GodotGesture", "onScroll");
|
||||
final int x = Math.round(distanceX);
|
||||
final int y = Math.round(distanceY);
|
||||
queueEvent(() -> GodotLib.scroll(x, y));
|
||||
GodotLib.scroll(x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,10 +68,6 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
this.inputManager.registerInputDeviceListener(this, null);
|
||||
}
|
||||
|
||||
private void queueEvent(Runnable task) {
|
||||
godotView.queueEvent(task);
|
||||
}
|
||||
|
||||
private boolean isKeyEvent_GameDevice(int source) {
|
||||
// Note that keyboards are often (SOURCE_KEYBOARD | SOURCE_DPAD)
|
||||
if (source == (InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD))
|
||||
@@ -96,13 +92,12 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
if (mJoystickIds.indexOfKey(deviceId) >= 0) {
|
||||
final int button = getGodotButton(keyCode);
|
||||
final int godotJoyId = mJoystickIds.get(deviceId);
|
||||
|
||||
queueEvent(() -> GodotLib.joybutton(godotJoyId, button, false));
|
||||
GodotLib.joybutton(godotJoyId, button, false);
|
||||
}
|
||||
} else {
|
||||
final int scanCode = event.getScanCode();
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, false));
|
||||
GodotLib.key(keyCode, scanCode, chr, false);
|
||||
};
|
||||
|
||||
return true;
|
||||
@@ -132,13 +127,12 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
if (mJoystickIds.indexOfKey(deviceId) >= 0) {
|
||||
final int button = getGodotButton(keyCode);
|
||||
final int godotJoyId = mJoystickIds.get(deviceId);
|
||||
|
||||
queueEvent(() -> GodotLib.joybutton(godotJoyId, button, true));
|
||||
GodotLib.joybutton(godotJoyId, button, true);
|
||||
}
|
||||
} else {
|
||||
final int scanCode = event.getScanCode();
|
||||
final int chr = event.getUnicodeChar(0);
|
||||
queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, true));
|
||||
GodotLib.key(keyCode, scanCode, chr, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -170,18 +164,16 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final int action = event.getActionMasked();
|
||||
final int pointer_idx = event.getPointerId(event.getActionIndex());
|
||||
|
||||
godotView.queueEvent(() -> {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
|
||||
} break;
|
||||
}
|
||||
});
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -205,7 +197,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
// save value to prevent repeats
|
||||
joystick.axesValues.put(axis, value);
|
||||
final int godotAxisIdx = i;
|
||||
queueEvent(() -> GodotLib.joyaxis(godotJoyId, godotAxisIdx, value));
|
||||
GodotLib.joyaxis(godotJoyId, godotAxisIdx, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +207,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
if (joystick.hatX != hatX || joystick.hatY != hatY) {
|
||||
joystick.hatX = hatX;
|
||||
joystick.hatY = hatY;
|
||||
queueEvent(() -> GodotLib.joyhat(godotJoyId, hatX, hatY));
|
||||
GodotLib.joyhat(godotJoyId, hatX, hatY);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -224,7 +216,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(() -> GodotLib.hover(type, x, y));
|
||||
GodotLib.hover(type, x, y);
|
||||
return true;
|
||||
} else if ((event.isFromSource(InputDevice.SOURCE_MOUSE))) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
@@ -315,7 +307,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
}
|
||||
mJoysticksDevices.put(deviceId, joystick);
|
||||
|
||||
queueEvent(() -> GodotLib.joyconnectionchanged(id, true, joystick.name));
|
||||
GodotLib.joyconnectionchanged(id, true, joystick.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -327,8 +319,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final int godotJoyId = mJoystickIds.get(deviceId);
|
||||
mJoystickIds.delete(deviceId);
|
||||
mJoysticksDevices.delete(deviceId);
|
||||
|
||||
queueEvent(() -> GodotLib.joyconnectionchanged(godotJoyId, false, ""));
|
||||
GodotLib.joyconnectionchanged(godotJoyId, false, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -417,7 +408,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final int type = event.getAction();
|
||||
queueEvent(() -> GodotLib.hover(type, x, y));
|
||||
GodotLib.hover(type, x, y);
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_BUTTON_PRESS:
|
||||
@@ -427,7 +418,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final float y = event.getY();
|
||||
final int buttonsMask = event.getButtonState();
|
||||
final int action = event.getAction();
|
||||
queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask));
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask);
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_SCROLL: {
|
||||
@@ -437,7 +428,7 @@ public class GodotInputHandler implements InputDeviceListener {
|
||||
final int action = event.getAction();
|
||||
final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
|
||||
queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor));
|
||||
GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -94,17 +94,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
|
||||
//Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
|
||||
|
||||
mView.queueEvent(() -> {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
|
||||
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
|
||||
|
||||
if (mHasSelection) {
|
||||
mHasSelection = false;
|
||||
break;
|
||||
}
|
||||
if (mHasSelection) {
|
||||
mHasSelection = false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,17 +113,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
for (int i = start; i < start + count; ++i) {
|
||||
newChars[i - start] = pCharSequence.charAt(i);
|
||||
}
|
||||
mView.queueEvent(() -> {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int key = newChars[i];
|
||||
if ((key == '\n') && !mEdit.isMultiline()) {
|
||||
// Return keys are handled through action events
|
||||
continue;
|
||||
}
|
||||
GodotLib.key(0, 0, key, true);
|
||||
GodotLib.key(0, 0, key, false);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int key = newChars[i];
|
||||
if ((key == '\n') && !mEdit.isMultiline()) {
|
||||
// Return keys are handled through action events
|
||||
continue;
|
||||
}
|
||||
});
|
||||
GodotLib.key(0, 0, key, true);
|
||||
GodotLib.key(0, 0, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,13 +129,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
|
||||
if (this.mEdit == pTextView && this.isFullScreenEdit()) {
|
||||
final String characters = pKeyEvent.getCharacters();
|
||||
|
||||
mView.queueEvent(() -> {
|
||||
for (int i = 0; i < characters.length(); i++) {
|
||||
final int ch = characters.codePointAt(i);
|
||||
GodotLib.key(0, 0, ch, true);
|
||||
GodotLib.key(0, 0, ch, false);
|
||||
}
|
||||
});
|
||||
for (int i = 0; i < characters.length(); i++) {
|
||||
final int ch = characters.codePointAt(i);
|
||||
GodotLib.key(0, 0, ch, true);
|
||||
GodotLib.key(0, 0, ch, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (pActionID == EditorInfo.IME_ACTION_DONE) {
|
||||
|
||||
Reference in New Issue
Block a user