diff options
Diffstat (limited to 'core/variant')
-rw-r--r-- | core/variant/array.cpp | 2 | ||||
-rw-r--r-- | core/variant/binder_common.h | 50 | ||||
-rw-r--r-- | core/variant/dictionary.cpp | 2 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 46 | ||||
-rw-r--r-- | core/variant/variant.cpp | 24 | ||||
-rw-r--r-- | core/variant/variant.h | 6 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 4 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 62 | ||||
-rw-r--r-- | core/variant/variant_utility.cpp | 2 |
9 files changed, 117 insertions, 81 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 3d2f337442..1b39558dff 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -631,7 +631,7 @@ Variant Array::max() const { } const void *Array::id() const { - return _p->array.ptr(); + return _p; } Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 14f49d530c..b6fdb4d902 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -44,24 +44,42 @@ #include <stdio.h> +// Variant cannot define an implicit cast operator for every Object subclass, so the +// casting is done here, to allow binding methods with parameters more specific than Object * + template <class T> struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t<T>; + if constexpr (std::is_base_of<Object, TStripped>::value) { + return Object::cast_to<TStripped>(p_variant); + } else { + return p_variant; + } } }; template <class T> struct VariantCaster<T &> { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t<T>; + if constexpr (std::is_base_of<Object, TStripped>::value) { + return Object::cast_to<TStripped>(p_variant); + } else { + return p_variant; + } } }; template <class T> struct VariantCaster<const T &> { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t<T>; + if constexpr (std::is_base_of<Object, TStripped>::value) { + return Object::cast_to<TStripped>(p_variant); + } else { + return p_variant; + } } }; @@ -135,7 +153,13 @@ struct PtrToArg<char32_t> { template <typename T> struct VariantObjectClassChecker { static _FORCE_INLINE_ bool check(const Variant &p_variant) { - return true; + using TStripped = std::remove_pointer_t<T>; + if constexpr (std::is_base_of<Object, TStripped>::value) { + Object *obj = p_variant; + return Object::cast_to<TStripped>(p_variant) || !obj; + } else { + return true; + } } }; @@ -151,24 +175,6 @@ struct VariantObjectClassChecker<const Ref<T> &> { } }; -template <> -struct VariantObjectClassChecker<Node *> { - static _FORCE_INLINE_ bool check(const Variant &p_variant) { - Object *obj = p_variant; - Node *node = p_variant; - return node || !obj; - } -}; - -template <> -struct VariantObjectClassChecker<Control *> { - static _FORCE_INLINE_ bool check(const Variant &p_variant) { - Object *obj = p_variant; - Control *control = p_variant; - return control || !obj; - } -}; - #ifdef DEBUG_METHODS_ENABLED template <class T> diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index cc04ae712b..0f2f8fc8ed 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -350,7 +350,7 @@ void Dictionary::operator=(const Dictionary &p_dictionary) { } const void *Dictionary::id() const { - return _p->variant_map.id(); + return _p; } Dictionary::Dictionary(const Dictionary &p_from) { diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index fe541c8d4b..8e9fbbc0a4 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -53,22 +53,36 @@ struct GDNativePtr { operator Variant() const { return uint64_t(data); } }; -#define GDVIRTUAL_NATIVE_PTR(m_type) \ - template <> \ - struct GDNativeConstPtr<const m_type> { \ - const m_type *data = nullptr; \ - GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return "const " #m_type; } \ - operator const m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ - }; \ - template <> \ - struct GDNativePtr<m_type> { \ - m_type *data = nullptr; \ - GDNativePtr(m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return #m_type; } \ - operator m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ +#define GDVIRTUAL_NATIVE_PTR(m_type) \ + template <> \ + struct GDNativeConstPtr<const m_type> { \ + const m_type *data = nullptr; \ + GDNativeConstPtr() {} \ + GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return "const " #m_type; } \ + operator const m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDNativeConstPtr<const m_type>> { \ + static _FORCE_INLINE_ GDNativeConstPtr<const m_type> cast(const Variant &p_variant) { \ + return GDNativeConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct GDNativePtr<m_type> { \ + m_type *data = nullptr; \ + GDNativePtr() {} \ + GDNativePtr(m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return #m_type; } \ + operator m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDNativePtr<m_type>> { \ + static _FORCE_INLINE_ GDNativePtr<m_type> cast(const Variant &p_variant) { \ + return GDNativePtr<m_type>((m_type *)p_variant.operator uint64_t()); \ + } \ }; template <class T> diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index db198da54a..fcfa530388 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -38,8 +38,6 @@ #include "core/math/math_funcs.h" #include "core/string/print_string.h" #include "core/variant/variant_parser.h" -#include "scene/gui/control.h" -#include "scene/main/node.h" String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { @@ -1692,8 +1690,6 @@ String Variant::stringify(int recursion_count) const { pairs.push_back(sp); } - pairs.sort(); - for (int i = 0; i < pairs.size(); i++) { if (i > 0) { str += ", "; @@ -2006,22 +2002,6 @@ Object *Variant::get_validated_object() const { } } -Variant::operator Node *() const { - if (type == OBJECT) { - return Object::cast_to<Node>(_get_obj().obj); - } else { - return nullptr; - } -} - -Variant::operator Control *() const { - if (type == OBJECT) { - return Object::cast_to<Control>(_get_obj().obj); - } else { - return nullptr; - } -} - Variant::operator Dictionary() const { if (type == DICTIONARY) { return *reinterpret_cast<const Dictionary *>(_data._mem); @@ -3256,7 +3236,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const return false; } -bool Variant::is_ref() const { +bool Variant::is_ref_counted() const { return type == OBJECT && _get_obj().id.is_ref_counted(); } @@ -3416,7 +3396,7 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, } String class_name = p_base->get_class(); - Ref<Script> script = p_base->get_script(); + Ref<Resource> script = p_base->get_script(); if (script.is_valid() && script->get_path().is_resource_file()) { class_name += "(" + script->get_path().get_file() + ")"; } diff --git a/core/variant/variant.h b/core/variant/variant.h index 0860e7fdc3..36fa755647 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -53,8 +53,6 @@ #include "core/variant/dictionary.h" class Object; -class Node; // helper -class Control; // helper struct PropertyInfo; struct MethodInfo; @@ -287,7 +285,7 @@ public: static bool can_convert(Type p_type_from, Type p_type_to); static bool can_convert_strict(Type p_type_from, Type p_type_to); - bool is_ref() const; + bool is_ref_counted() const; _FORCE_INLINE_ bool is_num() const { return type == INT || type == FLOAT; } @@ -339,8 +337,6 @@ public: operator ::RID() const; operator Object *() const; - operator Node *() const; - operator Control *() const; operator Callable() const; operator Signal() const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 8dd48a4c28..750f23902d 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1382,7 +1382,7 @@ static void _register_variant_builtin_methods() { bind_methodv(String, begins_with, static_cast<bool (String::*)(const String &) const>(&String::begins_with), sarray("text"), varray()); bind_method(String, ends_with, sarray("text"), varray()); bind_method(String, is_subsequence_of, sarray("text"), varray()); - bind_method(String, is_subsequence_ofi, sarray("text"), varray()); + bind_method(String, is_subsequence_ofn, sarray("text"), varray()); bind_method(String, bigrams, sarray(), varray()); bind_method(String, similarity, sarray("text"), varray()); @@ -1421,6 +1421,7 @@ static void _register_variant_builtin_methods() { bind_method(String, sha1_buffer, sarray(), varray()); bind_method(String, sha256_buffer, sarray(), varray()); bind_method(String, is_empty, sarray(), varray()); + bind_methodv(String, contains, static_cast<bool (String::*)(const String &) const>(&String::contains), sarray("what"), varray()); bind_method(String, is_absolute_path, sarray(), varray()); bind_method(String, is_relative_path, sarray(), varray()); @@ -1789,6 +1790,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, scaled, sarray("scale"), varray()); bind_method(Transform3D, translated, sarray("offset"), varray()); bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); + bind_method(Transform3D, sphere_interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 57875bf50f..e889a1bb40 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -188,7 +188,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (p_stream->is_eof()) { r_token.type = TK_EOF; return OK; - } else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) { + } else if (is_hex_digit(ch)) { color_str += ch; } else { @@ -217,6 +217,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } case '"': { String str; + char32_t prev = 0; while (true) { char32_t ch = p_stream->get_char(); @@ -252,22 +253,25 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri case 'r': res = 13; break; + case 'U': case 'u': { - //hex number - for (int j = 0; j < 4; j++) { + // Hexadecimal sequence. + int hex_len = (next == 'U') ? 6 : 4; + for (int j = 0; j < hex_len; j++) { char32_t c = p_stream->get_char(); + if (c == 0) { r_err_str = "Unterminated String"; r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + if (!is_hex_digit(c)) { r_err_str = "Malformed hex constant in string"; r_token.type = TK_ERROR; return ERR_PARSE_ERROR; } char32_t v; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { v = c - '0'; } else if (c >= 'a' && c <= 'f') { v = c - 'a'; @@ -290,15 +294,49 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } break; } + // Parse UTF-16 pair. + if ((res & 0xfffffc00) == 0xd800) { + if (prev == 0) { + prev = res; + continue; + } else { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } + } else if ((res & 0xfffffc00) == 0xdc00) { + if (prev == 0) { + r_err_str = "Invalid UTF-16 sequence in string, unpaired trail surrogate"; + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } else { + res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000); + prev = 0; + } + } + if (prev != 0) { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } str += res; - } else { + if (prev != 0) { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } if (ch == '\n') { line++; } str += ch; } } + if (prev != 0) { + r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate"; + r_token.type = TK_ERROR; + return ERR_PARSE_ERROR; + } if (p_stream->is_utf8()) { str.parse_utf8(str.ascii(true).get_data()); @@ -343,7 +381,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri while (true) { switch (reading) { case READING_INT: { - if (c >= '0' && c <= '9') { + if (is_digit(c)) { //pass } else if (c == '.') { reading = READING_DEC; @@ -357,7 +395,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } break; case READING_DEC: { - if (c >= '0' && c <= '9') { + if (is_digit(c)) { } else if (c == 'e') { reading = READING_EXP; } else { @@ -366,7 +404,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } break; case READING_EXP: { - if (c >= '0' && c <= '9') { + if (is_digit(c)) { exp_beg = true; } else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) { @@ -395,11 +433,11 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri r_token.value = num.as_int(); } return OK; - } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { + } else if (is_ascii_char(cchar) || is_underscore(cchar)) { StringBuffer<> id; bool first = true; - while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) { + while (is_ascii_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) { id += cchar; cchar = p_stream->get_char(); first = false; @@ -1457,7 +1495,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::FLOAT: { String s = rtos_fix(p_variant.operator double()); if (s != "inf" && s != "inf_neg" && s != "nan") { - if (s.find(".") == -1 && s.find("e") == -1) { + if (!s.contains(".") && !s.contains("e")) { s += ".0"; } } diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 3fd8eb5474..60950099d2 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -433,7 +433,7 @@ struct VariantUtilityFunctions { static inline Variant weakref(const Variant &obj, Callable::CallError &r_error) { if (obj.get_type() == Variant::OBJECT) { r_error.error = Callable::CallError::CALL_OK; - if (obj.is_ref()) { + if (obj.is_ref_counted()) { Ref<WeakRef> wref = memnew(WeakRef); REF r = obj; if (r.is_valid()) { |