Skip to content

Commit 5027c77

Browse files
committed
Add back support for Godot 4.4
1 parent 7df6252 commit 5027c77

File tree

8 files changed

+323873
-7
lines changed

8 files changed

+323873
-7
lines changed

gdextension/extension_api-4-4.json

Lines changed: 323821 additions & 0 deletions
Large diffs are not rendered by default.

include/godot_cpp/core/class_db.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,11 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
242242
class_register_order.push_back(cl.name);
243243

244244
// Register this class with Godot
245+
#if GODOT_VERSION_MINOR >= 5
245246
GDExtensionClassCreationInfo5 class_info = {
247+
#else
248+
GDExtensionClassCreationInfo4 class_info = {
249+
#endif
246250
p_virtual, // GDExtensionBool is_virtual;
247251
is_abstract, // GDExtensionBool is_abstract;
248252
p_exposed, // GDExtensionBool is_exposed;
@@ -268,7 +272,11 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
268272
(void *)&T::get_class_static(), // void *class_userdata;
269273
};
270274

275+
#if GODOT_VERSION_MINOR >= 5
271276
::godot::gdextension_interface::classdb_register_extension_class5(::godot::gdextension_interface::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
277+
#else
278+
::godot::gdextension_interface::classdb_register_extension_class4(::godot::gdextension_interface::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
279+
#endif
272280

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

include/godot_cpp/godot.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ extern "C" GDExtensionInterfaceGetProcAddress get_proc_address;
4040
extern "C" GDExtensionClassLibraryPtr library;
4141
extern "C" void *token;
4242

43+
#if GODOT_VERSION_MINOR >= 5
4344
extern "C" GDExtensionGodotVersion2 godot_version;
45+
#else
46+
extern "C" GDExtensionGodotVersion godot_version;
47+
#endif
4448

4549
} // namespace gdextension_interface
4650

@@ -69,11 +73,13 @@ class GDExtensionBinding {
6973
GDExtensionInitializationLevel minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
7074
Callback init_callback = nullptr;
7175
Callback terminate_callback = nullptr;
76+
#if GODOT_VERSION_MINOR >= 5
7277
GDExtensionMainLoopCallbacks main_loop_callbacks = {};
7378

7479
inline bool has_main_loop_callbacks() const {
7580
return main_loop_callbacks.frame_func || main_loop_callbacks.startup_func || main_loop_callbacks.shutdown_func;
7681
}
82+
#endif
7783
};
7884

7985
class InitDataList {
@@ -108,12 +114,14 @@ class GDExtensionBinding {
108114
void register_terminator(Callback p_init) const;
109115
void set_minimum_library_initialization_level(ModuleInitializationLevel p_level) const;
110116

117+
#if GODOT_VERSION_MINOR >= 5
111118
// Register a callback that is called after all initialization levels when Godot is fully initialized.
112119
void register_startup_callback(GDExtensionMainLoopStartupCallback p_callback) const;
113120
// Register a callback that is called for every process frame. This will run after all `_process()` methods on Node, and before `ScriptServer::frame()`.
114121
void register_frame_callback(GDExtensionMainLoopFrameCallback p_callback) const;
115122
// Register a callback that is called before Godot is shutdown when it is still fully initialized.
116123
void register_shutdown_callback(GDExtensionMainLoopShutdownCallback p_callback) const;
124+
#endif
117125

118126
GDExtensionBool init() const;
119127
};

src/godot.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ GDExtensionInterfaceGetProcAddress get_proc_address = nullptr;
5050
GDExtensionClassLibraryPtr library = nullptr;
5151
void *token = nullptr;
5252

53+
#if GODOT_VERSION_MINOR >= 5
5354
GDExtensionGodotVersion2 godot_version = {};
55+
#else
56+
GDExtensionGodotVersion godot_version = {};
57+
#endif
5458

5559
} // namespace gdextension_interface
5660

@@ -142,8 +146,13 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
142146
::godot::gdextension_interface::library = p_library;
143147
::godot::gdextension_interface::token = p_library;
144148

149+
#if GODOT_VERSION_MINOR >= 5
145150
LOAD_PROC_ADDRESS(get_godot_version2, GDExtensionInterfaceGetGodotVersion2);
146151
::godot::gdextension_interface::get_godot_version2(&::godot::gdextension_interface::godot_version);
152+
#else
153+
LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion);
154+
::godot::gdextension_interface::get_godot_version(&::godot::gdextension_interface::godot_version);
155+
#endif
147156

148157
// Check that godot-cpp was compiled using an extension_api.json older or at the
149158
// same version as the Godot that is loading it.
@@ -204,12 +213,16 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
204213
}
205214
level_initialized[p_level]++;
206215

