Skip to content

Commit 239c7cd

Browse files
committed
Test that internal classes work as expected
1 parent 8bb931c commit 239c7cd

File tree

8 files changed

+61
-5
lines changed

8 files changed

+61
-5
lines changed

gdextension/gdextension_interface.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ typedef struct {
399399
void *class_userdata; // Per-class user data, later accessible in instance bindings.
400400
} GDExtensionClassCreationInfo4;
401401

402+
typedef GDExtensionClassCreationInfo4 GDExtensionClassCreationInfo5;
403+
402404
typedef void *GDExtensionClassLibraryPtr;
403405

404406
/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */
@@ -2943,6 +2945,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionCl
29432945
/**
29442946
* @name classdb_register_extension_class4
29452947
* @since 4.4
2948+
* @deprecated in Godot 4.5. Use `classdb_register_extension_class5` instead.
29462949
*
29472950
* Registers an extension class in the ClassDB.
29482951
*
@@ -2955,6 +2958,21 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionCl
29552958
*/
29562959
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass4)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs);
29572960

2961+
/**
2962+
* @name classdb_register_extension_class5
2963+
* @since 4.5
2964+
*
2965+
* Registers an extension class in the ClassDB.
2966+
*
2967+
* Provided struct can be safely freed once the function returns.
2968+
*
2969+
* @param p_library A pointer the library received by the GDExtension's entry point function.
2970+
* @param p_class_name A pointer to a StringName with the class name.
2971+
* @param p_parent_class_name A pointer to a StringName with the parent class name.
2972+
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
2973+
*/
2974+
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass5)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo5 *p_extension_funcs);
2975+
29582976
/**
29592977
* @name classdb_register_extension_class_method
29602978
* @since 4.1

include/godot_cpp/core/class_db.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
252252
class_register_order.push_back(cl.name);
253253

254254
// Register this class with Godot
255-
GDExtensionClassCreationInfo4 class_info = {
255+
GDExtensionClassCreationInfo5 class_info = {
256256
p_virtual, // GDExtensionBool is_virtual;
257257
is_abstract, // GDExtensionBool is_abstract;
258258
p_exposed, // GDExtensionBool is_exposed;
@@ -278,7 +278,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
278278
(void *)&T::get_class_static(), // void *class_userdata;
279279
};
280280

281-
internal::gdextension_interface_classdb_register_extension_class4(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
281+
internal::gdextension_interface_classdb_register_extension_class5(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
282282

283283
// call bind_methods etc. to register all members of the class
284284
T::initialize_class();

include/godot_cpp/godot.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ extern "C" GDExtensionInterfaceObjectSetScriptInstance gdextension_interface_obj
185185
extern "C" GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2;
186186
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
187187
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
188-
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4;
188+
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass5 gdextension_interface_classdb_register_extension_class5;
189189
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
190190
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
191191
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;

src/godot.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ GDExtensionInterfaceObjectSetScriptInstance gdextension_interface_object_set_scr
192192
GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2 = nullptr;
193193
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
194194
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
195-
GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4 = nullptr;
195+
GDExtensionInterfaceClassdbRegisterExtensionClass5 gdextension_interface_classdb_register_extension_class5 = nullptr;
196196
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
197197
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
198198
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
@@ -477,7 +477,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
477477
LOAD_PROC_ADDRESS(classdb_construct_object2, GDExtensionInterfaceClassdbConstructObject2);
478478
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
479479
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
480-
LOAD_PROC_ADDRESS(classdb_register_extension_class4, GDExtensionInterfaceClassdbRegisterExtensionClass4);
480+
LOAD_PROC_ADDRESS(classdb_register_extension_class5, GDExtensionInterfaceClassdbRegisterExtensionClass5);
481481
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
482482
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
483483
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);

test/project/main.gd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ func _ready():
287287
assert_equal(library_path, ProjectSettings.globalize_path(library_path))
288288
assert_equal(FileAccess.file_exists(library_path), true)
289289

290+
# Test that internal classes work as expected (at least for Godot 4.5+).
291+
assert_equal(ClassDB.can_instantiate("ExampleInternal"), false)
292+
assert_equal(ClassDB.instantiate("ExampleInternal"), null)
293+
var internal_class = example.test_get_internal_class()
294+
assert_equal(internal_class.get_the_answer(), 42)
295+
assert_equal(internal_class.get_class(), "ExampleInternal")
296+
290297
# Test a class with a unicode name.
291298
var przykład = ExamplePrzykład.new()
292299
assert_equal(przykład.get_the_word(), "słowo to przykład")

test/src/example.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ void Example::_bind_methods() {
252252

253253
ClassDB::bind_method(D_METHOD("test_use_engine_singleton"), &Example::test_use_engine_singleton);
254254

255+
ClassDB::bind_method(D_METHOD("test_get_internal_class"), &Example::test_get_internal_class);
256+
255257
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
256258
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
257259

@@ -744,6 +746,12 @@ String Example::test_library_path() {
744746
return library_path;
745747
}
746748

749+
Ref<RefCounted> Example::test_get_internal_class() const {
750+
Ref<ExampleInternal> it;
751+
it.instantiate();
752+
return it;
753+
}
754+
747755
int64_t Example::test_get_internal(const Variant &p_input) const {
748756
if (p_input.get_type() != Variant::INT) {
749757
return -1;
@@ -779,3 +787,11 @@ void ExamplePrzykład::_bind_methods() {
779787
String ExamplePrzykład::get_the_word() const {
780788
return U"słowo to przykład";
781789
}
790+
791+
void ExampleInternal::_bind_methods() {
792+
ClassDB::bind_method(D_METHOD("get_the_answer"), &ExampleInternal::get_the_answer);
793+
}
794+
795+
int ExampleInternal::get_the_answer() const {
796+
return 42;
797+
}

test/src/example.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
using namespace godot;
3131

32+
class ExampleInternal;
33+
3234
class ExampleRef : public RefCounted {
3335
GDCLASS(ExampleRef, RefCounted);
3436

@@ -203,6 +205,8 @@ class Example : public Control {
203205
String test_use_engine_singleton() const;
204206

205207
static String test_library_path();
208+
209+
Ref<RefCounted> test_get_internal_class() const;
206210
};
207211

208212
VARIANT_ENUM_CAST(Example::Constants);
@@ -288,3 +292,13 @@ class ExamplePrzykład : public RefCounted {
288292
public:
289293
String get_the_word() const;
290294
};
295+
296+
class ExampleInternal : public RefCounted {
297+
GDCLASS(ExampleInternal, RefCounted);
298+
299+
protected:
300+
static void _bind_methods();
301+
302+
public:
303+
int get_the_answer() const;
304+
};

test/src/register_types.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
3131
GDREGISTER_CLASS(ExampleChild);
3232
GDREGISTER_RUNTIME_CLASS(ExampleRuntime);
3333
GDREGISTER_CLASS(ExamplePrzykład);
34+
GDREGISTER_INTERNAL_CLASS(ExampleInternal);
3435
}
3536

3637
void uninitialize_example_module(ModuleInitializationLevel p_level) {

0 commit comments

Comments
 (0)