From 2afa3557b4402fc26d67f5461f1a67735964da7e Mon Sep 17 00:00:00 2001 From: David Snopek Date: Fri, 16 Feb 2024 14:40:04 -0600 Subject: [PATCH] Allow GDExtensions to set a compatibility_maximum --- core/extension/gdextension.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index fa4e7eb2e261..5a9941523f12 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -914,6 +914,35 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, return ERR_INVALID_DATA; } + // Optionally check maximum compatibility. + if (config->has_section_key("configuration", "compatibility_maximum")) { + uint32_t compatibility_maximum[3] = { 0, 0, 0 }; + String compat_string = config->get_value("configuration", "compatibility_maximum"); + Vector parts = compat_string.split_ints("."); + for (int i = 0; i < 3; i++) { + if (i < parts.size() && parts[i] >= 0) { + compatibility_maximum[i] = parts[i]; + } else { + // If a version part is missing, set the maximum to an arbitrary high value. + compatibility_maximum[i] = 9999; + } + } + + compatible = true; + if (VERSION_MAJOR != compatibility_maximum[0]) { + compatible = VERSION_MAJOR < compatibility_maximum[0]; + } else if (VERSION_MINOR != compatibility_maximum[1]) { + compatible = VERSION_MINOR < compatibility_maximum[1]; + } else { + compatible = VERSION_PATCH <= compatibility_maximum[2]; + } + + if (!compatible) { + ERR_PRINT(vformat("GDExtension only compatible with Godot version %s or earlier: %s", compat_string, p_path)); + return ERR_INVALID_DATA; + } + } + String library_path = GDExtension::find_extension_library(p_path, config, [](const String &p_feature) { return OS::get_singleton()->has_feature(p_feature); }); if (library_path.is_empty()) {