216+
#if GODOT_VERSION_MINOR >= 5
207217
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_CORE && init_data && init_data->has_main_loop_callbacks()) {
208218
::godot::gdextension_interface::register_main_loop_callbacks(::godot::gdextension_interface::library, &init_data->main_loop_callbacks);
209219
}
220+
#endif
210221

211222
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
223+
#if GODOT_VERSION_MINOR >= 5
212224
::godot::gdextension_interface::editor_register_get_classes_used_callback(::godot::gdextension_interface::library, &ClassDB::_editor_get_classes_used_callback);
225+
#endif
213226

214227
const ::godot::internal::DocData &doc_data = ::godot::internal::get_doc_data();
215228
if (doc_data.is_valid()) {
@@ -278,6 +291,7 @@ void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(Mo
278291
init_data->minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
279292
}
280293

294+
#if GODOT_VERSION_MINOR >= 5
281295
void GDExtensionBinding::InitObject::register_startup_callback(GDExtensionMainLoopStartupCallback p_callback) const {
282296
init_data->main_loop_callbacks.startup_func = p_callback;
283297
}
@@ -289,6 +303,7 @@ void GDExtensionBinding::InitObject::register_frame_callback(GDExtensionMainLoop
289303
void GDExtensionBinding::InitObject::register_shutdown_callback(GDExtensionMainLoopShutdownCallback p_callback) const {
290304
init_data->main_loop_callbacks.shutdown_func = p_callback;
291305
}
306+
#endif
292307

293308
GDExtensionBool GDExtensionBinding::InitObject::init() const {
294309
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);

test/project/main.gd

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class TestClass:
88

99
func _ready():
1010
var example: Example = $Example
11+
var godot_target_version := example.get_godot_target_version()
1112

1213
# Timing of set instance binding.
1314
assert_equal(example.is_object_binding_set_by_parent_constructor(), true)
@@ -290,12 +291,13 @@ func _ready():
290291
assert_equal(library_path, ProjectSettings.globalize_path(library_path))
291292
assert_equal(FileAccess.file_exists(library_path), true)
292293

293-
# Test that internal classes work as expected (at least for Godot 4.5+).
294-
assert_equal(ClassDB.can_instantiate("ExampleInternal"), false)
295-
assert_equal(ClassDB.instantiate("ExampleInternal"), null)
296-
var internal_class = example.test_get_internal_class()
297-
assert_equal(internal_class.get_the_answer(), 42)
298-
assert_equal(internal_class.get_class(), "ExampleInternal")
294+
if godot_target_version[1] >= 5:
295+
# Test that internal classes work as expected (at least for Godot 4.5+).
296+
assert_equal(ClassDB.can_instantiate("ExampleInternal"), false)
297+
assert_equal(ClassDB.instantiate("ExampleInternal"), null)
298+
var internal_class = example.test_get_internal_class()
299+
assert_equal(internal_class.get_the_answer(), 42)
300+
assert_equal(internal_class.get_class(), "ExampleInternal")
299301

300302
# Test a class with a unicode name.
301303
var przykład = ExamplePrzykład.new()

test/src/example.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ ExampleRef::ExampleRef() {
9292
ExampleRef::~ExampleRef() {
9393
}
9494

95+
Array Example::get_godot_target_version() const {
96+
Array ret;
97+
ret.resize(3);
98+
ret[0] = GODOT_VERSION_MAJOR;
99+
ret[1] = GODOT_VERSION_MINOR;
100+
ret[2] = GODOT_VERSION_PATCH;
101+
return ret;
102+
}
103+
95104
int Example::test_static(int p_a, int p_b) {
96105
return p_a + p_b;
97106
}
@@ -182,6 +191,7 @@ void Example::_validate_property(PropertyInfo &p_property) const {
182191

183192
void Example::_bind_methods() {
184193
// Methods.
194+
ClassDB::bind_method(D_METHOD("get_godot_target_version"), &Example::get_godot_target_version);
185195
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
186196
ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
187197
ClassDB::bind_method(D_METHOD("custom_ref_func", "ref"), &Example::custom_ref_func);

test/src/example.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class Example : public Control {
108108
Example();
109109
~Example();
110110

111+
Array get_godot_target_version() const;
112+
111113
// Functions.
112114
void simple_func();
113115
void simple_const_func() const;

tools/godotcpp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def scons_generate_bindings(target, source, env):
176176
return None
177177

178178

179-
api_versions = ["4.5", "4.6"]
179+
api_versions = ["4.4", "4.5", "4.6"]
180180

181181
platforms = ["linux", "macos", "windows", "android", "ios", "web"]
182182

0 commit comments

Comments
 (0)