mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 10:35:11 -04:00
Merge pull request #898 from UnknownShadow200/AndroidRecreateFix
Android: Use cached method IDs for more of java interop calls
This commit is contained in:
commit
f10596a5cd
@ -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<NativeCmdArgs> pending = new ConcurrentLinkedQueue<NativeCmdArgs>();
|
||||
Queue<NativeCmdArgs> freeCmds = new ConcurrentLinkedQueue<NativeCmdArgs>();
|
||||
// static to persist across activity destroy/create
|
||||
static Queue<NativeCmdArgs> pending = new ConcurrentLinkedQueue<NativeCmdArgs>();
|
||||
static Queue<NativeCmdArgs> freeCmds = new ConcurrentLinkedQueue<NativeCmdArgs>();
|
||||
|
||||
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..");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -10,8 +10,6 @@
|
||||
#include "Utils.h"
|
||||
#include "Errors.h"
|
||||
#include "PackedCol.h"
|
||||
|
||||
/* POSIX can be shared between Linux/BSD/macOS */
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
@ -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 <mach/mach_time.h>
|
||||
#include <mach-o/dyld.h>
|
||||
@ -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);
|
||||
|
@ -9,8 +9,14 @@
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/keycodes.h>
|
||||
|
||||
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(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user