diff options
author | Ruslan Mustakov <r.mustakov@gmail.com> | 2017-08-18 21:17:35 +0700 |
---|---|---|
committer | Ruslan Mustakov <r.mustakov@gmail.com> | 2017-08-30 18:14:19 +0700 |
commit | 5ccdeccb6ed6b8480a86b0db36f192526cba1274 (patch) | |
tree | eafb890997ee985210b66272957aa22ad00df125 /platform/android/java/src/org/godotengine | |
parent | 8b9026c05e9982a7bc0c7f52776ad74276b90252 (diff) |
Make GDNative work on Android
The changes include work done to ensure that GDNative apps and Nim
integration specifically can run on Android. The changes have been
tested on our WIP game, which uses godot-nim and depends on several
third-party .so libs, and Platformer demo to ensure nothing got broken.
- .so libraries are exported to lib/ folder in .apk, instead of assets/,
because that's where Android expects them to be and it resolves the
library name into "lib/<ABI>/<name>", where <ABI> is the ABI matching
the current device. So we establish the convention that Android .so
files in the project must be located in the folder corresponding to
the ABI they were compiled for.
- Godot callbacks (event handlers) are now called from the same thread
from which Main::iteration is called. It is also what Godot now
considers to be the main thread, because Main::setup is also called
from there. This makes threading on Android more consistent with
other platforms, making the code that depends on Thread::get_main_id
more portable (GDNative has such code).
- Sizes of GDNative API types have been fixed to work on 32-bit
platforms.
Diffstat (limited to 'platform/android/java/src/org/godotengine')
5 files changed, 257 insertions, 142 deletions
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index eab0387f32..53a90e4cfe 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -92,7 +92,7 @@ import android.os.SystemClock; public class Godot extends Activity implements SensorEventListener, IDownloaderClient -{ +{ static final int MAX_SINGLETONS = 64; private IStub mDownloaderClientStub; @@ -139,9 +139,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC com.godot.game.R.string.text_button_pause; mPauseButton.setText(stringResourceID); } - + static public class SingletonBase { - + protected void registerClass(String p_name, String[] p_methods) { GodotLib.singleton(p_name,this); @@ -210,6 +210,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC */ private String[] command_line; + private boolean use_apk_expansion; public GodotView mView; private boolean godot_initialized=false; @@ -264,27 +265,40 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC layout = new FrameLayout(this); layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); setContentView(layout); - + // GodotEditText layout - GodotEditText edittext = new GodotEditText(this); + GodotEditText edittext = new GodotEditText(this); edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); // ...add to FrameLayout layout.addView(edittext); - + mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this); layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); - setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True")); - - edittext.setView(mView); - io.setEdit(edittext); - + edittext.setView(mView); + io.setEdit(edittext); + // Ad layout adLayout = new RelativeLayout(this); adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); layout.addView(adLayout); - + + final String[] current_command_line = command_line; + final GodotView view = mView; + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.setup(current_command_line); + runOnUiThread(new Runnable() { + @Override + public void run() { + view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on"))); + } + }); + } + }); + } - + public void setKeepScreenOn(final boolean p_enabled) { keep_screen_on = p_enabled; if (mView != null){ @@ -315,13 +329,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } }); } - + private static Godot _self; - + public static Godot getInstance(){ return Godot._self; } - + private String[] getCommandLine() { InputStream is; @@ -402,7 +416,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC Log.d("GODOT"," " + command_line[w]); } }*/ - GodotLib.initialize(this,io.needsReloadHooks(),command_line,getAssets()); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); @@ -411,9 +424,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); + GodotLib.initialize(this, io.needsReloadHooks(), getAssets(), use_apk_expansion); + result_callback = null; mPaymentsManager = PaymentsManager.createManager(this).initService(); + godot_initialized=true; } @@ -426,7 +442,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC - @Override + @Override protected void onCreate(Bundle icicle) { Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n"); @@ -437,12 +453,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC //window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); - //check for apk expansion API if (true) { boolean md5mismatch = false; command_line = getCommandLine(); - boolean use_apk_expansion=false; String main_pack_md5=null; String main_pack_key=null; @@ -528,23 +542,23 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC if (!pack_valid) { Log.d("GODOT", "Pack Invalid, try re-downloading."); - + Intent notifierIntent = new Intent(this, this.getClass()); notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); - + int startResult; try { Log.d("GODOT", "INITIALIZING DOWNLOAD"); startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( - getApplicationContext(), - pendingIntent, + getApplicationContext(), + pendingIntent, GodotDownloaderService.class); Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult); - + if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { Log.d("GODOT", "DOWNLOAD REQUIRED"); // This is where you do set up to display the download @@ -563,7 +577,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mCellMessage = findViewById(com.godot.game.R.id.approveCellular); mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton); mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton); - + return; } else{ Log.d("GODOT", "NO DOWNLOAD REQUIRED"); @@ -582,7 +596,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC initializeGodot(); - + //instanceSingleton( new GodotFacebook(this) ); @@ -590,14 +604,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override protected void onDestroy(){ - + if(mPaymentsManager != null ) mPaymentsManager.destroy(); for(int i=0;i<singleton_count;i++) { singletons[i].onMainDestroy(); } super.onDestroy(); } - + @Override protected void onPause() { super.onPause(); if (!godot_initialized){ @@ -607,8 +621,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return; } mView.onPause(); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.focusout(); + } + }); mSensorManager.unregisterListener(this); - GodotLib.focusout(); for(int i=0;i<singleton_count;i++) { singletons[i].onMainPause(); @@ -625,10 +644,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } mView.onResume(); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.focusin(); + } + }); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); - GodotLib.focusin(); + if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+ Window window = getWindow(); window.getDecorView().setSystemUiVisibility( @@ -644,8 +669,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC singletons[i].onMainResume(); } - - + + } @@ -670,32 +695,39 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onSensorChanged(SensorEvent event) { Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int displayRotation = display.getRotation(); - + float[] adjustedValues = new float[3]; final int axisSwap[][] = { - { 1, -1, 0, 1 }, // ROTATION_0 - {-1, -1, 1, 0 }, // ROTATION_90 - {-1, 1, 0, 1 }, // ROTATION_180 - { 1, 1, 1, 0 } }; // ROTATION_270 - - final int[] as = axisSwap[displayRotation]; - adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; - adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; + { 1, -1, 0, 1 }, // ROTATION_0 + {-1, -1, 1, 0 }, // ROTATION_90 + {-1, 1, 0, 1 }, // ROTATION_180 + { 1, 1, 1, 0 } }; // ROTATION_270 + + final int[] as = axisSwap[displayRotation]; + adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; + adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; adjustedValues[2] = event.values[2]; - - float x = adjustedValues[0]; - float y = adjustedValues[1]; - float z = adjustedValues[2]; - - int typeOfSensor = event.sensor.getType(); - if (typeOfSensor == event.sensor.TYPE_ACCELEROMETER) { - GodotLib.accelerometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) { - GodotLib.magnetometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_GYROSCOPE) { - GodotLib.gyroscope(x,y,z); + + final float x = adjustedValues[0]; + final float y = adjustedValues[1]; + final float z = adjustedValues[2]; + + final int typeOfSensor = event.sensor.getType(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { + GodotLib.accelerometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { + GodotLib.magnetometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { + GodotLib.gyroscope(x,y,z); + } + } + }); } } @@ -722,7 +754,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onBackPressed() { System.out.printf("** BACK REQUEST!\n"); - //GodotLib.back(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + } } public void forceQuit() { @@ -733,7 +772,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private boolean obbIsCorrupted(String f, String main_pack_md5){ - + try { InputStream fis = new FileInputStream(f); @@ -780,58 +819,64 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } //@Override public boolean dispatchTouchEvent (MotionEvent event) { - public boolean gotTouchEvent(MotionEvent event) { + public boolean gotTouchEvent(final MotionEvent event) { super.onTouchEvent(event); - int evcount=event.getPointerCount(); + final int evcount=event.getPointerCount(); if (evcount==0) return true; - int[] arr = new int[event.getPointerCount()*3]; + if (mView != null) { + final int[] arr = new int[event.getPointerCount()*3]; - for(int i=0;i<event.getPointerCount();i++) { + for(int i=0;i<event.getPointerCount();i++) { - arr[i*3+0]=(int)event.getPointerId(i); - arr[i*3+1]=(int)event.getX(i); - arr[i*3+2]=(int)event.getY(i); - } + arr[i*3+0]=(int)event.getPointerId(i); + arr[i*3+1]=(int)event.getX(i); + arr[i*3+2]=(int)event.getY(i); + } - //System.out.printf("gaction: %d\n",event.getAction()); - switch(event.getAction()&MotionEvent.ACTION_MASK) { - - case MotionEvent.ACTION_DOWN: { - GodotLib.touch(0,0,evcount,arr); - //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY()); - } break; - case MotionEvent.ACTION_MOVE: { - GodotLib.touch(1,0,evcount,arr); - /* - for(int i=0;i<event.getPointerCount();i++) { - System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i)); - } - */ - } break; - case MotionEvent.ACTION_POINTER_UP: { - final int indexPointUp = event.getActionIndex(); - final int pointer_idx = event.getPointerId(indexPointUp); - GodotLib.touch(4,pointer_idx,evcount,arr); - //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); - } break; - case MotionEvent.ACTION_POINTER_DOWN: { - int pointer_idx = event.getActionIndex(); - GodotLib.touch(3,pointer_idx,evcount,arr); - //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); - } break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: { - GodotLib.touch(2,0,evcount,arr); - /* - for(int i=0;i<event.getPointerCount();i++) { - System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i)); + //System.out.printf("gaction: %d\n",event.getAction()); + final int action = event.getAction() & MotionEvent.ACTION_MASK; + mView.queueEvent(new Runnable() { + @Override + public void run() { + switch(action) { + case MotionEvent.ACTION_DOWN: { + GodotLib.touch(0,0,evcount,arr); + //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY()); + } break; + case MotionEvent.ACTION_MOVE: { + GodotLib.touch(1,0,evcount,arr); + /* + for(int i=0;i<event.getPointerCount();i++) { + System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i)); + } + */ + } break; + case MotionEvent.ACTION_POINTER_UP: { + final int indexPointUp = event.getActionIndex(); + final int pointer_idx = event.getPointerId(indexPointUp); + GodotLib.touch(4,pointer_idx,evcount,arr); + //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); + } break; + case MotionEvent.ACTION_POINTER_DOWN: { + int pointer_idx = event.getActionIndex(); + GodotLib.touch(3,pointer_idx,evcount,arr); + //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); + } break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: { + GodotLib.touch(2,0,evcount,arr); + /* + for(int i=0;i<event.getPointerCount();i++) { + System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i)); + } + */ + } break; + } } - */ - } break; - + }); } return true; } @@ -864,7 +909,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private void queueEvent(Runnable runnable) { // TODO Auto-generated method stub - + } public PaymentsManager getPaymentsManager() { @@ -988,7 +1033,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mProgressFraction.setText(Helpers.getDownloadProgressString (progress.mOverallProgress, progress.mOverallTotal)); - + } - + } diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index b487c17f53..47a690140f 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -37,7 +37,7 @@ public class GodotLib { public static GodotIO io; static { - System.loadLibrary("godot_android"); + System.loadLibrary("godot_android"); } /** @@ -45,7 +45,8 @@ public class GodotLib { * @param height the current view height */ - public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline,Object p_asset_manager); + public static native void initialize(Godot p_instance,boolean need_reload_hook,Object p_asset_manager, boolean use_apk_expansion); + public static native void setup(String[] p_cmdline); public static native void resize(int width, int height,boolean reload); public static native void newcontext(boolean p_32_bits); public static native void back(); diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index a16c67523e..8fe79fdfc7 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -89,7 +89,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase { } public void callbackSuccess(String ticket, String signature, String sku) { - GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); + GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); } public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) { diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 19fcf8e687..3c2ad7cc59 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -208,8 +208,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { @Override public void onInputDeviceAdded(int deviceId) { joystick joy = new joystick(); joy.device_id = deviceId; - int id = joy_devices.size(); + final int id = joy_devices.size(); InputDevice device = mInputManager.getInputDevice(deviceId); + final String name = device.getName(); joy.name = device.getName(); joy.axes = new ArrayList<InputDevice.MotionRange>(); joy.hats = new ArrayList<InputDevice.MotionRange>(); @@ -224,19 +225,29 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { } } joy_devices.add(joy); - GodotLib.joyconnectionchanged(id, true, joy.name); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, true, name); + } + }); } @Override public void onInputDeviceRemoved(int deviceId) { - int id = find_joy_device(deviceId); + final int id = find_joy_device(deviceId); joy_devices.remove(id); - GodotLib.joyconnectionchanged(id, false, ""); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, false, ""); + } + }); } @Override public void onInputDeviceChanged(int deviceId) { } - @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + @Override public boolean onKeyUp(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; @@ -249,22 +260,38 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { int source = event.getSource(); if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); - GodotLib.joybutton(device, button, false); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, false); + } + }); return true; } else { - - GodotLib.key(keyCode, event.getUnicodeChar(0), false); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, false); + } + }); }; return super.onKeyUp(keyCode, event); }; - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + @Override public boolean onKeyDown(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - GodotLib.back(); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + // press 'back' button should not terminate program //normal handle 'back' event in game logic return true; @@ -281,16 +308,26 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if (event.getRepeatCount() > 0) // ignore key echo return true; - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); - - GodotLib.joybutton(device, button, true); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, true); + } + }); return true; } else { - GodotLib.key(keyCode, event.getUnicodeChar(0), true); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, true); + } + }); }; return super.onKeyDown(keyCode, event); } @@ -299,21 +336,32 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - int device_id = find_joy_device(event.getDeviceId()); + final int device_id = find_joy_device(event.getDeviceId()); joystick joy = joy_devices.get(device_id); for (int i = 0; i < joy.axes.size(); i++) { InputDevice.MotionRange range = joy.axes.get(i); - float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; + final float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; //Log.e(TAG, String.format("axis event: %d, value %f", i, value)); - GodotLib.joyaxis(device_id, i, value); + final int idx = i; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyaxis(device_id, idx, value); + } + }); } for (int i = 0; i < joy.hats.size(); i+=2) { - int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); - int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); + final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); + final int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY)); - GodotLib.joyhat(device_id, hatX, hatY); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyhat(device_id, hatX, hatY); + } + }); } return true; }; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index c2d03e4ecc..04669a3b0c 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -89,8 +89,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); for (int i=0;i<count;i++){ - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + } + }); } } @@ -99,9 +104,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene //Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before); for (int i=start;i<start+count;i++){ - int ch = pCharSequence.charAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + final int ch = pCharSequence.charAt(i); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(0, ch, true); + GodotLib.key(0, ch, false); + } + }); } } @@ -111,8 +121,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene if (this.mEdit == pTextView && this.isFullScreenEdit()) { // user press the action button, delete all old text and insert new text for (int i = this.mOriginText.length(); i > 0; i--) { - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + } + }); + /* if (BuildConfig.DEBUG) { Log.d(TAG, "deleteBackward"); @@ -131,9 +147,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } for(int i = 0; i < text.length(); i++) { - int ch = text.codePointAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + final int ch = text.codePointAt(i); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(0, ch, true); + GodotLib.key(0, ch, false); + } + }); } /* if (BuildConfig.DEBUG) { @@ -141,7 +162,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } */ } - + if (pActionID == EditorInfo.IME_ACTION_DONE) { this.mView.requestFocus(); } |