Skip to content

Commit

Permalink
Merge pull request #92143 from m4gr3d/cleanup_android_plugin_on_exit
Browse files Browse the repository at this point in the history
Add logic to unregister the Godot plugins on engine termination
  • Loading branch information
akien-mga committed May 20, 2024
2 parents b44e9b0 + 5a74e58 commit eef7e29
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 15 deletions.
1 change: 1 addition & 0 deletions platform/android/api/jni_singleton.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ class JNISingleton : public Object {

~JNISingleton() {
#ifdef ANDROID_ENABLED
method_map.clear();
if (instance) {
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL(env);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,18 @@ protected Activity getActivity() {
/**
* Register the plugin with Godot native code.
* <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() {
registeredSignals.putAll(
registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals()));
}
final String pluginName = getPluginName();
if (!nativeRegisterSingleton(pluginName, this)) {
return;
}

private static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject,
String pluginName, List<String> pluginMethods, Set<SignalInfo> pluginSignals) {
nativeRegisterSingleton(pluginName, pluginObject);
List<String> pluginMethods = getPluginMethods();

Set<Method> filteredMethods = new HashSet<>();
Class<?> clazz = pluginObject.getClass();
Class<?> clazz = getClass();

Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
Expand Down Expand Up @@ -156,15 +155,14 @@ private static Map<String, SignalInfo> registerPluginWithGodotNative(Object plug
nativeRegisterMethod(pluginName, method.getName(), method.getReturnType().getName(), pt);
}

Set<SignalInfo> pluginSignals = getPluginSignals();

// Register the signals for this plugin.
Map<String, SignalInfo> registeredSignals = new HashMap<>();
for (SignalInfo signalInfo : pluginSignals) {
String signalName = signalInfo.getName();
nativeRegisterSignal(pluginName, signalName, signalInfo.getParamTypesNames());
registeredSignals.put(signalName, signalInfo);
}

return registeredSignals;
}

/**
Expand Down Expand Up @@ -408,7 +406,7 @@ public static void emitSignal(Godot godot, String pluginName, SignalInfo signalI
* Used to setup a {@link GodotPlugin} 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.
Expand Down
4 changes: 3 additions & 1 deletion platform/android/java/nativeSrcsConfigs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(GODOT_ROOT_DIR ../../../..)
set(ANDROID_ROOT_DIR "${GODOT_ROOT_DIR}/platform/android" CACHE STRING "")

# Get sources
file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**)
Expand All @@ -15,6 +16,7 @@ file(GLOB_RECURSE HEADERS ${GODOT_ROOT_DIR}/*.h**)
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC
${GODOT_ROOT_DIR})
${GODOT_ROOT_DIR}
${ANDROID_ROOT_DIR})

add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED)
4 changes: 4 additions & 0 deletions platform/android/java_godot_lib_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "jni_utils.h"
#include "net_socket_android.h"
#include "os_android.h"
#include "plugin/godot_plugin_jni.h"
#include "string_android.h"
#include "thread_jandroid.h"
#include "tts_android.h"
Expand Down Expand Up @@ -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

// lets cleanup
// Unregister android plugins
unregister_plugins_singletons();

if (java_class_wrapper) {
memdelete(java_class_wrapper);
}
Expand Down
18 changes: 17 additions & 1 deletion platform/android/plugin/godot_plugin_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,32 @@

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" {

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);

ERR_FAIL_COND_V(jni_singletons.has(singname), false);

JNISingleton *s = (JNISingleton *)ClassDB::instantiate("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
jni_singletons[singname] = s;

Engine::get_singleton()->add_singleton(Engine::Singleton(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) {
Expand Down
4 changes: 3 additions & 1 deletion platform/android/plugin/godot_plugin_jni.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
#include <android/log.h>
#include <jni.h>

void unregister_plugins_singletons();

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_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);
Expand Down

0 comments on commit eef7e29

Please sign in to comment.