Skip to content

Commit ff3d16a

Browse files
authored
Fix default values of user script types (#137)
* Fix script default value init by fetching properties after all classes are registered in cpp * Use cpp11 init and add ptr explicitly * Update entry gen ref
1 parent 1724dc2 commit ff3d16a

10 files changed

Lines changed: 50 additions & 19 deletions

File tree

kt/godot-runtime/src/main/kotlin/godot/core/Properties.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ open class KtProperty<T : KtObject, P: Any?>(
2121
val ktPropertyInfo: KtPropertyInfo,
2222
protected val kProperty: KMutableProperty1<T, P>,
2323
protected val variantType: VariantType,
24-
internal val _defaultValue: P?,
24+
internal val _defaultValue: () -> P?,
2525
val isRef: Boolean
2626
) {
2727
open fun getDefaultValue() {
28-
TransferContext.writeReturnValue(_defaultValue, variantType)
28+
TransferContext.writeReturnValue(_defaultValue(), variantType)
2929
}
3030

3131
open fun callGet(instance: T) {
@@ -50,7 +50,7 @@ open class KtProperty<T : KtObject, P: Any?>(
5050
class KtEnumProperty<T : KtObject, P : Any>(
5151
ktPropertyInfo: KtPropertyInfo,
5252
kProperty: KMutableProperty1<T, P>,
53-
defaultValue: P,
53+
defaultValue: () -> P,
5454
val getValueConverter: (P?) -> Int,
5555
val setValueConverter: (Int) -> P
5656
) : KtProperty<T, P>(
@@ -61,7 +61,7 @@ class KtEnumProperty<T : KtObject, P : Any>(
6161
false
6262
) {
6363
override fun getDefaultValue() {
64-
TransferContext.writeReturnValue(getValueConverter(_defaultValue), VariantType.JVM_INT)
64+
TransferContext.writeReturnValue(getValueConverter(_defaultValue()), VariantType.JVM_INT)
6565
}
6666

6767
override fun callGet(instance: T) {

kt/godot-runtime/src/main/kotlin/godot/runtime/Bootstrap.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class Bootstrap {
112112
}
113113
loadClasses(registry!!.classes.toTypedArray())
114114
registerUserTypesNames(TypeManager.userTypes.toTypedArray())
115+
registerUserTypesMembers()
115116
} else {
116117
err("Unable to find Entry class, no classes will be loaded")
117118
}
@@ -158,4 +159,5 @@ class Bootstrap {
158159
)
159160

160161
private external fun registerUserTypesNames(userTypesNames: Array<String>)
162+
private external fun registerUserTypesMembers()
161163
}

kt/godot-runtime/src/main/kotlin/godot/runtime/Registration.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class ClassBuilderDsl<T : KtObject>(
6363
className: String,
6464
hint: PropertyHint = PropertyHint.NONE,
6565
hintString: String = "",
66-
defaultArgument: P?,
66+
defaultArgument: () -> P?,
6767
rpcModeId: Int = 0,
6868
isRef: Boolean = false
6969
) {
@@ -88,9 +88,9 @@ class ClassBuilderDsl<T : KtObject>(
8888
}
8989

9090
inline fun <reified P : Enum<P>> enumProperty(
91-
kProperty: KMutableProperty1<T, P>,
92-
defaultValue: P,
93-
rpcModeId: Int = 0
91+
kProperty: KMutableProperty1<T, P>,
92+
noinline defaultValue: () -> P,
93+
rpcModeId: Int = 0
9494
) {
9595
val propertyName = kProperty.name.camelToSnakeCase()
9696
require(!properties.contains(propertyName)) {
@@ -142,13 +142,13 @@ class ClassBuilderDsl<T : KtObject>(
142142
@JvmName("enumFlagPropertyMutable")
143143
inline fun <reified P : Enum<P>> enumFlagProperty(
144144
kProperty: KMutableProperty1<T, MutableSet<P>>,
145-
defaultValue: MutableSet<P>,
145+
noinline defaultValue: () -> MutableSet<P>,
146146
rpcModeId: Int
147147
) = enumFlagProperty(kProperty as KMutableProperty1<T, Set<P>>, defaultValue, rpcModeId)
148148

149149
inline fun <reified P : Enum<P>> enumFlagProperty(
150150
kProperty: KMutableProperty1<T, Set<P>>,
151-
defaultValue: Set<P>,
151+
noinline defaultValue: () -> Set<P>,
152152
rpcModeId: Int
153153
) {
154154
val propertyName = kProperty.name.camelToSnakeCase()
@@ -202,7 +202,7 @@ class ClassBuilderDsl<T : KtObject>(
202202
variantType: VariantType,
203203
setValueConverter: ((Any?) -> P),
204204
isRef: Boolean = false,
205-
defaultArgument: P,
205+
defaultArgument: () -> P,
206206
rpcModeId: Int = 0,
207207
pib: KtPropertyInfoBuilderDsl.() -> Unit
208208
) {

src/bootstrap.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Bootstrap::Bootstrap(jni::JObject p_wrapped, jni::JObject p_class_loader) : Java
1111
void
1212
Bootstrap::register_hooks(jni::Env& p_env, LoadClassesHook p_load_classes_hook, UnloadClassesHook p_unload_classes_hook,
1313
RegisterManagedEngineTypesHook p_register_managed_engine_types_hook,
14-
RegisterUserTypesNamesHook p_user_types_names_hook) {
14+
RegisterUserTypesNamesHook p_user_types_names_hook, RegisterUserTypesMembersHook p_user_types_nmembers_hook) {
1515
jni::JNativeMethod load_class_hook_method {
1616
"loadClasses",
1717
"([Lgodot/core/KtClass;)V",
@@ -36,11 +36,18 @@ Bootstrap::register_hooks(jni::Env& p_env, LoadClassesHook p_load_classes_hook,
3636
(void*) p_user_types_names_hook
3737
};
3838

39+
jni::JNativeMethod register_user_types_members {
40+
"registerUserTypesMembers",
41+
"()V",
42+
(void*) p_user_types_nmembers_hook
43+
};
44+
3945
Vector<jni::JNativeMethod> methods;
4046
methods.push_back(load_class_hook_method);
4147
methods.push_back(unload_class_hook_method);
4248
methods.push_back(register_managed_engine_types_method);
4349
methods.push_back(register_user_types_names);
50+
methods.push_back(register_user_types_members);
4451
j_class.register_natives(p_env, methods);
4552
}
4653

src/bootstrap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ class Bootstrap : public JavaInstanceWrapper<Bootstrap> {
1212
jobjectArray singleton_names, jobjectArray method_names,
1313
jobjectArray types_of_methods);
1414
typedef void (*RegisterUserTypesNamesHook)(JNIEnv* p_env, jobject p_this, jobjectArray classes_names);
15+
typedef void (*RegisterUserTypesMembersHook)(JNIEnv* p_env, jobject p_this);
1516

1617
Bootstrap(jni::JObject p_wrapped, jni::JObject p_class_loader);
1718
~Bootstrap() = default;
1819

1920
void register_hooks(jni::Env& p_env, LoadClassesHook p_load_classes_hook, UnloadClassesHook p_unload_classes_hook,
2021
RegisterManagedEngineTypesHook p_register_managed_engine_types_hook,
21-
RegisterUserTypesNamesHook p_user_types_names_hook);
22+
RegisterUserTypesNamesHook p_user_types_names_hook, RegisterUserTypesMembersHook p_user_types_nmembers_hook);
2223
void init(jni::Env& p_env, bool p_is_editor, const String& p_project_path, const String& p_jar_file,
2324
const jni::JObject& p_class_loader);
2425
void finish(jni::Env& p_env);

src/gd_kotlin.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ void register_user_types_hook(JNIEnv* p_env, jobject p_this, jobjectArray p_type
188188
LOG_VERBOSE("Done registering user types.");
189189
}
190190

191+
void register_user_types_members_hook(JNIEnv* p_env, jobject p_this) {
192+
jni::Env env(p_env);
193+
GDKotlin::get_instance().register_members(env);
194+
}
195+
191196
void GDKotlin::init() {
192197
if (Main::is_project_manager()) {
193198
#ifdef DEBUG_ENABLED
@@ -377,7 +382,7 @@ void GDKotlin::init() {
377382
bootstrap = new Bootstrap(instance, class_loader);
378383

379384
bootstrap->register_hooks(env, load_classes_hook, unload_classes_hook, register_engine_types_hook,
380-
register_user_types_hook);
385+
register_user_types_hook, register_user_types_members_hook);
381386
bool is_editor = Engine::get_singleton()->is_editor_hint();
382387

383388
#ifdef TOOLS_ENABLED
@@ -539,3 +544,11 @@ GDKotlin::GDKotlin() :
539544
is_gc_started(false),
540545
transfer_context(nullptr) {
541546
}
547+
548+
void GDKotlin::register_members(jni::Env& p_env) {
549+
auto* map_entry{classes.front()};
550+
while (map_entry) {
551+
map_entry->get()->fetch_members();
552+
map_entry = map_entry->next();
553+
}
554+
}

src/gd_kotlin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class GDKotlin {
4949

5050
void register_classes(jni::Env& p_env, jni::JObjectArray p_classes);
5151

52+
void register_members(jni::Env& p_env);
53+
5254
void unregister_classes(jni::Env& p_env, jni::JObjectArray p_classes);
5355

5456
KtClass* find_class(const StringName& p_script_path);

src/kt_class.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ KtClass::KtClass(jni::JObject p_wrapped, jni::JObject& p_class_loader) :
1111
registered_class_name = get_registered_name(env);
1212
super_class = get_super_class(env);
1313
base_godot_class = get_base_godot_class(env);
14-
fetch_methods(env);
15-
fetch_properties(env);
16-
fetch_signals(env);
17-
fetch_constructors(env);
1814
}
1915

2016
KtClass::~KtClass() {
@@ -156,3 +152,11 @@ void KtClass::get_property_list(List<PropertyInfo>* p_list) {
156152
void KtClass::get_signal_list(List<MethodInfo>* p_list) {
157153
get_member_list(p_list, signal_infos);
158154
}
155+
156+
void KtClass::fetch_members() {
157+
jni::Env env { jni::Jvm::current_env() };
158+
fetch_methods(env);
159+
fetch_properties(env);
160+
fetch_signals(env);
161+
fetch_constructors(env);
162+
}

src/kt_class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class KtClass : public JavaInstanceWrapper<KtClass> {
3939

4040
void get_signal_list(List<MethodInfo>* p_list);
4141

42+
void fetch_members();
43+
4244
private:
4345
HashMap<StringName, KtFunction*> methods;
4446
HashMap<StringName, KtProperty*> properties;

0 commit comments

Comments
 (0)