Skip to content

Commit

Permalink
fix: make proper constructor calls in CallableBridge (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
piiertho committed Nov 16, 2022
1 parent 4f0de9e commit 2feb5b6
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 34 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(GODOT_ROOT_DIR ../../)
# Get sources
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.cpp)

add_library(${PROJECT_NAME} SHARED register_types.cpp ${SOURCES} src/gd_kotlin.cpp src/gd_kotlin.h src/godotkotlin_defs.h src/jni/wrapper.h src/kt_function.cpp src/kt_function.h src/kt_property.cpp src/kt_property.h src/jni/local_frame.cpp src/jni/local_frame.h src/kt_signal_info.cpp src/kt_signal_info.h src/bridges/memory_bridge.cpp src/bridges/memory_bridge.h src/jni/java_method_signature.cpp src/jni/java_method_signature.h src/java_instance_wrapper.h src/shared_buffer.h src/shared_buffer.cpp src/type_manager.cpp src/type_manager.h src/bridges_manager.cpp src/bridges_manager.h src/bridges/variant_array_bridge.cpp src/bridges/variant_array_bridge.h src/bridges/constants.h src/bridges/dictionary_bridge.cpp src/bridges/dictionary_bridge.h src/bridges/bridges_utils.h src/bridges/rid_bridge.cpp src/bridges/rid_bridge.h src/bridges/node_path_bridge.cpp src/bridges/node_path_bridge.h src/bridges/packed_byte_array_bridge.h src/bridges/packed_byte_array_bridge.cpp src/bridges/packed_color_array_bridge.h src/bridges/packed_color_array_bridge.cpp src/bridges/packed_int_32_array_bridge.h src/bridges/packed_int_32_array_bridge.cpp src/bridges/packed_float_32_array_bridge.h src/bridges/packed_float_32_array_bridge.cpp src/bridges/packed_string_array_bridge.h src/bridges/packed_string_array_bridge.cpp src/bridges/packed_vector2_array_bridge.h src/bridges/packed_vector2_array_bridge.cpp src/bridges/packed_vector3_array_bridge.h src/bridges/packed_vector3_array_bridge.cpp src/logging.h src/kt_constructor.cpp src/kt_constructor.h src/bridges/gd_print_bridge.cpp src/bridges/gd_print_bridge.h src/kotlin_editor_export_plugin.cpp src/kotlin_editor_export_plugin.h src/jni/platforms/jvm_desktop.cpp src/jni/platforms/jvm_android.cpp src/jni/platforms/init_args_desktop.cpp src/jni/platforms/init_args_android.cpp src/ref_db.h src/ref_db.cpp src/editor/godot_kotlin_jvm_editor.cpp src/editor/godot_kotlin_jvm_editor.h src/editor/menu_option.h src/editor/build/build_manager.cpp src/editor/build/build_manager.h src/editor/panel/bottom_panel.cpp src/editor/panel/bottom_panel.h src/editor/dialog/build_dialog.cpp src/editor/dialog/build_dialog.h src/editor/dialog/about_dialog.cpp src/editor/dialog/about_dialog.h src/long_string_queue.h src/long_string_queue.cpp src/jni/class_loader.h src/jni/class_loader.cpp src/java_singleton_wrapper.h src/editor/dialog/error_dialog.cpp src/editor/dialog/error_dialog.h src/bridges/packed_int_64_array_bridge.h src/bridges/packed_int_64_array_bridge.cpp src/bridges/packed_float_64_array_bridge.h src/bridges/packed_float_64_array_bridge.cpp src/bridges/string_name_bridge.cpp src/bridges/string_name_bridge.h src/kt_custom_callable.cpp src/kt_custom_callable.h src/bridges/callable_bridge.cpp src/bridges/callable_bridge.h src/kt_custom_callable_middleman.h src/jni/jni_constants.h)
add_library(${PROJECT_NAME} SHARED register_types.cpp ${SOURCES} src/gd_kotlin.cpp src/gd_kotlin.h src/godotkotlin_defs.h src/jni/wrapper.h src/kt_function.cpp src/kt_function.h src/kt_property.cpp src/kt_property.h src/jni/local_frame.cpp src/jni/local_frame.h src/kt_signal_info.cpp src/kt_signal_info.h src/bridges/memory_bridge.cpp src/bridges/memory_bridge.h src/jni/java_method_signature.cpp src/jni/java_method_signature.h src/java_instance_wrapper.h src/shared_buffer.h src/shared_buffer.cpp src/type_manager.cpp src/type_manager.h src/bridges_manager.cpp src/bridges_manager.h src/bridges/variant_array_bridge.cpp src/bridges/variant_array_bridge.h src/bridges/constants.h src/bridges/dictionary_bridge.cpp src/bridges/dictionary_bridge.h src/bridges/bridges_utils.h src/bridges/rid_bridge.cpp src/bridges/rid_bridge.h src/bridges/node_path_bridge.cpp src/bridges/node_path_bridge.h src/bridges/packed_byte_array_bridge.h src/bridges/packed_byte_array_bridge.cpp src/bridges/packed_color_array_bridge.h src/bridges/packed_color_array_bridge.cpp src/bridges/packed_int_32_array_bridge.h src/bridges/packed_int_32_array_bridge.cpp src/bridges/packed_float_32_array_bridge.h src/bridges/packed_float_32_array_bridge.cpp src/bridges/packed_string_array_bridge.h src/bridges/packed_string_array_bridge.cpp src/bridges/packed_vector2_array_bridge.h src/bridges/packed_vector2_array_bridge.cpp src/bridges/packed_vector3_array_bridge.h src/bridges/packed_vector3_array_bridge.cpp src/logging.h src/kt_constructor.cpp src/kt_constructor.h src/bridges/gd_print_bridge.cpp src/bridges/gd_print_bridge.h src/kotlin_editor_export_plugin.cpp src/kotlin_editor_export_plugin.h src/jni/platforms/jvm_desktop.cpp src/jni/platforms/jvm_android.cpp src/jni/platforms/init_args_desktop.cpp src/jni/platforms/init_args_android.cpp src/ref_db.h src/ref_db.cpp src/editor/godot_kotlin_jvm_editor.cpp src/editor/godot_kotlin_jvm_editor.h src/editor/menu_option.h src/editor/build/build_manager.cpp src/editor/build/build_manager.h src/editor/panel/bottom_panel.cpp src/editor/panel/bottom_panel.h src/editor/dialog/build_dialog.cpp src/editor/dialog/build_dialog.h src/editor/dialog/about_dialog.cpp src/editor/dialog/about_dialog.h src/long_string_queue.h src/long_string_queue.cpp src/jni/class_loader.h src/jni/class_loader.cpp src/java_singleton_wrapper.h src/editor/dialog/error_dialog.cpp src/editor/dialog/error_dialog.h src/bridges/packed_int_64_array_bridge.h src/bridges/packed_int_64_array_bridge.cpp src/bridges/packed_float_64_array_bridge.h src/bridges/packed_float_64_array_bridge.cpp src/bridges/string_name_bridge.cpp src/bridges/string_name_bridge.h src/kt_custom_callable.cpp src/kt_custom_callable.h src/bridges/callable_bridge.cpp src/bridges/callable_bridge.h src/jni/jni_constants.h)

