Merge pull request #92143 from m4gr3d/cleanup_android_plugin_on_exit
Add logic to unregister the Godot plugins on engine termination
This commit is contained in:
commit
eef7e29527
|
@ -244,6 +244,7 @@ public:
|
||||||
|
|
||||||
~JNISingleton() {
|
~JNISingleton() {
|
||||||
#ifdef ANDROID_ENABLED
|
#ifdef ANDROID_ENABLED
|
||||||
|
method_map.clear();
|
||||||
if (instance) {
|
if (instance) {
|
||||||
JNIEnv *env = get_jni_env();
|
JNIEnv *env = get_jni_env();
|
||||||
ERR_FAIL_NULL(env);
|
ERR_FAIL_NULL(env);
|
||||||
|
|
|
@ -112,19 +112,18 @@ public abstract class GodotPlugin {
|
||||||
/**
|
/**
|
||||||
* Register the plugin with Godot native code.
|
* Register the plugin with Godot native code.
|
||||||
* <p>
|
* <p>
|
||||||
* This method is invoked by the Godot Engine on the render thread.
|
* This method is invoked on the render thread to register the plugin on engine startup.
|
||||||
*/
|
*/
|
||||||
public final void onRegisterPluginWithGodotNative() {
|
public final void onRegisterPluginWithGodotNative() {
|
||||||
registeredSignals.putAll(
|
final String pluginName = getPluginName();
|
||||||
registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals()));
|
if (!nativeRegisterSingleton(pluginName, this)) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
private static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject,
|
List<String> pluginMethods = getPluginMethods();
|
||||||
String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals) {
|
|
||||||
nativeRegisterSingleton(pluginName, pluginObject);
|
|
||||||
|
|
||||||
Set<Method> filteredMethods = new HashSet<>();
|
Set<Method> filteredMethods = new HashSet<>();
|
||||||
Class<?> clazz = pluginObject.getClass();
|
Class<?> clazz = getClass();
|
||||||
|
|
||||||
Method[] methods = clazz.getDeclaredMethods();
|
Method[] methods = clazz.getDeclaredMethods();
|
||||||
for (Method method : methods) {
|
for (Method method : methods) {
|
||||||
|
@ -156,15 +155,14 @@ public abstract class GodotPlugin {
|
||||||
nativeRegisterMethod(pluginName, method.getName(), method.getReturnType().getName(), pt);
|
nativeRegisterMethod(pluginName, method.getName(), method.getReturnType().getName(), pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<SignalInfo> pluginSignals = getPluginSignals();
|
||||||
|
|
||||||
// Register the signals for this plugin.
|
// Register the signals for this plugin.
|
||||||
Map<String, SignalInfo> registeredSignals = new HashMap<>();
|
|
||||||
for (SignalInfo signalInfo : pluginSignals) {
|
for (SignalInfo signalInfo : pluginSignals) {
|
||||||
String signalName = signalInfo.getName();
|
String signalName = signalInfo.getName();
|
||||||
nativeRegisterSignal(pluginName, signalName, signalInfo.getParamTypesNames());
|
nativeRegisterSignal(pluginName, signalName, signalInfo.getParamTypesNames());
|
||||||
registeredSignals.put(signalName, signalInfo);
|
registeredSignals.put(signalName, signalInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return registeredSignals;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -408,7 +406,7 @@ public abstract class GodotPlugin {
|
||||||
* Used to setup a {@link GodotPlugin} instance.
|
* Used to setup a {@link GodotPlugin} instance.
|
||||||
* @param p_name Name of the instance.
|
* @param p_name Name of the instance.
|
||||||
*/
|
*/
|
||||||
private static native void nativeRegisterSingleton(String p_name, Object object);
|
private static native boolean nativeRegisterSingleton(String p_name, Object object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to complete registration of the {@link GodotPlugin} instance's methods.
|
* Used to complete registration of the {@link GodotPlugin} instance's methods.
|
||||||
|
|
|
@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
set(GODOT_ROOT_DIR ../../../..)
|
set(GODOT_ROOT_DIR ../../../..)
|
||||||
|
set(ANDROID_ROOT_DIR "${GODOT_ROOT_DIR}/platform/android" CACHE STRING "")
|
||||||
|
|
||||||
# Get sources
|
# Get sources
|
||||||
file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**)
|
file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**)
|
||||||
|
@ -15,6 +16,7 @@ file(GLOB_RECURSE HEADERS ${GODOT_ROOT_DIR}/*.h**)
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME}
|
||||||
SYSTEM PUBLIC
|
SYSTEM PUBLIC
|
||||||
${GODOT_ROOT_DIR})
|
${GODOT_ROOT_DIR}
|
||||||
|
${ANDROID_ROOT_DIR})
|
||||||
|
|
||||||
add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED)
|
add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED)
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "jni_utils.h"
|
#include "jni_utils.h"
|
||||||
#include "net_socket_android.h"
|
#include "net_socket_android.h"
|
||||||
#include "os_android.h"
|
#include "os_android.h"
|
||||||
|
#include "plugin/godot_plugin_jni.h"
|
||||||
#include "string_android.h"
|
#include "string_android.h"
|
||||||
#include "thread_jandroid.h"
|
#include "thread_jandroid.h"
|
||||||
#include "tts_android.h"
|
#include "tts_android.h"
|
||||||
|
@ -78,6 +79,9 @@ static void _terminate(JNIEnv *env, bool p_restart = false) {
|
||||||
step.set(-1); // Ensure no further steps are attempted and no further events are sent
|
step.set(-1); // Ensure no further steps are attempted and no further events are sent
|
||||||
|
|
||||||
// lets cleanup
|
// lets cleanup
|
||||||
|
// Unregister android plugins
|
||||||
|
unregister_plugins_singletons();
|
||||||
|
|
||||||
if (java_class_wrapper) {
|
if (java_class_wrapper) {
|
||||||
memdelete(java_class_wrapper);
|
memdelete(java_class_wrapper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,16 +40,32 @@
|
||||||
|
|
||||||
static HashMap<String, JNISingleton *> jni_singletons;
|
static HashMap<String, JNISingleton *> jni_singletons;
|
||||||
|
|
||||||
|
void unregister_plugins_singletons() {
|
||||||
|
for (const KeyValue<String, JNISingleton *> &E : jni_singletons) {
|
||||||
|
Engine::get_singleton()->remove_singleton(E.key);
|
||||||
|
ProjectSettings::get_singleton()->set(E.key, Variant());
|
||||||
|
|
||||||
|
if (E.value) {
|
||||||
|
memdelete(E.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jni_singletons.clear();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
|
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
|
||||||
String singname = jstring_to_string(name, env);
|
String singname = jstring_to_string(name, env);
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(jni_singletons.has(singname), false);
|
||||||
|
|
||||||
JNISingleton *s = (JNISingleton *)ClassDB::instantiate("JNISingleton");
|
JNISingleton *s = (JNISingleton *)ClassDB::instantiate("JNISingleton");
|
||||||
s->set_instance(env->NewGlobalRef(obj));
|
s->set_instance(env->NewGlobalRef(obj));
|
||||||
jni_singletons[singname] = s;
|
jni_singletons[singname] = s;
|
||||||
|
|
||||||
Engine::get_singleton()->add_singleton(Engine::Singleton(singname, s));
|
Engine::get_singleton()->add_singleton(Engine::Singleton(singname, s));
|
||||||
ProjectSettings::get_singleton()->set(singname, s);
|
ProjectSettings::get_singleton()->set(singname, s);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) {
|
||||||
|
|
|
@ -34,8 +34,10 @@
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
|
void unregister_plugins_singletons();
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
|
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
|
||||||
|
|
Loading…
Reference in New Issue