Skip to content

Commit 58a6412

Browse files
committed
Merge pull request godotengine#111135 from m4gr3d/add_emit_signal_overload
[Android] Minor updates to the `GodotPlugin` APIs
2 parents 331d57d + b9c3b1d commit 58a6412

File tree

6 files changed

+44
-45
lines changed

6 files changed

+44
-45
lines changed

platform/android/api/java_class_wrapper.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class JavaClass : public RefCounted {
7070
RBMap<StringName, Variant> constant_map;
7171

7272
struct MethodInfo {
73+
bool _public = false;
7374
bool _static = false;
7475
bool _constructor = false;
7576
Vector<uint32_t> param_types;
@@ -276,7 +277,7 @@ class JavaClassWrapper : public Object {
276277

277278
Ref<JavaObject> exception;
278279

279-
Ref<JavaClass> _wrap(const String &p_class, bool p_allow_non_public_methods_access);
280+
Ref<JavaClass> _wrap(const String &p_class, bool p_allow_non_public_methods_access = false);
280281

281282
static JavaClassWrapper *singleton;
282283

@@ -295,7 +296,7 @@ class JavaClassWrapper : public Object {
295296
}
296297

297298
#ifdef ANDROID_ENABLED
298-
Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_private_methods_access = false);
299+
Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_non_public_methods_access = false);
299300
#endif
300301
JavaClassWrapper();
301302
};

platform/android/api/jni_singleton.h

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,31 +61,15 @@ class JNISingleton : public Object {
6161
}
6262

6363
// Check the method we're looking for is in the JNISingleton map.
64+
// This is done because JNISingletons register methods differently than wrapped JavaClass / JavaObject to allow
65+
// for access to private methods annotated with the @UsedByGodot annotation.
66+
// In the future, we should remove access to private methods and require that JNISingletons' methods exposed to
67+
// GDScript be all public, similarly to what we do for wrapped JavaClass / JavaObject methods. Doing so will
68+
// also allow dropping and deprecating the @UsedByGodot annotation.
6469
RBMap<StringName, MethodData>::Element *E = method_map.find(p_method);
6570
if (E) {
6671
if (wrapped_object.is_valid()) {
67-
// Check that the arguments match.
68-
int method_arg_count = E->get().argtypes.size();
69-
if (p_argcount < method_arg_count) {
70-
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
71-
} else if (p_argcount > method_arg_count) {
72-
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
73-
} else {
74-
// Check the arguments are valid.
75-
bool arguments_valid = true;
76-
for (int i = 0; i < p_argcount; i++) {
77-
if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
78-
arguments_valid = false;
79-
break;
80-
}
81-
}
82-
83-
if (arguments_valid) {
84-
return wrapped_object->callp(p_method, p_args, p_argcount, r_error);
85-
} else {
86-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
87-
}
88-
}
72+
return wrapped_object->callp(p_method, p_args, p_argcount, r_error);
8973
} else {
9074
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
9175
}

platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ protected void runOnRenderThread(Runnable action) {
361361
/**
362362
* Emit a registered Godot signal.
363363
* @param signalName Name of the signal to emit. It will be validated against the set of registered signals.
364-
* @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the {@link SignalInfo} matching the registered signalName parameter.
364+
* @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the registered {@link SignalInfo} matching the signalName parameter.
365365
*/
366366
protected void emitSignal(final String signalName, final Object... signalArgs) {
367367
try {
@@ -380,6 +380,15 @@ protected void emitSignal(final String signalName, final Object... signalArgs) {
380380
}
381381
}
382382

383+
/**
384+
* Emit a registered Godot signal.
385+
* @param signal Signal to emit. It will be validated against the set of registered signals.
386+
* @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the registered {@link SignalInfo} matching the signal parameter.
387+
*/
388+
protected void emitSignal(SignalInfo signal, final Object... signalArgs) {
389+
emitSignal(signal.getName(), signalArgs);
390+
}
391+
383392
/**
384393
* Emit a Godot signal.
385394
* @param godot Godot instance
@@ -402,7 +411,8 @@ public static void emitSignal(Godot godot, String pluginName, SignalInfo signalI
402411

403412
// Validate the argument's types.
404413
for (int i = 0; i < signalParamTypes.length; i++) {
405-
if (!signalParamTypes[i].isInstance(signalArgs[i])) {
414+
Object signalArg = signalArgs[i];
415+
if (signalArg != null && !signalParamTypes[i].isInstance(signalArg)) {
406416
throw new IllegalArgumentException(
407417
"Invalid type for argument #" + i + ". Should be of type " + signalParamTypes[i].getName());
408418
}

platform/android/java_class_wrapper.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
199199
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
200200
if (p_args[i]->get_type() == Variant::ARRAY) {
201201
Array arr = *p_args[i];
202-
if (arr.is_typed() && arr.get_typed_builtin() != Variant::STRING) {
202+
if (arr.is_typed() && (arr.get_typed_builtin() != Variant::STRING || arr.get_typed_builtin() != Variant::STRING_NAME)) {
203203
arg_expected = Variant::ARRAY;
204204
}
205205
} else if (p_args[i]->get_type() != Variant::PACKED_STRING_ARRAY) {
@@ -1527,6 +1527,7 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_non_p
15271527
}
15281528

15291529
JavaClass::MethodInfo mi;
1530+
mi._public = is_public;
15301531
mi._static = (mods & 0x8) != 0;
15311532
mi._constructor = is_constructor;
15321533
bool valid = true;
@@ -1686,15 +1687,15 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_non_p
16861687
return java_class;
16871688
}
16881689

1689-
Ref<JavaClass> JavaClassWrapper::wrap_jclass(jclass p_class, bool p_allow_private_methods_access) {
1690+
Ref<JavaClass> JavaClassWrapper::wrap_jclass(jclass p_class, bool p_allow_non_public_methods_access) {
16901691
JNIEnv *env = get_jni_env();
16911692
ERR_FAIL_NULL_V(env, Ref<JavaClass>());
16921693

16931694
jstring class_name = (jstring)env->CallObjectMethod(p_class, Class_getName);
16941695
String class_name_string = jstring_to_string(class_name, env);
16951696
env->DeleteLocalRef(class_name);
16961697

1697-
return _wrap(class_name_string, p_allow_private_methods_access);
1698+
return _wrap(class_name_string, p_allow_non_public_methods_access);
16981699
}
16991700

17001701
JavaClassWrapper *JavaClassWrapper::singleton = nullptr;

platform/android/jni_utils.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,17 @@ Callable jcallable_to_callable(JNIEnv *p_env, jobject p_jcallable_obj) {
5555
ERR_FAIL_NULL_V(p_env, Callable());
5656

5757
const Variant *callable_variant = nullptr;
58-
jclass callable_class = jni_find_class(p_env, "org/godotengine/godot/variant/Callable");
59-
if (callable_class && p_env->IsInstanceOf(p_jcallable_obj, callable_class)) {
60-
jmethodID get_native_pointer = p_env->GetMethodID(callable_class, "getNativePointer", "()J");
61-
jlong native_callable = p_env->CallLongMethod(p_jcallable_obj, get_native_pointer);
58+
if (p_jcallable_obj) {
59+
jclass callable_class = jni_find_class(p_env, "org/godotengine/godot/variant/Callable");
60+
if (callable_class && p_env->IsInstanceOf(p_jcallable_obj, callable_class)) {
61+
jmethodID get_native_pointer = p_env->GetMethodID(callable_class, "getNativePointer", "()J");
62+
jlong native_callable = p_env->CallLongMethod(p_jcallable_obj, get_native_pointer);
6263

63-
callable_variant = reinterpret_cast<const Variant *>(native_callable);
64-
}
64+
callable_variant = reinterpret_cast<const Variant *>(native_callable);
65+
}
6566

66-
p_env->DeleteLocalRef(callable_class);
67+
p_env->DeleteLocalRef(callable_class);
68+
}
6769

6870
ERR_FAIL_NULL_V(callable_variant, Callable());
6971
return *callable_variant;
@@ -73,16 +75,18 @@ String charsequence_to_string(JNIEnv *p_env, jobject p_charsequence) {
7375
ERR_FAIL_NULL_V(p_env, String());
7476

7577
String result;
76-
jclass bclass = jni_find_class(p_env, "java/lang/CharSequence");
77-
if (bclass && p_env->IsInstanceOf(p_charsequence, bclass)) {
78-
jmethodID to_string = p_env->GetMethodID(bclass, "toString", "()Ljava/lang/String;");
79-
jstring obj_string = (jstring)p_env->CallObjectMethod(p_charsequence, to_string);
78+
if (p_charsequence) {
79+
jclass bclass = jni_find_class(p_env, "java/lang/CharSequence");
80+
if (bclass && p_env->IsInstanceOf(p_charsequence, bclass)) {
81+
jmethodID to_string = p_env->GetMethodID(bclass, "toString", "()Ljava/lang/String;");
82+
jstring obj_string = (jstring)p_env->CallObjectMethod(p_charsequence, to_string);
83+
84+
result = jstring_to_string(obj_string, p_env);
85+
p_env->DeleteLocalRef(obj_string);
86+
}
8087

81-
result = jstring_to_string(obj_string, p_env);
82-
p_env->DeleteLocalRef(obj_string);
88+
p_env->DeleteLocalRef(bclass);
8389
}
84-
85-
p_env->DeleteLocalRef(bclass);
8690
return result;
8791
}
8892

platform/android/plugin/godot_plugin_jni.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
128128

129129
for (int i = 0; i < count; i++) {
130130
jobject j_param = env->GetObjectArrayElement(j_signal_params, i);
131-
ERR_FAIL_NULL(j_param);
132131
memnew_placement(&variant_params[i], Variant(_jobject_to_variant(env, j_param)));
133132
args[i] = &variant_params[i];
134133
env->DeleteLocalRef(j_param);

0 commit comments

Comments
 (0)