diff options
Diffstat (limited to 'platform/android/java_godot_lib_jni.cpp')
-rw-r--r-- | platform/android/java_godot_lib_jni.cpp | 99 |
1 files changed, 59 insertions, 40 deletions
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index ce7a49e53c..d971727269 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -34,6 +34,7 @@ #include "java_godot_wrapper.h" #include "android/asset_manager_jni.h" +#include "android_input_handler.h" #include "api/java_class_wrapper.h" #include "api/jni_singleton.h" #include "core/config/engine.h" @@ -56,11 +57,12 @@ static JavaClassWrapper *java_class_wrapper = nullptr; static OS_Android *os_android = nullptr; +static AndroidInputHandler *input_handler = nullptr; static GodotJavaWrapper *godot_java = nullptr; static GodotIOJavaWrapper *godot_io_java = nullptr; static bool initialized = false; -static int step = 0; +static SafeNumeric<int> step; // Shared between UI and render threads static Size2 new_size; static Vector3 accelerometer; @@ -111,6 +113,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env if (godot_java) { delete godot_java; } + if (input_handler) { + delete input_handler; + } if (os_android) { delete os_android; } @@ -165,7 +170,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j os_android->set_display_size(Size2i(p_width, p_height)); // No need to reset the surface during startup - if (step > 0) { + if (step.get() > 0) { if (p_surface) { ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface); os_android->set_native_window(native_window); @@ -179,7 +184,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) { if (os_android) { - if (step == 0) { + if (step.get() == 0) { // During startup os_android->set_context_is_16_bits(!p_32_bits); if (p_surface) { @@ -188,33 +193,36 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } } else { // Rendering context recreated because it was lost; restart app to let it reload everything + step.set(-1); // Ensure no further steps are attempted and no further events are sent os_android->main_loop_end(); godot_java->restart(env); - step = -1; // Ensure no further steps are attempted } } } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() == 0) return; - os_android->main_loop_request_go_back(); + if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { + dsa->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST); + } } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz) { - if (step == -1) + if (step.get() == -1) return; - if (step == 0) { + if (step.get() == 0) { // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); - ++step; + input_handler = new AndroidInputHandler(); + step.increment(); return; } - if (step == 1) { + if (step.get() == 1) { if (!Main::start()) { return; // should exit instead and print the error } @@ -222,7 +230,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl godot_java->on_godot_setup_completed(env); os_android->main_loop_begin(); godot_java->on_godot_main_loop_started(env); - ++step; + step.increment(); } DisplayServerAndroid::get_singleton()->process_accelerometer(accelerometer); @@ -236,91 +244,100 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl } void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) { - if (step == 0) + if (step.get() <= 0) return; - Vector<DisplayServerAndroid::TouchPos> points; + Vector<AndroidInputHandler::TouchPos> points; for (int i = 0; i < pointer_count; i++) { jfloat p[3]; env->GetFloatArrayRegion(positions, i * 3, 3, p); - DisplayServerAndroid::TouchPos tp; + AndroidInputHandler::TouchPos tp; tp.pos = Point2(p[1], p[2]); tp.id = (int)p[0]; points.push_back(tp); } if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE || (input_device & AINPUT_SOURCE_MOUSE_RELATIVE) == AINPUT_SOURCE_MOUSE_RELATIVE) { - DisplayServerAndroid::get_singleton()->process_mouse_event(input_device, ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor); + input_handler->process_mouse_event(input_device, ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor); } else { - DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points); + input_handler->process_touch(ev, pointer, points); } } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask, vertical_factor, horizontal_factor); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y)); + input_handler->process_hover(p_type, Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_double_tap(p_button_mask, Point2(p_x, p_y)); + input_handler->process_double_tap(p_button_mask, Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_scroll(Point2(p_x, p_y)); + input_handler->process_scroll(Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_BUTTON; + jevent.type = AndroidInputHandler::JOY_EVENT_BUTTON; jevent.index = p_button; jevent.pressed = p_pressed; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_AXIS; + jevent.type = AndroidInputHandler::JOY_EVENT_AXIS; jevent.index = p_axis; jevent.value = p_value; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_HAT; + jevent.type = AndroidInputHandler::JOY_EVENT_HAT; int hat = 0; if (p_hat_x != 0) { if (p_hat_x < 0) @@ -336,9 +353,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j } jevent.hat = hat; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) { if (os_android) { String name = jstring_to_string(p_name, env); @@ -346,11 +364,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); + input_handler->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { @@ -370,14 +389,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; os_android->main_loop_focusin(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; os_android->main_loop_focusout(); @@ -456,7 +475,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResu } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; if (os_android->get_main_loop()) { @@ -465,7 +484,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNI } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; if (os_android->get_main_loop()) { |