Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2099,11 +2099,20 @@ def generate_version_header(api, output_dir):
header.append(f"#define {header_guard}")
header.append("")

header.append(f"#define REDOT_VERSION_MAJOR {api['redot_header']['version_major']}")
header.append(f"#define REDOT_VERSION_MINOR {api['redot_header']['version_minor']}")
header.append(f"#define REDOT_VERSION_PATCH {api['redot_header']['version_patch']}")
header.append(f"#define REDOT_VERSION_STATUS \"{api['redot_header']['version_status']}\"")
header.append(f"#define REDOT_VERSION_STATUS_VERSION {api['redot_header']['version_status_version']}")
header.append(f"#define REDOT_VERSION_BUILD \"{api['redot_header']['version_build']}\"")

header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}")
header.append(f"#define GODOT_VERSION_MINOR {api['header']['version_minor']}")
header.append(f"#define GODOT_VERSION_PATCH {api['header']['version_patch']}")
header.append(f"#define GODOT_VERSION_STATUS \"{api['header']['version_status']}\"")
header.append(f"#define GODOT_VERSION_STATUS_VERSION \"{api['header']['version_status_version']}\"")
header.append(
f"#define GODOT_VERSION_STATUS_VERSION {next(filter(str.isdigit, api['header']['version_status']), 0)}"
)
header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"")

header.append("")
Expand Down
10 changes: 9 additions & 1 deletion gdextension/extension_api.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"header": {
"redot_header": {
"version_major": 4,
"version_minor": 4,
"version_patch": 0,
Expand All @@ -8,6 +8,14 @@
"version_build": "custom_build",
"version_full_name": "Redot Engine v4.4.alpha.custom_build"
},
"header": {
"version_major": 4,
"version_minor": 3,
"version_patch": 1,
"version_status": "dev",
"version_build": "redot.custom_build",
"version_full_name": "Godot Engine v4.3.1.dev.redot.custom_build"
},
"builtin_class_sizes": [
{
"build_configuration": "float_32",
Expand Down
2 changes: 2 additions & 0 deletions include/godot_cpp/godot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ extern "C" GDExtensionClassLibraryPtr library;
extern "C" void *token;

extern "C" GDExtensionGodotVersion godot_version;
extern "C" GDExtensionRedotVersion redot_version;

// All of the GDExtension interface functions.
extern "C" GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version;
extern "C" GDExtensionInterfaceGetRedotVersion gdextension_interface_get_redot_version;
extern "C" GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc;
extern "C" GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc;
extern "C" GDExtensionInterfaceMemFree gdextension_interface_mem_free;
Expand Down
29 changes: 19 additions & 10 deletions src/godot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ GDExtensionClassLibraryPtr library = nullptr;
void *token = nullptr;

GDExtensionGodotVersion godot_version = { 0, 0, 0, nullptr };
GDExtensionRedotVersion redot_version = { 0, 0, 0, 0, nullptr, 0, nullptr, nullptr, 0, nullptr };

// All of the GDExtension interface functions.
GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version = nullptr;
GDExtensionInterfaceGetRedotVersion gdextension_interface_get_redot_version = nullptr;
GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc = nullptr;
GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc = nullptr;
GDExtensionInterfaceMemFree gdextension_interface_mem_free = nullptr;
Expand Down Expand Up @@ -310,16 +312,23 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion);
internal::gdextension_interface_get_godot_version(&internal::godot_version);

// Check that godot-cpp was compiled using an extension_api.json older or at the
// same version as the Godot that is loading it.
internal::gdextension_interface_get_redot_version = (GDExtensionInterfaceGetRedotVersion)p_get_proc_address("get_redot_version");
if (!internal::gdextension_interface_get_redot_version) {
ERR_PRINT_EARLY("Cannot load a GDExtension built for Redot using Godot or non-Redot derivative.");
return false;
}
internal::gdextension_interface_get_redot_version(&internal::redot_version);

// Check that redot-cpp was compiled using an extension_api.json older or at the
// same version as the Redot that is loading it.
bool compatible;
if (internal::godot_version.major != GODOT_VERSION_MAJOR) {
compatible = internal::godot_version.major > GODOT_VERSION_MAJOR;
} else if (internal::godot_version.minor != GODOT_VERSION_MINOR) {
compatible = internal::godot_version.minor > GODOT_VERSION_MINOR;
if (internal::redot_version.major != REDOT_VERSION_MAJOR) {
compatible = internal::redot_version.major > REDOT_VERSION_MAJOR;
} else if (internal::redot_version.minor != REDOT_VERSION_MINOR) {
compatible = internal::redot_version.minor > REDOT_VERSION_MINOR;
} else {
#if GODOT_VERSION_PATCH > 0
compatible = internal::godot_version.patch >= GODOT_VERSION_PATCH;
compatible = internal::redot_version.patch >= REDOT_VERSION_PATCH;
#else
// Prevent -Wtype-limits warning due to unsigned comparison.
compatible = true;
Expand All @@ -329,9 +338,9 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
// We need to use snprintf() here because vformat() uses Variant, and we haven't loaded
// the GDExtension interface far enough to use Variants yet.
char msg[128];
snprintf(msg, 128, "Cannot load a GDExtension built for Godot %d.%d.%d using an older version of Godot (%d.%d.%d).",
GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR, GODOT_VERSION_PATCH,
internal::godot_version.major, internal::godot_version.minor, internal::godot_version.patch);
snprintf(msg, 128, "Cannot load a GDExtension built for Redot %d.%d.%d using an older version of Redot (%d.%d.%d).",
REDOT_VERSION_MAJOR, REDOT_VERSION_MINOR, REDOT_VERSION_PATCH,
internal::redot_version.major, internal::redot_version.minor, internal::redot_version.patch);
ERR_PRINT_EARLY(msg);
return false;
}
Expand Down