diff --git a/android/app/src/main/java/com/classicube/MainActivity.java b/android/app/src/main/java/com/classicube/MainActivity.java index 6dff6fe48..09316663f 100644 --- a/android/app/src/main/java/com/classicube/MainActivity.java +++ b/android/app/src/main/java/com/classicube/MainActivity.java @@ -63,8 +63,9 @@ public class MainActivity extends Activity { // Therefore pushing/pulling events must be thread-safe, which is achieved through ConcurrentLinkedQueue // Additionally, a cache is used (freeCmds) to avoid constantly allocating NativeCmdArgs instances class NativeCmdArgs { public int cmd, arg1, arg2, arg3, arg4; public String str; public Surface sur; } - Queue pending = new ConcurrentLinkedQueue(); - Queue freeCmds = new ConcurrentLinkedQueue(); + // static to persist across activity destroy/create + static Queue pending = new ConcurrentLinkedQueue(); + static Queue freeCmds = new ConcurrentLinkedQueue(); NativeCmdArgs getCmdArgs() { NativeCmdArgs args = freeCmds.poll(); @@ -136,8 +137,9 @@ public class MainActivity extends Activity { // ====================================== // --------------- EVENTS --------------- // ====================================== - static boolean gameRunning; InputMethodManager input; + // static to persist across activity destroy/create + static boolean gameRunning; void startGameAsync() { Log.i("CC_WIN", "handing off to native.."); diff --git a/src/Http_Worker.c b/src/Http_Worker.c index d5830a091..f4c3fe6f9 100644 --- a/src/Http_Worker.c +++ b/src/Http_Worker.c @@ -631,6 +631,8 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) { *-----------------------------------------------------Android backend-----------------------------------------------------* *#########################################################################################################################*/ struct HttpRequest* java_req; +static jmethodID JAVA_httpInit, JAVA_httpSetHeader, JAVA_httpPerform, JAVA_httpSetData; +static jmethodID JAVA_httpDescribeError; cc_bool Http_DescribeError(cc_result res, cc_string* dst) { char buffer[NATIVE_STR_LEN]; @@ -641,7 +643,7 @@ cc_bool Http_DescribeError(cc_result res, cc_string* dst) { JavaGetCurrentEnv(env); args[0].i = res; - obj = JavaCallObject(env, "httpDescribeError", "(I)Ljava/lang/String;", args); + obj = JavaInstanceCall_Obj(env, JAVA_httpDescribeError, args); if (!obj) return false; err = JavaGetString(env, obj, buffer); @@ -658,7 +660,7 @@ static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_st args[0].l = JavaMakeConst(env, key); args[1].l = JavaMakeString(env, value); - JavaCallVoid(env, "httpSetHeader", "(Ljava/lang/String;Ljava/lang/String;)V", args); + JavaInstanceCall_Void(env, JAVA_httpSetHeader, args); (*env)->DeleteLocalRef(env, args[0].l); (*env)->DeleteLocalRef(env, args[1].l); } @@ -680,14 +682,24 @@ static void JNICALL java_HttpAppendData(JNIEnv* env, jobject o, jbyteArray arr, Http_BufferExpanded(req, len); } -static const JNINativeMethod methods[2] = { +static const JNINativeMethod methods[] = { { "httpParseHeader", "(Ljava/lang/String;)V", java_HttpParseHeader }, { "httpAppendData", "([BI)V", java_HttpAppendData } }; +static void CacheMethodRefs(JNIEnv* env) { + JAVA_httpInit = JavaGetMethod(env, "httpInit", "(Ljava/lang/String;Ljava/lang/String;)I"); + JAVA_httpSetHeader = JavaGetMethod(env, "httpSetHeader", "(Ljava/lang/String;Ljava/lang/String;)V"); + JAVA_httpPerform = JavaGetMethod(env, "httpPerform", "()I"); + JAVA_httpSetData = JavaGetMethod(env, "httpSetData", "([B)I"); + + JAVA_httpDescribeError = JavaGetMethod(env, "httpDescribeError", "(I)Ljava/lang/String;"); +} + static void HttpBackend_Init(void) { JNIEnv* env; JavaGetCurrentEnv(env); JavaRegisterNatives(env, methods); + CacheMethodRefs(env); } static cc_result Http_InitReq(JNIEnv* env, struct HttpRequest* req, cc_string* url) { @@ -698,7 +710,7 @@ static cc_result Http_InitReq(JNIEnv* env, struct HttpRequest* req, cc_string* u args[0].l = JavaMakeString(env, url); args[1].l = JavaMakeConst(env, verbs[req->requestType]); - res = JavaCallInt(env, "httpInit", "(Ljava/lang/String;Ljava/lang/String;)I", args); + res = JavaInstanceCall_Int(env, JAVA_httpInit, args); (*env)->DeleteLocalRef(env, args[0].l); (*env)->DeleteLocalRef(env, args[1].l); return res; @@ -709,7 +721,7 @@ static cc_result Http_SetData(JNIEnv* env, struct HttpRequest* req) { jint res; args[0].l = JavaMakeBytes(env, req->data, req->size); - res = JavaCallInt(env, "httpSetData", "([B)I", args); + res = JavaInstanceCall_Int(env, JAVA_httpSetData, args); (*env)->DeleteLocalRef(env, args[0].l); return res; } @@ -729,7 +741,7 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) { req->_capacity = 0; http_curProgress = HTTP_PROGRESS_FETCHING_DATA; - res = JavaCallInt(env, "httpPerform", "()I", NULL); + res = JavaInstanceCall_Int(env, JAVA_httpPerform, NULL); http_curProgress = 100; return res; } diff --git a/src/Platform.h b/src/Platform.h index 69f6308da..10f86a34d 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -244,9 +244,11 @@ extern jclass App_Class; extern jobject App_Instance; extern JavaVM* VM_Ptr; -#define JavaGetCurrentEnv(env) (*VM_Ptr)->AttachCurrentThread(VM_Ptr, &env, NULL); -#define JavaMakeConst(env, str) (*env)->NewStringUTF(env, str); +#define JavaGetCurrentEnv(env) (*VM_Ptr)->AttachCurrentThread(VM_Ptr, &env, NULL) +#define JavaMakeConst(env, str) (*env)->NewStringUTF(env, str) + #define JavaRegisterNatives(env, methods) (*env)->RegisterNatives(env, App_Class, methods, Array_Elems(methods)); +#define JavaGetMethod(env, name, sig) (*env)->GetMethodID(env, App_Class, name, sig) /* Creates a string from the given java string. buffer must be at least NATIVE_STR_LEN long. */ /* NOTE: Don't forget to call env->ReleaseStringUTFChars. Only works with ASCII strings. */ @@ -258,8 +260,6 @@ jbyteArray JavaMakeBytes(JNIEnv* env, const void* src, cc_uint32 len); /* Calls a method in the activity class that returns nothing. */ void JavaCallVoid(JNIEnv* env, const char* name, const char* sig, jvalue* args); /* Calls a method in the activity class that returns a jint. */ -jint JavaCallInt(JNIEnv* env, const char* name, const char* sig, jvalue* args); -/* Calls a method in the activity class that returns a jint. */ jlong JavaCallLong(JNIEnv* env, const char* name, const char* sig, jvalue* args); /* Calls a method in the activity class that returns a jint. */ jfloat JavaCallFloat(JNIEnv* env, const char* name, const char* sig, jvalue* args); @@ -271,5 +271,13 @@ void JavaCall_String_Void(const char* name, const cc_string* value); void JavaCall_Void_String(const char* name, cc_string* dst); /* Calls a method in the activity class that takes a string and returns a string. */ void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* dst); + +#define JavaInstanceCall_Void(env, method, args) (*env)->CallVoidMethodA(env, App_Instance, method, args) +/* Calls an instance method in the activity class that returns a jint */ +#define JavaInstanceCall_Int(env, method, args) (*env)->CallIntMethodA(env, App_Instance, method, args) +#define JavaInstanceCall_Long(env, method, args) (*env)->CallLongMethodA(env, App_Instance, method, args) +/* Calls an instance method in the activity class that returns a jfloat */ +#define JavaInstanceCall_Float(env,method, args) (*env)->CallFloatMethodA(env, App_Instance, method, args) +#define JavaInstanceCall_Obj(env, method, args) (*env)->CallObjectMethodA(env,App_Instance, method, args) #endif #endif diff --git a/src/Platform_Posix.c b/src/Platform_Posix.c index f9f423f86..3796c6ff2 100644 --- a/src/Platform_Posix.c +++ b/src/Platform_Posix.c @@ -10,8 +10,6 @@ #include "Utils.h" #include "Errors.h" #include "PackedCol.h" - -/* POSIX can be shared between Linux/BSD/macOS */ #include #include #include @@ -40,7 +38,7 @@ const cc_result ReturnCode_SocketInProgess = EINPROGRESS; const cc_result ReturnCode_SocketWouldBlock = EWOULDBLOCK; const cc_result ReturnCode_DirectoryExists = EEXIST; -/* Platform specific include files (Try to share for UNIX-ish) */ +/* Operating system specific include files */ #if defined CC_BUILD_DARWIN #include #include @@ -1368,11 +1366,6 @@ void JavaCallVoid(JNIEnv* env, const char* name, const char* sig, jvalue* args) (*env)->CallVoidMethodA(env, App_Instance, method, args); } -jint JavaCallInt(JNIEnv* env, const char* name, const char* sig, jvalue* args) { - jmethodID method = (*env)->GetMethodID(env, App_Class, name, sig); - return (*env)->CallIntMethodA(env, App_Instance, method, args); -} - jlong JavaCallLong(JNIEnv* env, const char* name, const char* sig, jvalue* args) { jmethodID method = (*env)->GetMethodID(env, App_Class, name, sig); return (*env)->CallLongMethodA(env, App_Instance, method, args); diff --git a/src/Window_Android.c b/src/Window_Android.c index 9625e19aa..d157bea98 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -9,8 +9,14 @@ #include #include #include + static ANativeWindow* win_handle; static cc_bool winCreated; +static jmethodID JAVA_openKeyboard, JAVA_setKeyboardText, JAVA_closeKeyboard; +static jmethodID JAVA_getWindowState, JAVA_enterFullscreen, JAVA_exitFullscreen; +static jmethodID JAVA_showAlert, JAVA_setRequestedOrientation; +static jmethodID JAVA_processedSurfaceDestroyed, JAVA_processEvents; +static jmethodID JAVA_getDpiX, JAVA_getDpiY, JAVA_setupForGame; static void RefreshWindowBounds(void) { WindowInfo.Width = ANativeWindow_getWidth(win_handle); @@ -138,7 +144,7 @@ static void JNICALL java_processSurfaceDestroyed(JNIEnv* env, jobject o) { /* eglSwapBuffers might return EGL_BAD_SURFACE, EGL_BAD_ALLOC, or some other error */ /* Instead the context is lost here in a consistent manner */ if (Gfx.Created) Gfx_LoseContext("surface lost"); - JavaCallVoid(env, "processedSurfaceDestroyed", "()V", NULL); + JavaInstanceCall_Void(env, JAVA_processedSurfaceDestroyed, NULL); } static void JNICALL java_processSurfaceResized(JNIEnv* env, jobject o, jobject surface) { @@ -174,7 +180,7 @@ static void JNICALL java_onDestroy(JNIEnv* env, jobject o) { if (WindowInfo.Exists) Window_Close(); /* TODO: signal to java code we're done */ - /* JavaCallVoid(env, "processedDestroyed", "()V", NULL); */ + /* JavaInstanceCall_Void(env, JAVA_processedDestroyed", NULL); */ } static void JNICALL java_onGotFocus(JNIEnv* env, jobject o) { @@ -220,19 +226,39 @@ static const JNINativeMethod methods[] = { { "processOnLostFocus", "()V", java_onLostFocus }, { "processOnLowMemory", "()V", java_onLowMemory } }; +static void CacheMethodRefs(JNIEnv* env) { + JAVA_openKeyboard = JavaGetMethod(env, "openKeyboard", "(Ljava/lang/String;I)V"); + JAVA_setKeyboardText = JavaGetMethod(env, "setKeyboardText", "(Ljava/lang/String;)V"); + JAVA_closeKeyboard = JavaGetMethod(env, "closeKeyboard", "()V"); + + JAVA_getWindowState = JavaGetMethod(env, "getWindowState", "()I"); + JAVA_enterFullscreen = JavaGetMethod(env, "enterFullscreen", "()V"); + JAVA_exitFullscreen = JavaGetMethod(env, "exitFullscreen", "()V"); + + JAVA_getDpiX = JavaGetMethod(env, "getDpiX", "()F"); + JAVA_getDpiY = JavaGetMethod(env, "getDpiY", "()F"); + JAVA_setupForGame = JavaGetMethod(env, "setupForGame", "()V"); + + JAVA_processedSurfaceDestroyed = JavaGetMethod(env, "processedSurfaceDestroyed", "()V"); + JAVA_processEvents = JavaGetMethod(env, "processEvents", "()V"); + + JAVA_showAlert = JavaGetMethod(env, "showAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); + JAVA_setRequestedOrientation = JavaGetMethod(env, "setRequestedOrientation", "(I)V"); +} void Window_Init(void) { JNIEnv* env; /* TODO: ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); */ JavaGetCurrentEnv(env); JavaRegisterNatives(env, methods); + CacheMethodRefs(env); WindowInfo.SoftKeyboard = SOFT_KEYBOARD_RESIZE; Input_SetTouchMode(true); DisplayInfo.Depth = 32; - DisplayInfo.ScaleX = JavaCallFloat(env, "getDpiX", "()F", NULL); - DisplayInfo.ScaleY = JavaCallFloat(env, "getDpiY", "()F", NULL); + DisplayInfo.ScaleX = JavaInstanceCall_Float(env, JAVA_getDpiX, NULL); + DisplayInfo.ScaleY = JavaInstanceCall_Float(env, JAVA_getDpiY, NULL); } static void Window_RemakeSurface(void) { @@ -242,7 +268,7 @@ static void Window_RemakeSurface(void) { /* Force window to be destroyed and re-created */ /* (see comments in setupForGame for why this has to be done) */ - JavaCallVoid(env, "setupForGame", "()V", NULL); + JavaInstanceCall_Void(env, JAVA_setupForGame, NULL); Platform_LogConst("Entering wait for window exist loop.."); /* Loop until window gets created by main UI thread */ @@ -280,20 +306,20 @@ void Window_Show(void) { } /* Window already visible */ int Window_GetWindowState(void) { JNIEnv* env; JavaGetCurrentEnv(env); - return JavaCallInt(env, "getWindowState", "()I", NULL); + return JavaInstanceCall_Int(env, JAVA_getWindowState, NULL); } cc_result Window_EnterFullscreen(void) { JNIEnv* env; JavaGetCurrentEnv(env); - JavaCallVoid(env, "enterFullscreen", "()V", NULL); + JavaInstanceCall_Void(env, JAVA_enterFullscreen, NULL); return 0; } cc_result Window_ExitFullscreen(void) { JNIEnv* env; JavaGetCurrentEnv(env); - JavaCallVoid(env, "exitFullscreen", "()V", NULL); + JavaInstanceCall_Void(env, JAVA_exitFullscreen, NULL); return 0; } @@ -309,8 +335,8 @@ void Window_Close(void) { void Window_ProcessEvents(void) { JNIEnv* env; JavaGetCurrentEnv(env); - /* TODO: Cache the java env and cache the method ID!!!!! */ - JavaCallVoid(env, "processEvents", "()V", NULL); + /* TODO: Cache the java env */ + JavaInstanceCall_Void(env, JAVA_processEvents, NULL); } /* No actual mouse cursor */ @@ -330,7 +356,7 @@ static void ShowDialogCore(const char* title, const char* msg) { args[0].l = JavaMakeConst(env, title); args[1].l = JavaMakeConst(env, msg); - JavaCallVoid(env, "showAlert", "(Ljava/lang/String;Ljava/lang/String;)V", args); + JavaInstanceCall_Void(env, JAVA_showAlert, args); (*env)->DeleteLocalRef(env, args[0].l); (*env)->DeleteLocalRef(env, args[1].l); } @@ -386,7 +412,7 @@ void Window_OpenKeyboard(const struct OpenKeyboardArgs* kArgs) { args[0].l = JavaMakeString(env, kArgs->text); args[1].i = kArgs->type; - JavaCallVoid(env, "openKeyboard", "(Ljava/lang/String;I)V", args); + JavaInstanceCall_Void(env, JAVA_openKeyboard, args); (*env)->DeleteLocalRef(env, args[0].l); } @@ -396,14 +422,14 @@ void Window_SetKeyboardText(const cc_string* text) { JavaGetCurrentEnv(env); args[0].l = JavaMakeString(env, text); - JavaCallVoid(env, "setKeyboardText", "(Ljava/lang/String;)V", args); + JavaInstanceCall_Void(env, JAVA_setKeyboardText, args); (*env)->DeleteLocalRef(env, args[0].l); } void Window_CloseKeyboard(void) { JNIEnv* env; JavaGetCurrentEnv(env); - JavaCallVoid(env, "closeKeyboard", "()V", NULL); + JavaInstanceCall_Void(env, JAVA_closeKeyboard, NULL); } void Window_LockLandscapeOrientation(cc_bool lock) { @@ -414,7 +440,7 @@ void Window_LockLandscapeOrientation(cc_bool lock) { /* SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 0x00000006 */ /* SCREEN_ORIENTATION_UNSPECIFIED = 0xffffffff */ args[0].i = lock ? 0x00000006 : 0xffffffff; - JavaCallVoid(env, "setRequestedOrientation", "(I)V", args); + JavaInstanceCall_Void(env, JAVA_setRequestedOrientation, args); } void Window_EnableRawMouse(void) { DefaultEnableRawMouse(); }