feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -96,8 +96,7 @@ static String fix_doc_description(const String &p_bbcode) {
|
|||
// Based on what EditorHelp does.
|
||||
|
||||
return p_bbcode.dedent()
|
||||
.replace("\t", "")
|
||||
.replace("\r", "")
|
||||
.remove_chars("\t\r")
|
||||
.strip_edges();
|
||||
}
|
||||
|
||||
|
|
@ -107,16 +106,22 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
{
|
||||
//header
|
||||
Dictionary header;
|
||||
header["version_major"] = VERSION_MAJOR;
|
||||
header["version_minor"] = VERSION_MINOR;
|
||||
#if VERSION_PATCH
|
||||
header["version_patch"] = VERSION_PATCH;
|
||||
header["version_major"] = GODOT_VERSION_MAJOR;
|
||||
header["version_minor"] = GODOT_VERSION_MINOR;
|
||||
#if GODOT_VERSION_PATCH
|
||||
header["version_patch"] = GODOT_VERSION_PATCH;
|
||||
#else
|
||||
header["version_patch"] = 0;
|
||||
#endif
|
||||
header["version_status"] = VERSION_STATUS;
|
||||
header["version_build"] = VERSION_BUILD;
|
||||
header["version_full_name"] = VERSION_FULL_NAME;
|
||||
header["version_status"] = GODOT_VERSION_STATUS;
|
||||
header["version_build"] = GODOT_VERSION_BUILD;
|
||||
header["version_full_name"] = GODOT_VERSION_FULL_NAME;
|
||||
|
||||
#if REAL_T_IS_DOUBLE
|
||||
header["precision"] = "double";
|
||||
#else
|
||||
header["precision"] = "single";
|
||||
#endif
|
||||
|
||||
api_dump["header"] = header;
|
||||
}
|
||||
|
|
@ -278,43 +283,43 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
#define REAL_MEMBER_OFFSET(type, member) \
|
||||
{ \
|
||||
type, \
|
||||
member, \
|
||||
"float", \
|
||||
sizeof(float), \
|
||||
"float", \
|
||||
sizeof(float), \
|
||||
"double", \
|
||||
sizeof(double), \
|
||||
"double", \
|
||||
sizeof(double), \
|
||||
member, \
|
||||
"float", \
|
||||
sizeof(float), \
|
||||
"float", \
|
||||
sizeof(float), \
|
||||
"double", \
|
||||
sizeof(double), \
|
||||
"double", \
|
||||
sizeof(double), \
|
||||
}
|
||||
|
||||
#define INT32_MEMBER_OFFSET(type, member) \
|
||||
{ \
|
||||
type, \
|
||||
member, \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
member, \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
"int32", \
|
||||
sizeof(int32_t), \
|
||||
}
|
||||
|
||||
#define INT32_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \
|
||||
{ \
|
||||
type, \
|
||||
member, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
member_type, \
|
||||
sizeof(int32_t) * member_elems, \
|
||||
}
|
||||
|
||||
#define REAL_BASED_BUILTIN_MEMBER_OFFSET(type, member, member_type, member_elems) \
|
||||
|
|
@ -970,14 +975,14 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
Array values;
|
||||
List<StringName> enum_constant_list;
|
||||
ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true);
|
||||
for (List<StringName>::Element *G = enum_constant_list.front(); G; G = G->next()) {
|
||||
for (const StringName &enum_constant : enum_constant_list) {
|
||||
Dictionary d3;
|
||||
d3["name"] = String(G->get());
|
||||
d3["value"] = ClassDB::get_integer_constant(class_name, G->get());
|
||||
d3["name"] = String(enum_constant);
|
||||
d3["value"] = ClassDB::get_integer_constant(class_name, enum_constant);
|
||||
|
||||
if (p_include_docs) {
|
||||
for (const DocData::ConstantDoc &constant_doc : class_doc->constants) {
|
||||
if (constant_doc.name == G->get()) {
|
||||
if (constant_doc.name == enum_constant) {
|
||||
d3["description"] = fix_doc_description(constant_doc.description);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1048,9 +1053,8 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
}
|
||||
|
||||
Array arguments;
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = mi.arguments.begin(); itr != mi.arguments.end(); ++itr, ++i) {
|
||||
const PropertyInfo &pinfo = *itr;
|
||||
for (int64_t i = 0; i < mi.arguments.size(); ++i) {
|
||||
const PropertyInfo &pinfo = mi.arguments[i];
|
||||
Dictionary d3;
|
||||
|
||||
d3["name"] = pinfo.name;
|
||||
|
|
@ -1175,11 +1179,10 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
|||
|
||||
Array arguments;
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = F.arguments.begin(); itr != F.arguments.end(); ++itr, ++i) {
|
||||
for (int64_t i = 0; i < F.arguments.size(); ++i) {
|
||||
Dictionary d3;
|
||||
d3["name"] = itr->name;
|
||||
d3["type"] = get_property_info_type_name(*itr);
|
||||
d3["name"] = F.arguments[i].name;
|
||||
d3["type"] = get_property_info_type_name(F.arguments[i]);
|
||||
if (F.get_argument_meta(i) > 0) {
|
||||
d3["meta"] = get_type_meta_name((GodotTypeInfo::Metadata)F.get_argument_meta(i));
|
||||
}
|
||||
|
|
@ -1340,16 +1343,16 @@ static bool compare_value(const String &p_path, const String &p_field, const Var
|
|||
} else if (p_old_value.get_type() == Variant::DICTIONARY && p_new_value.get_type() == Variant::DICTIONARY) {
|
||||
Dictionary old_dict = p_old_value;
|
||||
Dictionary new_dict = p_new_value;
|
||||
for (const Variant &key : old_dict.keys()) {
|
||||
if (!new_dict.has(key)) {
|
||||
for (const KeyValue<Variant, Variant> &kv : old_dict) {
|
||||
if (!new_dict.has(kv.key)) {
|
||||
failed = true;
|
||||
print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, key));
|
||||
print_error(vformat("Validate extension JSON: Error: Field '%s': %s was removed.", p_path, kv.key));
|
||||
continue;
|
||||
}
|
||||
if (p_allow_name_change && key == "name") {
|
||||
if (p_allow_name_change && kv.key == "name") {
|
||||
continue;
|
||||
}
|
||||
if (!compare_value(path, key, old_dict[key], new_dict[key], p_allow_name_change)) {
|
||||
if (!compare_value(path, kv.key, kv.value, new_dict[kv.key], p_allow_name_change)) {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1420,25 +1423,25 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_
|
|||
bool optional = field.begins_with("*");
|
||||
if (optional) {
|
||||
// This is an optional field, but if exists it has to exist in both.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
bool added = field.begins_with("+");
|
||||
if (added) {
|
||||
// Meaning this field must either exist or contents may not exist.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
bool enum_values = field.begins_with("$");
|
||||
if (enum_values) {
|
||||
// Meaning this field is a list of enum values.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
bool allow_name_change = field.begins_with("@");
|
||||
if (allow_name_change) {
|
||||
// Meaning that when structurally comparing the old and new value, the dictionary entry 'name' may change.
|
||||
field = field.substr(1, field.length());
|
||||
field = field.substr(1);
|
||||
}
|
||||
|
||||
Variant old_value;
|
||||
|
|
@ -1598,8 +1601,8 @@ Error GDExtensionAPIDump::validate_extension_json_file(const String &p_path) {
|
|||
int major = header["version_major"];
|
||||
int minor = header["version_minor"];
|
||||
|
||||
ERR_FAIL_COND_V_MSG(major != VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, VERSION_MAJOR));
|
||||
ERR_FAIL_COND_V_MSG(minor > VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor));
|
||||
ERR_FAIL_COND_V_MSG(major != GODOT_VERSION_MAJOR, ERR_INVALID_DATA, vformat("JSON API dump is for a different engine version (%d) than this one (%d)", major, GODOT_VERSION_MAJOR));
|
||||
ERR_FAIL_COND_V_MSG(minor > GODOT_VERSION_MINOR, ERR_INVALID_DATA, vformat("JSON API dump is for a newer version of the engine: %d.%d", major, minor));
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EXTENSION_API_DUMP_H
|
||||
#define EXTENSION_API_DUMP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension.h"
|
||||
|
||||
|
|
@ -42,5 +41,3 @@ public:
|
|||
static Error validate_extension_json_file(const String &p_path);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // EXTENSION_API_DUMP_H
|
||||
|
|
|
|||
|
|
@ -679,6 +679,13 @@ void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExte
|
|||
memnew_placement(r_path, String(library_path));
|
||||
}
|
||||
|
||||
void GDExtension::_register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
GDExtension *self = reinterpret_cast<GDExtension *>(p_library);
|
||||
self->get_classes_used_callback = p_callback;
|
||||
#endif
|
||||
}
|
||||
|
||||
HashMap<StringName, GDExtensionInterfaceFunctionPtr> GDExtension::gdextension_interface_functions;
|
||||
|
||||
void GDExtension::register_interface_function(const StringName &p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) {
|
||||
|
|
@ -799,6 +806,7 @@ void GDExtension::initialize_gdextensions() {
|
|||
register_interface_function("classdb_register_extension_class_signal", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_signal);
|
||||
register_interface_function("classdb_unregister_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_unregister_extension_class);
|
||||
register_interface_function("get_library_path", (GDExtensionInterfaceFunctionPtr)&GDExtension::_get_library_path);
|
||||
register_interface_function("editor_register_get_classes_used_callback", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_get_classes_used_callback);
|
||||
}
|
||||
|
||||
void GDExtension::finalize_gdextensions() {
|
||||
|
|
@ -1034,6 +1042,14 @@ void GDExtension::_untrack_instance(void *p_user_data, void *p_instance) {
|
|||
extension->instances.erase(obj->get_instance_id());
|
||||
}
|
||||
|
||||
PackedStringArray GDExtension::get_classes_used() const {
|
||||
PackedStringArray ret;
|
||||
if (get_classes_used_callback) {
|
||||
get_classes_used_callback((GDExtensionTypePtr)&ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Vector<StringName> GDExtensionEditorPlugins::extension_classes;
|
||||
GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_add_plugin = nullptr;
|
||||
GDExtensionEditorPlugins::EditorPluginRegisterFunc GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_H
|
||||
#define GDEXTENSION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension_interface.h"
|
||||
#include "core/extension/gdextension_loader.h"
|
||||
|
|
@ -94,6 +93,7 @@ class GDExtension : public Resource {
|
|||
static void _register_extension_class_signal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count);
|
||||
static void _unregister_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name);
|
||||
static void _get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path);
|
||||
static void _register_get_classes_used_callback(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback);
|
||||
|
||||
GDExtensionInitialization initialization;
|
||||
int32_t level_initialized = -1;
|
||||
|
|
@ -102,6 +102,7 @@ class GDExtension : public Resource {
|
|||
bool is_reloading = false;
|
||||
Vector<GDExtensionMethodBind *> invalid_methods;
|
||||
Vector<ObjectID> instance_bindings;
|
||||
GDExtensionEditorGetClassesUsedCallback get_classes_used_callback = nullptr;
|
||||
|
||||
static void _track_instance(void *p_user_data, void *p_instance);
|
||||
static void _untrack_instance(void *p_user_data, void *p_instance);
|
||||
|
|
@ -156,6 +157,8 @@ public:
|
|||
|
||||
void track_instance_binding(Object *p_object);
|
||||
void untrack_instance_binding(Object *p_object);
|
||||
|
||||
PackedStringArray get_classes_used() const;
|
||||
#endif
|
||||
|
||||
InitializationLevel get_minimum_library_initialization_level() const;
|
||||
|
|
@ -226,5 +229,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
#endif // GDEXTENSION_H
|
||||
|
|
|
|||
|
|
@ -241,11 +241,25 @@ GDExtensionInterfaceFunctionPtr gdextension_get_proc_address(const char *p_name)
|
|||
return GDExtension::get_interface_function(p_name);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
static void gdextension_get_godot_version(GDExtensionGodotVersion *r_godot_version) {
|
||||
r_godot_version->major = VERSION_MAJOR;
|
||||
r_godot_version->minor = VERSION_MINOR;
|
||||
r_godot_version->patch = VERSION_PATCH;
|
||||
r_godot_version->string = VERSION_FULL_NAME;
|
||||
r_godot_version->major = GODOT_VERSION_MAJOR;
|
||||
r_godot_version->minor = GODOT_VERSION_MINOR;
|
||||
r_godot_version->patch = GODOT_VERSION_PATCH;
|
||||
r_godot_version->string = GODOT_VERSION_FULL_NAME;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gdextension_get_godot_version2(GDExtensionGodotVersion2 *r_godot_version) {
|
||||
r_godot_version->major = GODOT_VERSION_MAJOR;
|
||||
r_godot_version->minor = GODOT_VERSION_MINOR;
|
||||
r_godot_version->patch = GODOT_VERSION_PATCH;
|
||||
r_godot_version->hex = GODOT_VERSION_HEX;
|
||||
r_godot_version->status = GODOT_VERSION_STATUS;
|
||||
r_godot_version->build = GODOT_VERSION_BUILD;
|
||||
r_godot_version->hash = GODOT_VERSION_HASH;
|
||||
r_godot_version->timestamp = GODOT_VERSION_TIMESTAMP;
|
||||
r_godot_version->string = GODOT_VERSION_FULL_NAME;
|
||||
}
|
||||
|
||||
// Memory Functions
|
||||
|
|
@ -858,84 +872,82 @@ static GDExtensionPtrUtilityFunction gdextension_variant_get_ptr_utility_functio
|
|||
//string helpers
|
||||
|
||||
static void gdextension_string_new_with_latin1_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) {
|
||||
memnew_placement(r_dest, String(p_contents));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_latin1(Span<char>(p_contents, p_contents ? strlen(p_contents) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf8(p_contents);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf8(p_contents);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16(p_contents);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16(p_contents);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) {
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf32(Span(p_contents, p_contents ? strlen(p_contents) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_wide_chars(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents) {
|
||||
if constexpr (sizeof(wchar_t) == 2) {
|
||||
// wchar_t is 16 bit, parse.
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16((const char16_t *)p_contents);
|
||||
// wchar_t is 16 bit (UTF-16).
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16((const char16_t *)p_contents);
|
||||
} else {
|
||||
// wchar_t is 32 bit, copy.
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents));
|
||||
// wchar_t is 32 bit (UTF-32).
|
||||
String *string = memnew_placement(r_dest, String);
|
||||
string->append_utf32(Span((const char32_t *)p_contents, p_contents ? strlen(p_contents) : 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
memnew_placement(r_dest, String(p_contents, p_size));
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_latin1(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_size) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf8(p_contents, p_size);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf8(p_contents, p_size);
|
||||
}
|
||||
|
||||
static GDExtensionInt gdextension_string_new_with_utf8_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
return (GDExtensionInt)dest->parse_utf8(p_contents, p_size);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
return (GDExtensionInt)dest->append_utf8(p_contents, p_size);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16(p_contents, p_char_count);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16(p_contents, p_char_count);
|
||||
}
|
||||
|
||||
static GDExtensionInt gdextension_string_new_with_utf16_chars_and_len2(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian) {
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
return (GDExtensionInt)dest->parse_utf16(p_contents, p_char_count, p_default_little_endian);
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
return (GDExtensionInt)dest->append_utf16(p_contents, p_char_count, p_default_little_endian);
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count) {
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count));
|
||||
String *string = memnew_placement(r_dest, String);
|
||||
string->append_utf32(Span(p_contents, p_contents ? _strlen_clipped(p_contents, p_char_count) : 0));
|
||||
}
|
||||
|
||||
static void gdextension_string_new_with_wide_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count) {
|
||||
if constexpr (sizeof(wchar_t) == 2) {
|
||||
// wchar_t is 16 bit, parse.
|
||||
memnew_placement(r_dest, String);
|
||||
String *dest = reinterpret_cast<String *>(r_dest);
|
||||
dest->parse_utf16((const char16_t *)p_contents, p_char_count);
|
||||
// wchar_t is 16 bit (UTF-16).
|
||||
String *dest = memnew_placement(r_dest, String);
|
||||
dest->append_utf16((const char16_t *)p_contents, p_char_count);
|
||||
} else {
|
||||
// wchar_t is 32 bit, copy.
|
||||
memnew_placement(r_dest, String((const char32_t *)p_contents, p_char_count));
|
||||
// wchar_t is 32 bit (UTF-32).
|
||||
String *string = memnew_placement(r_dest, String);
|
||||
string->append_utf32(Span((const char32_t *)p_contents, p_contents ? _strlen_clipped((const char32_t *)p_contents, p_char_count) : 0));
|
||||
}
|
||||
}
|
||||
|
||||
static GDExtensionInt gdextension_string_to_latin1_chars(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length) {
|
||||
String *self = (String *)p_self;
|
||||
CharString cs = self->ascii(true);
|
||||
CharString cs = self->latin1();
|
||||
GDExtensionInt len = cs.length();
|
||||
if (r_text) {
|
||||
const char *s_text = cs.ptr();
|
||||
|
|
@ -1040,16 +1052,12 @@ static void gdextension_string_name_new_with_latin1_chars(GDExtensionUninitializ
|
|||
}
|
||||
|
||||
static void gdextension_string_name_new_with_utf8_chars(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents) {
|
||||
String tmp;
|
||||
tmp.parse_utf8(p_contents);
|
||||
|
||||
String tmp = String::utf8(p_contents);
|
||||
memnew_placement(r_dest, StringName(tmp));
|
||||
}
|
||||
|
||||
static void gdextension_string_name_new_with_utf8_chars_and_len(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size) {
|
||||
String tmp;
|
||||
tmp.parse_utf8(p_contents, p_size);
|
||||
|
||||
String tmp = String::utf8(p_contents, p_size);
|
||||
memnew_placement(r_dest, StringName(tmp));
|
||||
}
|
||||
|
||||
|
|
@ -1543,11 +1551,8 @@ static void gdextension_placeholder_script_instance_update(GDExtensionScriptInst
|
|||
properties_list.push_back(PropertyInfo::from_dict(d));
|
||||
}
|
||||
|
||||
List<Variant> keys;
|
||||
values.get_key_list(&keys);
|
||||
|
||||
for (const Variant &E : keys) {
|
||||
values_map.insert(E, values[E]);
|
||||
for (const KeyValue<Variant, Variant> &kv : values) {
|
||||
values_map.insert(kv.key, kv.value);
|
||||
}
|
||||
|
||||
placeholder->update(properties_list, values_map);
|
||||
|
|
@ -1572,6 +1577,15 @@ static GDExtensionScriptInstancePtr gdextension_object_get_script_instance(GDExt
|
|||
return script_instance_extension->instance;
|
||||
}
|
||||
|
||||
static void gdextension_object_set_script_instance(GDExtensionObjectPtr p_object, GDExtensionScriptInstancePtr p_script_instance) {
|
||||
ERR_FAIL_NULL(p_object);
|
||||
|
||||
Object *o = (Object *)p_object;
|
||||
ScriptInstance *script_instance = (ScriptInstanceExtension *)p_script_instance;
|
||||
|
||||
o->set_script_instance(script_instance);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
static void gdextension_callable_custom_create(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_custom_callable_info) {
|
||||
memnew_placement(r_callable, Callable(memnew(CallableCustomExtension(p_custom_callable_info))));
|
||||
|
|
@ -1666,7 +1680,10 @@ static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data)
|
|||
#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr) & gdextension_##m_name)
|
||||
|
||||
void gdextension_setup_interface() {
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
REGISTER_INTERFACE_FUNC(get_godot_version);
|
||||
#endif // DISABLE_DEPRECATED
|
||||
REGISTER_INTERFACE_FUNC(get_godot_version2);
|
||||
REGISTER_INTERFACE_FUNC(mem_alloc);
|
||||
REGISTER_INTERFACE_FUNC(mem_realloc);
|
||||
REGISTER_INTERFACE_FUNC(mem_free);
|
||||
|
|
@ -1809,6 +1826,7 @@ void gdextension_setup_interface() {
|
|||
REGISTER_INTERFACE_FUNC(placeholder_script_instance_create);
|
||||
REGISTER_INTERFACE_FUNC(placeholder_script_instance_update);
|
||||
REGISTER_INTERFACE_FUNC(object_get_script_instance);
|
||||
REGISTER_INTERFACE_FUNC(object_set_script_instance);
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
REGISTER_INTERFACE_FUNC(callable_custom_create);
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_INTERFACE_H
|
||||
#define GDEXTENSION_INTERFACE_H
|
||||
#pragma once
|
||||
|
||||
/* This is a C class header, you can copy it and use it directly in your own binders.
|
||||
* Together with the JSON file, you should be able to generate any binder.
|
||||
|
|
@ -401,6 +400,9 @@ typedef struct {
|
|||
|
||||
typedef void *GDExtensionClassLibraryPtr;
|
||||
|
||||
/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */
|
||||
typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array);
|
||||
|
||||
/* Method */
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -790,9 +792,22 @@ typedef struct {
|
|||
const char *string;
|
||||
} GDExtensionGodotVersion;
|
||||
|
||||
typedef struct {
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t patch;
|
||||
uint32_t hex; // Full version encoded as hexadecimal with one byte (2 hex digits) per number (e.g. for "3.1.12" it would be 0x03010C)
|
||||
const char *status; // (e.g. "stable", "beta", "rc1", "rc2")
|
||||
const char *build; // (e.g. "custom_build")
|
||||
const char *hash; // Full Git commit hash.
|
||||
uint64_t timestamp; // Git commit date UNIX timestamp in seconds, or 0 if unavailable.
|
||||
const char *string; // (e.g. "Godot v3.1.4.stable.official.mono")
|
||||
} GDExtensionGodotVersion2;
|
||||
|
||||
/**
|
||||
* @name get_godot_version
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.5. Use `get_godot_version2` instead.
|
||||
*
|
||||
* Gets the Godot version that the GDExtension was loaded into.
|
||||
*
|
||||
|
|
@ -800,6 +815,16 @@ typedef struct {
|
|||
*/
|
||||
typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_godot_version);
|
||||
|
||||
/**
|
||||
* @name get_godot_version2
|
||||
* @since 4.5
|
||||
*
|
||||
* Gets the Godot version that the GDExtension was loaded into.
|
||||
*
|
||||
* @param r_godot_version A pointer to the structure to write the version information into.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceGetGodotVersion2)(GDExtensionGodotVersion2 *r_godot_version);
|
||||
|
||||
/* INTERFACE: Memory */
|
||||
|
||||
/**
|
||||
|
|
@ -2721,6 +2746,17 @@ typedef void (*GDExtensionInterfacePlaceHolderScriptInstanceUpdate)(GDExtensionS
|
|||
*/
|
||||
typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptInstance)(GDExtensionConstObjectPtr p_object, GDExtensionObjectPtr p_language);
|
||||
|
||||
/**
|
||||
* @name object_set_script_instance
|
||||
* @since 4.5
|
||||
*
|
||||
* Set the script instance data attached to this object.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_script_instance A pointer to the script instance data to attach to this object.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceObjectSetScriptInstance)(GDExtensionObjectPtr p_object, GDExtensionScriptInstanceDataPtr p_script_instance);
|
||||
|
||||
/* INTERFACE: Callable */
|
||||
|
||||
/**
|
||||
|
|
@ -3078,8 +3114,22 @@ typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *
|
|||
*/
|
||||
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
|
||||
|
||||
/**
|
||||
* @name editor_register_get_classes_used_callback
|
||||
* @since 4.5
|
||||
*
|
||||
* Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension.
|
||||
*
|
||||
* This is used by the editor to generate a build profile (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"),
|
||||
* in order to recompile Godot with only the classes used.
|
||||
* In the provided callback, the GDExtension should provide the list of classes that _may_ be used statically, thus the time of invocation shouldn't matter.
|
||||
* If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_callback The callback to retrieve the list of classes used.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GDEXTENSION_INTERFACE_H
|
||||
|
|
|
|||
|
|
@ -307,12 +307,12 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) {
|
|||
|
||||
bool compatible = true;
|
||||
// Check version lexicographically.
|
||||
if (VERSION_MAJOR != compatibility_minimum[0]) {
|
||||
compatible = VERSION_MAJOR > compatibility_minimum[0];
|
||||
} else if (VERSION_MINOR != compatibility_minimum[1]) {
|
||||
compatible = VERSION_MINOR > compatibility_minimum[1];
|
||||
if (GODOT_VERSION_MAJOR != compatibility_minimum[0]) {
|
||||
compatible = GODOT_VERSION_MAJOR > compatibility_minimum[0];
|
||||
} else if (GODOT_VERSION_MINOR != compatibility_minimum[1]) {
|
||||
compatible = GODOT_VERSION_MINOR > compatibility_minimum[1];
|
||||
} else {
|
||||
compatible = VERSION_PATCH >= compatibility_minimum[2];
|
||||
compatible = GODOT_VERSION_PATCH >= compatibility_minimum[2];
|
||||
}
|
||||
if (!compatible) {
|
||||
ERR_PRINT(vformat("GDExtension only compatible with Godot version %d.%d.%d or later: %s", compatibility_minimum[0], compatibility_minimum[1], compatibility_minimum[2], p_path));
|
||||
|
|
@ -334,15 +334,15 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) {
|
|||
}
|
||||
|
||||
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];
|
||||
if (GODOT_VERSION_MAJOR != compatibility_maximum[0]) {
|
||||
compatible = GODOT_VERSION_MAJOR < compatibility_maximum[0];
|
||||
} else if (GODOT_VERSION_MINOR != compatibility_maximum[1]) {
|
||||
compatible = GODOT_VERSION_MINOR < compatibility_maximum[1];
|
||||
}
|
||||
#if VERSION_PATCH
|
||||
#if GODOT_VERSION_PATCH
|
||||
// #if check to avoid -Wtype-limits warning when 0.
|
||||
else {
|
||||
compatible = VERSION_PATCH <= compatibility_maximum[2];
|
||||
compatible = GODOT_VERSION_PATCH <= compatibility_maximum[2];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_LIBRARY_LOADER_H
|
||||
#define GDEXTENSION_LIBRARY_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
|
@ -38,6 +37,8 @@
|
|||
#include "core/os/shared_object.h"
|
||||
|
||||
class GDExtensionLibraryLoader : public GDExtensionLoader {
|
||||
GDSOFTCLASS(GDExtensionLibraryLoader, GDExtensionLoader);
|
||||
|
||||
friend class GDExtensionManager;
|
||||
friend class GDExtension;
|
||||
|
||||
|
|
@ -81,5 +82,3 @@ public:
|
|||
|
||||
Error parse_gdextension_file(const String &p_path);
|
||||
};
|
||||
|
||||
#endif // GDEXTENSION_LIBRARY_LOADER_H
|
||||
|
|
|
|||
|
|
@ -28,14 +28,15 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_LOADER_H
|
||||
#define GDEXTENSION_LOADER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
class GDExtension;
|
||||
|
||||
class GDExtensionLoader : public RefCounted {
|
||||
GDSOFTCLASS(GDExtensionLoader, GDExtensionLoader);
|
||||
|
||||
public:
|
||||
virtual Error open_library(const String &p_path) = 0;
|
||||
virtual Error initialize(GDExtensionInterfaceGetProcAddress p_get_proc_address, const Ref<GDExtension> &p_extension, GDExtensionInitialization *r_initialization) = 0;
|
||||
|
|
@ -44,5 +45,3 @@ public:
|
|||
virtual bool has_library_changed() const = 0;
|
||||
virtual bool library_exists() const = 0;
|
||||
};
|
||||
|
||||
#endif // GDEXTENSION_LOADER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_MANAGER_H
|
||||
#define GDEXTENSION_MANAGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/extension/gdextension.h"
|
||||
|
||||
|
|
@ -92,5 +91,3 @@ public:
|
|||
};
|
||||
|
||||
VARIANT_ENUM_CAST(GDExtensionManager::LoadStatus)
|
||||
|
||||
#endif // GDEXTENSION_MANAGER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
#define GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
#pragma once
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
|
|
@ -58,5 +57,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
#endif // GDEXTENSION_SPECIAL_COMPAT_HASHES_H
|
||||
|
|
|
|||
|
|
@ -1,55 +1,37 @@
|
|||
import zlib
|
||||
import methods
|
||||
|
||||
|
||||
def run(target, source, env):
|
||||
src = str(source[0])
|
||||
dst = str(target[0])
|
||||
with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g:
|
||||
buf = f.read()
|
||||
decomp_size = len(buf)
|
||||
|
||||
# Use maximum zlib compression level to further reduce file size
|
||||
# (at the cost of initial build times).
|
||||
buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
|
||||
|
||||
g.write(
|
||||
"""/* THIS FILE IS GENERATED DO NOT EDIT */
|
||||
#ifndef GDEXTENSION_INTERFACE_DUMP_H
|
||||
#define GDEXTENSION_INTERFACE_DUMP_H
|
||||
buffer = methods.get_buffer(str(source[0]))
|
||||
decomp_size = len(buffer)
|
||||
buffer = methods.compress_buffer(buffer)
|
||||
|
||||
with methods.generated_wrapper(str(target[0])) as file:
|
||||
file.write(f"""\
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#include "core/io/compression.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
"""
|
||||
)
|
||||
inline constexpr int _gdextension_interface_data_compressed_size = {len(buffer)};
|
||||
inline constexpr int _gdextension_interface_data_uncompressed_size = {decomp_size};
|
||||
inline constexpr unsigned char _gdextension_interface_data_compressed[] = {{
|
||||
{methods.format_buffer(buffer, 1)}
|
||||
}};
|
||||
|
||||
g.write("static const int _gdextension_interface_data_compressed_size = " + str(len(buf)) + ";\n")
|
||||
g.write("static const int _gdextension_interface_data_uncompressed_size = " + str(decomp_size) + ";\n")
|
||||
g.write("static const unsigned char _gdextension_interface_data_compressed[] = {\n")
|
||||
for i in range(len(buf)):
|
||||
g.write("\t" + str(buf[i]) + ",\n")
|
||||
g.write("};\n")
|
||||
|
||||
g.write(
|
||||
"""
|
||||
class GDExtensionInterfaceDump {
|
||||
public:
|
||||
static void generate_gdextension_interface_file(const String &p_path) {
|
||||
Ref<FileAccess> fa = FileAccess::open(p_path, FileAccess::WRITE);
|
||||
ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path));
|
||||
Vector<uint8_t> data;
|
||||
data.resize(_gdextension_interface_data_uncompressed_size);
|
||||
int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE);
|
||||
ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt.");
|
||||
fa->store_buffer(data.ptr(), data.size());
|
||||
};
|
||||
};
|
||||
class GDExtensionInterfaceDump {{
|
||||
public:
|
||||
static void generate_gdextension_interface_file(const String &p_path) {{
|
||||
Ref<FileAccess> fa = FileAccess::open(p_path, FileAccess::WRITE);
|
||||
ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path));
|
||||
Vector<uint8_t> data;
|
||||
data.resize(_gdextension_interface_data_uncompressed_size);
|
||||
int ret = Compression::decompress(data.ptrw(), _gdextension_interface_data_uncompressed_size, _gdextension_interface_data_compressed, _gdextension_interface_data_compressed_size, Compression::MODE_DEFLATE);
|
||||
ERR_FAIL_COND_MSG(ret == -1, "Compressed file is corrupt.");
|
||||
fa->store_buffer(data.ptr(), data.size());
|
||||
}};
|
||||
}};
|
||||
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
#endif // GDEXTENSION_INTERFACE_DUMP_H
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
|
|
|||
|
|
@ -119,10 +119,7 @@ def generate_ex_version(argcount, const=False, returns=False):
|
|||
def run(target, source, env):
|
||||
max_versions = 12
|
||||
|
||||
txt = """
|
||||
#ifndef GDEXTENSION_WRAPPERS_GEN_H
|
||||
#define GDEXTENSION_WRAPPERS_GEN_H
|
||||
"""
|
||||
txt = "#pragma once"
|
||||
|
||||
for i in range(max_versions + 1):
|
||||
txt += "\n/* Extension Wrapper " + str(i) + " Arguments */\n"
|
||||
|
|
@ -138,7 +135,5 @@ def run(target, source, env):
|
|||
txt += generate_mod_version(i, True, False)
|
||||
txt += generate_mod_version(i, True, True)
|
||||
|
||||
txt += "\n#endif\n"
|
||||
|
||||
with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(txt)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue