From 163257d51bd103588da246d39ab5d10afaf15c09 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 25 Aug 2022 12:35:30 +0300 Subject: [PATCH] [GDExtension] Implement support for typed arrays. --- core/extension/extension_api_dump.cpp | 3 + core/variant/array.h | 2 +- core/variant/variant_call.cpp | 8 ++ core/variant/variant_construct.cpp | 1 + core/variant/variant_construct.h | 76 +++++++++++++++++++ doc/classes/Array.xml | 54 +++++++++++++ .../gdextension_build/SConstruct | 29 ++++++- modules/text_server_adv/text_server_adv.cpp | 4 +- modules/text_server_adv/text_server_adv.h | 3 +- .../gdextension_build/SConstruct | 20 +++++ modules/text_server_fb/text_server_fb.h | 1 + servers/text/text_server_extension.cpp | 4 +- servers/text/text_server_extension.h | 4 +- servers/text_server.h | 2 +- 14 files changed, 200 insertions(+), 11 deletions(-) diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index bda1a5cdc1c7..310817c95272 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -46,6 +46,9 @@ static String get_type_name(const PropertyInfo &p_info) { return p_info.hint_string + "*"; } } + if (p_info.type == Variant::ARRAY && (p_info.hint == PROPERTY_HINT_ARRAY_TYPE)) { + return String("typedarray::") + p_info.hint_string; + } if (p_info.type == Variant::INT && (p_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM))) { return String("enum::") + String(p_info.class_name); } diff --git a/core/variant/array.h b/core/variant/array.h index c0073767346e..3d9a7949693e 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -47,7 +47,6 @@ class Array { void _unref() const; protected: - Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); bool _assign(const Array &p_array); public: @@ -131,6 +130,7 @@ class Array { void set_read_only(bool p_enable); bool is_read_only() const; + Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); Array(const Array &p_from); Array(); ~Array(); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index f09885b32507..2501d9fd4490 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -2065,6 +2065,14 @@ static void _register_variant_builtin_methods() { bind_method(Array, all, sarray("method"), varray()); bind_method(Array, max, sarray(), varray()); bind_method(Array, min, sarray(), varray()); + bind_method(Array, typed_assign, sarray("array"), varray()); + bind_method(Array, set_typed, sarray("type", "class_name", "script"), varray()); + bind_method(Array, is_typed, sarray(), varray()); + bind_method(Array, get_typed_builtin, sarray(), varray()); + bind_method(Array, get_typed_class_name, sarray(), varray()); + bind_method(Array, get_typed_script, sarray(), varray()); + bind_method(Array, set_read_only, sarray("enable"), varray()); + bind_method(Array, is_read_only, sarray(), varray()); /* Byte Array */ bind_method(PackedByteArray, size, sarray(), varray()); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index d048f4573764..3b88dc11ca5e 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -200,6 +200,7 @@ void Variant::_register_variant_constructors() { add_constructor>(sarray()); add_constructor>(sarray("from")); + add_constructor(sarray("base", "type", "class_name", "script")); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("from")); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index 58a0f34c1e84..34d228f4d296 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -336,6 +336,82 @@ class VariantConstructorSignalArgs { } }; +class VariantConstructorTypedArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::ARRAY; + return; + } + + if (p_args[1]->get_type() != Variant::INT) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::INT; + return; + } + + if (p_args[2]->get_type() != Variant::STRING_NAME) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 2; + r_error.expected = Variant::STRING_NAME; + return; + } + + const Array &base_arr = *VariantGetInternalPtr::get_ptr(p_args[0]); + const uint32_t type = p_args[1]->operator uint32_t(); + const StringName &class_name = *VariantGetInternalPtr::get_ptr(p_args[2]); + r_ret = Array(base_arr, type, class_name, *p_args[3]); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + const Array &base_arr = *VariantGetInternalPtr::get_ptr(p_args[0]); + const uint32_t type = p_args[1]->operator uint32_t(); + const StringName &class_name = *VariantGetInternalPtr::get_ptr(p_args[2]); + *r_ret = Array(base_arr, type, class_name, *p_args[3]); + } + + static void ptr_construct(void *base, const void **p_args) { + const Array &base_arr = PtrToArg::convert(p_args[0]); + const uint32_t type = PtrToArg::convert(p_args[1]); + const StringName &class_name = PtrToArg::convert(p_args[2]); + const Variant &script = PtrToArg::convert(p_args[3]); + Array dst_arr = Array(base_arr, type, class_name, script); + + PtrConstruct::construct(dst_arr, base); + } + + static int get_argument_count() { + return 4; + } + + static Variant::Type get_argument_type(int p_arg) { + switch (p_arg) { + case 0: { + return Variant::ARRAY; + } break; + case 1: { + return Variant::INT; + } break; + case 2: { + return Variant::STRING_NAME; + } break; + case 3: { + return Variant::NIL; + } break; + default: { + return Variant::NIL; + } break; + } + } + + static Variant::Type get_base_type() { + return Variant::ARRAY; + } +}; + template class VariantConstructorToArray { public: diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index f6d926031d93..d8c4b8fdb595 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -51,6 +51,15 @@ Constructs an empty [Array]. + + + + + + + + + @@ -303,6 +312,21 @@ [b]Note:[/b] Calling this function is not the same as writing [code]array[0][/code]. If the array is empty, accessing by index will pause project execution when running from the editor. + + + + + + + + + + + + + + + @@ -366,6 +390,16 @@ Returns [code]true[/code] if the array is empty. + + + + + + + + + + @@ -479,6 +513,20 @@ Searches the array in reverse order. Optionally, a start search index can be passed. If negative, the start index is considered relative to the end of the array. + + + + + + + + + + + + + + @@ -556,6 +604,12 @@ [/codeblocks] + + + + + + diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 0170c007ae3f..488d1f641b65 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -19,6 +19,7 @@ env = SConscript("./godot-cpp/SConstruct") env.__class__.disable_warnings = methods.disable_warnings opts = Variables([], ARGUMENTS) +opts.Add(BoolVariable("brotli_enabled", "Use Brotli library", True)) opts.Add(BoolVariable("freetype_enabled", "Use FreeType library", True)) opts.Add(BoolVariable("msdfgen_enabled", "Use MSDFgen library (require FreeType)", True)) opts.Add(BoolVariable("graphite_enabled", "Use Graphite library (require FreeType)", True)) @@ -162,6 +163,25 @@ if env["freetype_enabled"]: ] thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] + if env["brotli_enabled"]: + thirdparty_brotli_dir = "../../../thirdparty/brotli/" + thirdparty_brotli_sources = [ + "common/constants.c", + "common/context.c", + "common/dictionary.c", + "common/platform.c", + "common/shared_dictionary.c", + "common/transform.c", + "dec/bit_reader.c", + "dec/decode.c", + "dec/huffman.c", + "dec/state.c", + ] + thirdparty_freetype_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] + env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + env.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir]) env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"]) @@ -265,6 +285,7 @@ env_harfbuzz.Append( CPPPATH=[ "../../../thirdparty/harfbuzz/src", "../../../thirdparty/icu4c/common/", + "../../../thirdparty/icu4c/i18n/", ] ) @@ -569,6 +590,10 @@ thirdparty_icu_sources = [ "common/uvectr32.cpp", "common/uvectr64.cpp", "common/wintz.cpp", + "i18n/scriptset.cpp", + "i18n/ucln_in.cpp", + "i18n/uspoof.cpp", + "i18n/uspoof_impl.cpp", ] thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources] @@ -584,7 +609,7 @@ if env["static_icu_data"]: else: thirdparty_sources += ["../icu_data/icudata_stub.cpp"] -env_icu.Append(CPPPATH=["../../../thirdparty/icu4c/common/"]) +env_icu.Append(CPPPATH=["../../../thirdparty/icu4c/common/", "../../../thirdparty/icu4c/i18n/"]) env_icu.Append( CXXFLAGS=[ "-DU_STATIC_IMPLEMENTATION", @@ -610,7 +635,7 @@ env.Append( "-DICU_DATA_NAME=" + icu_data_name, ] ) -env.Append(CPPPATH=["../../../thirdparty/icu4c/common/"]) +env.Append(CPPPATH=["../../../thirdparty/icu4c/common/", "../../../thirdparty/icu4c/i18n/"]) if env["platform"] == "windows": env.Append(LIBS=["advapi32"]) diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c128374be14e..c97a6ef289ba 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -5851,9 +5851,9 @@ String TextServerAdvanced::percent_sign(const String &p_language) const { return "%"; } -int TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { +int64_t TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { UErrorCode status = U_ZERO_ERROR; - int match_index = -1; + int64_t match_index = -1; Char16String utf16 = p_string.utf16(); Vector skeletons; diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 1db95d153bb1..b9633a9b714f 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -705,7 +706,7 @@ class TextServerAdvanced : public TextServerExtension { virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override; - virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; + virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; virtual bool spoof_check(const String &p_string) const override; virtual String strip_diacritics(const String &p_string) const override; diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index de0a5499004f..488f9ca24eab 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -19,6 +19,7 @@ env = SConscript("./godot-cpp/SConstruct") env.__class__.disable_warnings = methods.disable_warnings opts = Variables([], ARGUMENTS) +opts.Add(BoolVariable("brotli_enabled", "Use Brotli library", True)) opts.Add(BoolVariable("freetype_enabled", "Use FreeType library", True)) opts.Add(BoolVariable("msdfgen_enabled", "Use MSDFgen library (require FreeType)", True)) opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) @@ -157,6 +158,25 @@ if env["freetype_enabled"]: ] thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources] + if env["brotli_enabled"]: + thirdparty_brotli_dir = "../../../thirdparty/brotli/" + thirdparty_brotli_sources = [ + "common/constants.c", + "common/context.c", + "common/dictionary.c", + "common/platform.c", + "common/shared_dictionary.c", + "common/transform.c", + "dec/bit_reader.c", + "dec/decode.c", + "dec/huffman.c", + "dec/state.c", + ] + thirdparty_freetype_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] + env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + env.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir]) env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"]) diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index cbb2fb03f271..42f311f5ad10 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index ebd35b0f7506..7a8a298dbdb1 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -1550,8 +1550,8 @@ PackedInt32Array TextServerExtension::string_get_word_breaks(const String &p_str return PackedInt32Array(); } -int TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { - int ret; +int64_t TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { + int64_t ret; if (GDVIRTUAL_CALL(is_confusable, p_string, p_dict, ret)) { return ret; } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 700d08f7d701..fbaa4961e11b 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -508,9 +508,9 @@ class TextServerExtension : public TextServer { TypedArray parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; GDVIRTUAL3RC(TypedArray, parse_structured_text, StructuredTextParser, const Array &, const String &); - virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; + virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const override; virtual bool spoof_check(const String &p_string) const override; - GDVIRTUAL2RC(int, is_confusable, const String &, const PackedStringArray &); + GDVIRTUAL2RC(int64_t, is_confusable, const String &, const PackedStringArray &); GDVIRTUAL1RC(bool, spoof_check, const String &); TextServerExtension(); diff --git a/servers/text_server.h b/servers/text_server.h index b62d418fc8b1..a0624c2c05fa 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -485,7 +485,7 @@ class TextServer : public RefCounted { // String functions. virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const = 0; - virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; + virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; virtual bool spoof_check(const String &p_string) const { return false; }; virtual String strip_diacritics(const String &p_string) const;