# JNI
find_package(JNI REQUIRED)
Expand Down
17 changes: 8 additions & 9 deletions kt/godot-library/src/main/kotlin/godot/core/Callable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ class Callable internal constructor(

constructor(target: Object, methodName: StringName) : this(target, methodName, null) {
TransferContext.writeArguments(VariantType.OBJECT to target, VariantType.STRING_NAME to methodName)
_handle = Bridge.engine_call_constructor(1)
_handle = Bridge.engine_call_constructor_object_string_name()
GarbageCollector.registerNativeCoreType(this, VariantType.CALLABLE)
}

constructor(target: Object, kFunction: KtCallable<KtObject, *>) : this(target, null, KtCustomCallable(target, kFunction)) {
_handle = Bridge.engine_call_constructor(2)
_handle = Bridge.engine_call_constructor_kt_custom_callable(customCallable!!)
GarbageCollector.registerNativeCoreType(this, VariantType.CALLABLE)
}

constructor(jvmCall: () -> Any?) : this(null, null, KtCustomCallable(jvmCall)) {
_handle = Bridge.engine_call_constructor(2)
_handle = Bridge.engine_call_constructor_kt_custom_callable(customCallable!!)
GarbageCollector.registerNativeCoreType(this, VariantType.CALLABLE)
}

constructor(callable: Callable) : this(callable.target, callable.methodName, callable.customCallable) {
TransferContext.writeArguments(VariantType.CALLABLE to callable)
_handle = Bridge.engine_call_constructor(3)
_handle = Bridge.engine_call_copy_constructor()
GarbageCollector.registerNativeCoreType(this, VariantType.CALLABLE)
}

Expand All @@ -55,11 +55,10 @@ class Callable internal constructor(

@Suppress("FunctionName")
object Bridge {
external fun engine_call_constructor(
paramType: Int = 0,
callable: KtCustomCallable? = null,
classLoader: ClassLoader? = null
): VoidPtr
external fun engine_call_constructor(): VoidPtr
external fun engine_call_constructor_object_string_name(): VoidPtr
external fun engine_call_constructor_kt_custom_callable(callable: KtCustomCallable): VoidPtr
external fun engine_call_copy_constructor(): VoidPtr

external fun engine_call_call(handle: VoidPtr)
external fun engine_call_call_deferred(handle: VoidPtr)
Expand Down
72 changes: 51 additions & 21 deletions src/bridges/callable_bridge.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <modules/kotlin_jvm/src/gd_kotlin.h>
#include <modules/kotlin_jvm/src/kt_custom_callable.h>
#include <modules/kotlin_jvm/src/jni/class_loader.h>
#include "callable_bridge.h"
#include "constants.h"
#include "bridges_utils.h"
Expand All @@ -8,25 +8,33 @@ using namespace bridges;

JNI_INIT_STATICS_FOR_CLASS(CallableBridge)

uintptr_t CallableBridge::engine_call_constructor(JNIEnv* p_raw_env, jobject p_instance, jint param_type,
jobject p_kt_custom_callable_instance, jobject p_class_loader) {
if (param_type == 0) {
return reinterpret_cast<uintptr_t>(memnew(Callable));
} else {
jni::Env env{p_raw_env};
Variant args[2] = {};
switch (param_type) {
case 1:
GDKotlin::get_instance().transfer_context->read_args(env, args);
return reinterpret_cast<uintptr_t>(memnew(Callable(args[0].operator Object *(),
args[1].operator StringName())));
case 2:
return reinterpret_cast<uintptr_t>(memnew(Callable(memnew(KtCustomCallable(p_kt_custom_callable_instance, p_class_loader)))));
case 3:
GDKotlin::get_instance().transfer_context->read_args(env, args);
return reinterpret_cast<uintptr_t>(memnew(Callable(args[0].operator Callable())));
}
}
uintptr_t CallableBridge::engine_call_constructor(JNIEnv* p_raw_env, jobject p_instance) {
return reinterpret_cast<uintptr_t>(memnew(Callable));
}

uintptr_t CallableBridge::engine_call_constructor_object_string_name(JNIEnv* p_raw_env, jobject p_instance) {
jni::Env env{p_raw_env};
Variant args[2] = {};
GDKotlin::get_instance().transfer_context->read_args(env, args);
return reinterpret_cast<uintptr_t>(
memnew(Callable(args[0].operator Object *(), args[1].operator StringName()))
);
}

uintptr_t CallableBridge::engine_call_constructor_kt_custom_callable(JNIEnv* p_raw_env, jobject p_instance,
jobject p_kt_custom_callable_instance) {
return reinterpret_cast<uintptr_t>(
memnew(Callable(
memnew(KtCustomCallable(p_kt_custom_callable_instance, ClassLoader::get_default_loader()))
))
);
}

uintptr_t CallableBridge::engine_call_copy_constructor(JNIEnv* p_raw_env, jobject p_instance) {
jni::Env env{p_raw_env};
Variant args[1] = {};
GDKotlin::get_instance().transfer_context->read_args(env, args);
return reinterpret_cast<uintptr_t>(memnew(Callable(args[0].operator Callable())));
}

void CallableBridge::engine_call_call(JNIEnv* p_raw_env, jobject p_instance, jlong p_raw_ptr) {
Expand Down Expand Up @@ -62,10 +70,28 @@ CallableBridge::CallableBridge(jni::JObject p_wrapped, jni::JObject p_class_load
JavaInstanceWrapper<CallableBridge>(CALLABLE_BRIDGE_CLASS_NAME, p_wrapped, p_class_loader){
jni::JNativeMethod engine_call_constructor_method{
"engine_call_constructor",
"(ILgodot/core/KtCustomCallable;Ljava/lang/ClassLoader;)J",
"()J",
(void *) CallableBridge::engine_call_constructor
};

jni::JNativeMethod engine_call_constructor_object_string_name_method{
"engine_call_constructor_object_string_name",
"()J",
(void *) CallableBridge::engine_call_constructor_object_string_name
};

jni::JNativeMethod engine_call_constructor_kt_custom_callable_method{
"engine_call_constructor_kt_custom_callable",
"(Lgodot/core/KtCustomCallable;)J",
(void *) CallableBridge::engine_call_constructor_kt_custom_callable
};

jni::JNativeMethod engine_call_copy_constructor_method{
"engine_call_copy_constructor",
"()J",
(void *) CallableBridge::engine_call_copy_constructor
};

jni::JNativeMethod engine_call_call_method{
"engine_call_call",
"(J)V",
Expand All @@ -80,6 +106,10 @@ CallableBridge::CallableBridge(jni::JObject p_wrapped, jni::JObject p_class_load

Vector<jni::JNativeMethod> methods;
methods.push_back(engine_call_constructor_method);
methods.push_back(engine_call_constructor_object_string_name_method);
methods.push_back(engine_call_constructor_kt_custom_callable_method);
methods.push_back(engine_call_copy_constructor_method);

methods.push_back(engine_call_call_method);
methods.push_back(engine_call_call_deferred_method);

Expand Down
10 changes: 8 additions & 2 deletions src/bridges/callable_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
namespace bridges {
class CallableBridge : public JavaInstanceWrapper<CallableBridge> {
public:
static uintptr_t engine_call_constructor(JNIEnv* p_raw_env, jobject p_instance);

static uintptr_t engine_call_constructor_object_string_name(JNIEnv* p_raw_env, jobject p_instance);

static uintptr_t
engine_call_constructor(JNIEnv* p_raw_env, jobject p_instance, jint param_type,
jobject p_kt_custom_callable_instance, jobject p_class_loader);
engine_call_constructor_kt_custom_callable(JNIEnv* p_raw_env, jobject p_instance,
jobject p_kt_custom_callable_instance);

static uintptr_t engine_call_copy_constructor(JNIEnv* p_raw_env, jobject p_instance);

static void engine_call_call(JNIEnv* p_raw_env, jobject p_instance, jlong p_raw_ptr);
static void engine_call_call_deferred(JNIEnv* p_raw_env, jobject p_instance, jlong p_raw_ptr);
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion src/transfer_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "kotlin_instance.h"

JNI_INIT_STATICS_FOR_CLASS(TransferContext)

const int VARIANT_ARG_MAX{5};
const int MAX_STACK_SIZE = VARIANT_ARG_MAX * 8;

thread_local static Variant variant_args[MAX_STACK_SIZE]; // NOLINT(cert-err58-cpp)
Expand Down

0 comments on commit 2feb5b6

Please sign in to comment.