diff options
Diffstat (limited to 'core/variant')
29 files changed, 2200 insertions, 1637 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index c1bdd6a6bc..94d1596514 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -1,42 +1,44 @@ -/*************************************************************************/ -/* array.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* array.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "array.h" #include "container_type_validate.h" +#include "core/math/math_funcs.h" #include "core/object/class_db.h" #include "core/object/script_language.h" #include "core/templates/hashfuncs.h" #include "core/templates/search_array.h" #include "core/templates/vector.h" #include "core/variant/callable.h" +#include "core/variant/dictionary.h" #include "core/variant/variant.h" class ArrayPrivate { @@ -52,16 +54,6 @@ void Array::_ref(const Array &p_from) const { ERR_FAIL_COND(!_fp); // should NOT happen. - if (unlikely(_fp->read_only != nullptr)) { - // If p_from is a read-only array, just copy the contents to avoid further modification. - _unref(); - _p = memnew(ArrayPrivate); - _p->refcount.init(); - _p->array = _fp->array; - _p->typed = _fp->typed; - return; - } - if (_fp == _p) { return; // whatever it is, nothing to do here move along } @@ -200,16 +192,21 @@ uint32_t Array::recursive_hash(int recursion_count) const { } bool Array::_assign(const Array &p_array) { + bool can_convert = p_array._p->typed.type == Variant::NIL; + can_convert |= _p->typed.type == Variant::STRING && p_array._p->typed.type == Variant::STRING_NAME; + can_convert |= _p->typed.type == Variant::STRING_NAME && p_array._p->typed.type == Variant::STRING; + if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) { //same type or untyped, just reference, should be fine _ref(p_array); } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway _p->array = p_array._p->array; - } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid + } else if (can_convert) { //from untyped to typed, must try to check if they are all valid if (_p->typed.type == Variant::OBJECT) { //for objects, it needs full validation, either can be converted or fail for (int i = 0; i < p_array._p->array.size(); i++) { - if (!_p->typed.validate(p_array._p->array[i], "assign")) { + const Variant &element = p_array._p->array[i]; + if (element.get_type() != Variant::OBJECT || !_p->typed.validate_object(element, "assign")) { return false; } } @@ -254,16 +251,20 @@ void Array::operator=(const Array &p_array) { void Array::push_back(const Variant &p_value) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back")); - _p->array.push_back(p_value); + Variant value = p_value; + ERR_FAIL_COND(!_p->typed.validate(value, "push_back")); + _p->array.push_back(value); } void Array::append_array(const Array &p_array) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - for (int i = 0; i < p_array.size(); ++i) { - ERR_FAIL_COND(!_p->typed.validate(p_array[i], "append_array")); + + Vector<Variant> validated_array = p_array._p->array; + for (int i = 0; i < validated_array.size(); ++i) { + ERR_FAIL_COND(!_p->typed.validate(validated_array.write[i], "append_array")); } - _p->array.append_array(p_array._p->array); + + _p->array.append_array(validated_array); } Error Array::resize(int p_new_size) { @@ -273,20 +274,23 @@ Error Array::resize(int p_new_size) { Error Array::insert(int p_pos, const Variant &p_value) { ERR_FAIL_COND_V_MSG(_p->read_only, ERR_LOCKED, "Array is in read-only state."); - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "insert"), ERR_INVALID_PARAMETER); - return _p->array.insert(p_pos, p_value); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "insert"), ERR_INVALID_PARAMETER); + return _p->array.insert(p_pos, value); } void Array::fill(const Variant &p_value) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - ERR_FAIL_COND(!_p->typed.validate(p_value, "fill")); - _p->array.fill(p_value); + Variant value = p_value; + ERR_FAIL_COND(!_p->typed.validate(value, "fill")); + _p->array.fill(value); } void Array::erase(const Variant &p_value) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - ERR_FAIL_COND(!_p->typed.validate(p_value, "erase")); - _p->array.erase(p_value); + Variant value = p_value; + ERR_FAIL_COND(!_p->typed.validate(value, "erase")); + _p->array.erase(value); } Variant Array::front() const { @@ -299,16 +303,40 @@ Variant Array::back() const { return operator[](_p->array.size() - 1); } +Variant Array::pick_random() const { + ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array."); + return operator[](Math::rand() % _p->array.size()); +} + int Array::find(const Variant &p_value, int p_from) const { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1); - return _p->array.find(p_value, p_from); + if (_p->array.size() == 0) { + return -1; + } + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "find"), -1); + + int ret = -1; + + if (p_from < 0 || size() == 0) { + return ret; + } + + for (int i = p_from; i < size(); i++) { + if (StringLikeVariantComparator::compare(_p->array[i], value)) { + ret = i; + break; + } + } + + return ret; } int Array::rfind(const Variant &p_value, int p_from) const { if (_p->array.size() == 0) { return -1; } - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "rfind"), -1); if (p_from < 0) { // Relative offset from the end @@ -320,7 +348,7 @@ int Array::rfind(const Variant &p_value, int p_from) const { } for (int i = p_from; i >= 0; i--) { - if (_p->array[i] == p_value) { + if (StringLikeVariantComparator::compare(_p->array[i], value)) { return i; } } @@ -328,20 +356,16 @@ int Array::rfind(const Variant &p_value, int p_from) const { return -1; } -int Array::find_last(const Variant &p_value) const { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1); - return rfind(p_value); -} - int Array::count(const Variant &p_value) const { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "count"), 0); if (_p->array.size() == 0) { return 0; } int amount = 0; for (int i = 0; i < _p->array.size(); i++) { - if (_p->array[i] == p_value) { + if (StringLikeVariantComparator::compare(_p->array[i], value)) { amount++; } } @@ -350,9 +374,10 @@ int Array::count(const Variant &p_value) const { } bool Array::has(const Variant &p_value) const { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "use 'has'"), false); - return _p->array.find(p_value, 0) != -1; + return find(value) != -1; } void Array::remove_at(int p_pos) { @@ -362,9 +387,10 @@ void Array::remove_at(int p_pos) { void Array::set(int p_idx, const Variant &p_value) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - ERR_FAIL_COND(!_p->typed.validate(p_value, "set")); + Variant value = p_value; + ERR_FAIL_COND(!_p->typed.validate(value, "set")); - operator[](p_idx) = p_value; + operator[](p_idx) = value; } const Variant &Array::get(int p_idx) const { @@ -402,6 +428,7 @@ Array Array::recursive_duplicate(bool p_deep, int recursion_count) const { Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { Array result; + result._p->typed = _p->typed; ERR_FAIL_COND_V_MSG(p_step == 0, result, "Slice step cannot be zero."); @@ -433,6 +460,7 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { Array Array::filter(const Callable &p_callable) const { Array new_arr; new_arr.resize(size()); + new_arr._p->typed = _p->typed; int accepted_count = 0; const Variant *argptrs[1]; @@ -585,15 +613,17 @@ void Array::shuffle() { } int Array::bsearch(const Variant &p_value, bool p_before) { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "binary search"), -1); SearchArray<Variant, _ArrayVariantSort> avs; - return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); + return avs.bisect(_p->array.ptrw(), _p->array.size(), value, p_before); } int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) { - ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); + Variant value = p_value; + ERR_FAIL_COND_V(!_p->typed.validate(value, "custom binary search"), -1); - return _p->array.bsearch_custom<CallableComparator>(p_value, p_before, p_callable); + return _p->array.bsearch_custom<CallableComparator>(value, p_before, p_callable); } void Array::reverse() { @@ -603,8 +633,9 @@ void Array::reverse() { void Array::push_front(const Variant &p_value) { ERR_FAIL_COND_MSG(_p->read_only, "Array is in read-only state."); - ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front")); - _p->array.insert(0, p_value); + Variant value = p_value; + ERR_FAIL_COND(!_p->typed.validate(value, "push_front")); + _p->array.insert(0, value); } Variant Array::pop_back() { @@ -744,15 +775,9 @@ Variant Array::get_typed_script() const { return _p->typed.script; } -void Array::set_read_only(bool p_enable) { - if (p_enable == bool(_p->read_only != nullptr)) { - return; - } - if (p_enable) { +void Array::make_read_only() { + if (_p->read_only == nullptr) { _p->read_only = memnew(Variant); - } else { - memdelete(_p->read_only); - _p->read_only = nullptr; } } diff --git a/core/variant/array.h b/core/variant/array.h index 3d9a794969..d9ca3278fb 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* array.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* array.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef ARRAY_H #define ARRAY_H @@ -79,6 +79,7 @@ public: Variant front() const; Variant back() const; + Variant pick_random() const; void sort(); void sort_custom(const Callable &p_callable); @@ -89,7 +90,6 @@ public: int find(const Variant &p_value, int p_from = 0) const; int rfind(const Variant &p_value, int p_from = -1) const; - int find_last(const Variant &p_value) const; int count(const Variant &p_value) const; bool has(const Variant &p_value) const; @@ -127,7 +127,7 @@ public: StringName get_typed_class_name() const; Variant get_typed_script() const; - void set_read_only(bool p_enable); + void make_read_only(); bool is_read_only() const; Array(const Array &p_base, 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 f0c3b1ce38..81ac5adba7 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* binder_common.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* binder_common.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef BINDER_COMMON_H #define BINDER_COMMON_H @@ -138,7 +138,7 @@ VARIANT_ENUM_CAST(Vector3::Axis); VARIANT_ENUM_CAST(Vector3i::Axis); VARIANT_ENUM_CAST(Vector4::Axis); VARIANT_ENUM_CAST(Vector4i::Axis); -VARIANT_ENUM_CAST(Basis::EulerOrder); +VARIANT_ENUM_CAST(EulerOrder); VARIANT_ENUM_CAST(Projection::Planes); VARIANT_ENUM_CAST(Error); @@ -146,22 +146,53 @@ VARIANT_ENUM_CAST(Side); VARIANT_ENUM_CAST(ClockDirection); VARIANT_ENUM_CAST(Corner); VARIANT_ENUM_CAST(HatDir); -VARIANT_ENUM_CAST(HatMask); +VARIANT_BITFIELD_CAST(HatMask); VARIANT_ENUM_CAST(JoyAxis); VARIANT_ENUM_CAST(JoyButton); -VARIANT_ENUM_CAST(Key); -VARIANT_ENUM_CAST(KeyModifierMask); + VARIANT_ENUM_CAST(MIDIMessage); VARIANT_ENUM_CAST(MouseButton); +VARIANT_BITFIELD_CAST(MouseButtonMask); VARIANT_ENUM_CAST(Orientation); VARIANT_ENUM_CAST(HorizontalAlignment); VARIANT_ENUM_CAST(VerticalAlignment); VARIANT_ENUM_CAST(InlineAlignment); VARIANT_ENUM_CAST(PropertyHint); -VARIANT_ENUM_CAST(PropertyUsageFlags); +VARIANT_BITFIELD_CAST(PropertyUsageFlags); VARIANT_ENUM_CAST(Variant::Type); VARIANT_ENUM_CAST(Variant::Operator); +// Key + +VARIANT_ENUM_CAST(Key); +VARIANT_BITFIELD_CAST(KeyModifierMask); + +static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) { + a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t())); + return a; +} + +static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) { + a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t())); + return a; +} + +static inline Key operator|(Key a, BitField<KeyModifierMask> b) { + return (Key)((int)a | (int)b.operator int64_t()); +} + +static inline Key operator&(Key a, BitField<KeyModifierMask> b) { + return (Key)((int)a & (int)b.operator int64_t()); +} + +static inline Key operator+(BitField<KeyModifierMask> a, Key b) { + return (Key)((int)a.operator int64_t() + (int)b); +} + +static inline Key operator|(BitField<KeyModifierMask> a, Key b) { + return (Key)((int)a.operator int64_t() | (int)b); +} + template <> struct VariantCaster<char32_t> { static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) { diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index b35e2f004b..2f2acc55a6 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* callable.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* callable.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "callable.h" @@ -102,7 +102,22 @@ Callable Callable::bindp(const Variant **p_arguments, int p_argcount) const { } return Callable(memnew(CallableCustomBind(*this, args))); } + +Callable Callable::bindv(const Array &p_arguments) { + if (p_arguments.is_empty()) { + return *this; // No point in creating a new callable if nothing is bound. + } + + Vector<Variant> args; + args.resize(p_arguments.size()); + for (int i = 0; i < p_arguments.size(); i++) { + args.write[i] = p_arguments[i]; + } + return Callable(memnew(CallableCustomBind(*this, args))); +} + Callable Callable::unbind(int p_argcount) const { + ERR_FAIL_COND_V_MSG(p_argcount <= 0, Callable(*this), "Amount of unbind() arguments must be 1 or greater."); return Callable(memnew(CallableCustomUnbind(*this, p_argcount))); } @@ -137,6 +152,35 @@ StringName Callable::get_method() const { return method; } +int Callable::get_bound_arguments_count() const { + if (!is_null() && is_custom()) { + return custom->get_bound_arguments_count(); + } else { + return 0; + } +} + +void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const { + if (!is_null() && is_custom()) { + custom->get_bound_arguments(r_arguments, r_argcount); + } else { + r_arguments.clear(); + r_argcount = 0; + } +} + +Array Callable::get_bound_arguments() const { + Vector<Variant> arr; + int ac; + get_bound_arguments_ref(arr, ac); + Array ret; + ret.resize(arr.size()); + for (int i = 0; i < arr.size(); i++) { + ret[i] = arr[i]; + } + return ret; +} + CallableCustom *Callable::get_custom() const { ERR_FAIL_COND_V_MSG(!is_custom(), nullptr, vformat("Can't get custom on non-CallableCustom \"%s\".", operator String())); @@ -344,6 +388,15 @@ const Callable *CallableCustom::get_base_comparator() const { return nullptr; } +int CallableCustom::get_bound_arguments_count() const { + return 0; +} + +void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { + r_arguments = Vector<Variant>(); + r_argcount = 0; +} + CallableCustom::CallableCustom() { ref_count.init(); } @@ -402,33 +455,33 @@ Error Signal::emit(const Variant **p_arguments, int p_argcount) const { } Error Signal::connect(const Callable &p_callable, uint32_t p_flags) { - Object *object = get_object(); - ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED); + Object *obj = get_object(); + ERR_FAIL_COND_V(!obj, ERR_UNCONFIGURED); - return object->connect(name, p_callable, p_flags); + return obj->connect(name, p_callable, p_flags); } void Signal::disconnect(const Callable &p_callable) { - Object *object = get_object(); - ERR_FAIL_COND(!object); - object->disconnect(name, p_callable); + Object *obj = get_object(); + ERR_FAIL_COND(!obj); + obj->disconnect(name, p_callable); } bool Signal::is_connected(const Callable &p_callable) const { - Object *object = get_object(); - ERR_FAIL_COND_V(!object, false); + Object *obj = get_object(); + ERR_FAIL_COND_V(!obj, false); - return object->is_connected(name, p_callable); + return obj->is_connected(name, p_callable); } Array Signal::get_connections() const { - Object *object = get_object(); - if (!object) { + Object *obj = get_object(); + if (!obj) { return Array(); } List<Object::Connection> connections; - object->get_signal_connection_list(name, &connections); + obj->get_signal_connection_list(name, &connections); Array arr; for (const Object::Connection &E : connections) { diff --git a/core/variant/callable.h b/core/variant/callable.h index 0305dc55c3..0abbb64c0b 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* callable.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* callable.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef CALLABLE_H #define CALLABLE_H @@ -73,6 +73,16 @@ public: void call_deferredp(const Variant **p_arguments, int p_argcount) const; Variant callv(const Array &p_arguments) const; + template <typename... VarArgs> + void call_deferred(VarArgs... p_args) const { + Variant args[sizeof...(p_args) + 1] = { p_args..., 0 }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + return call_deferredp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + Error rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const; _FORCE_INLINE_ bool is_null() const { @@ -88,6 +98,7 @@ public: template <typename... VarArgs> Callable bind(VarArgs... p_args); + Callable bindv(const Array &p_arguments); Callable bindp(const Variant **p_arguments, int p_argcount) const; Callable unbind(int p_argcount) const; @@ -96,6 +107,9 @@ public: ObjectID get_object_id() const; StringName get_method() const; CallableCustom *get_custom() const; + int get_bound_arguments_count() const; + void get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below. + Array get_bound_arguments() const; uint32_t hash() const; @@ -136,6 +150,8 @@ public: virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0; virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const; virtual const Callable *get_base_comparator() const; + virtual int get_bound_arguments_count() const; + virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const; CallableCustom(); virtual ~CallableCustom() {} diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index d26aa2ae46..5be91c6e11 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* callable_bind.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* callable_bind.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "callable_bind.h" @@ -87,6 +87,47 @@ const Callable *CallableCustomBind::get_base_comparator() const { return &callable; } +int CallableCustomBind::get_bound_arguments_count() const { + return callable.get_bound_arguments_count() + binds.size(); +} + +void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { + Vector<Variant> sub_args; + int sub_count; + callable.get_bound_arguments_ref(sub_args, sub_count); + + if (sub_count == 0) { + r_arguments = binds; + r_argcount = binds.size(); + return; + } + + int new_count = sub_count + binds.size(); + r_argcount = new_count; + + if (new_count <= 0) { + // Removed more arguments than it adds. + r_arguments = Vector<Variant>(); + return; + } + + r_arguments.resize(new_count); + + if (sub_count > 0) { + for (int i = 0; i < sub_count; i++) { + r_arguments.write[i] = sub_args[i]; + } + for (int i = 0; i < binds.size(); i++) { + r_arguments.write[i + sub_count] = binds[i]; + } + r_argcount = new_count; + } else { + for (int i = 0; i < binds.size() + sub_count; i++) { + r_arguments.write[i] = binds[i - sub_count]; + } + } +} + void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount)); for (int i = 0; i < p_argcount; i++) { @@ -164,6 +205,25 @@ const Callable *CallableCustomUnbind::get_base_comparator() const { return &callable; } +int CallableCustomUnbind::get_bound_arguments_count() const { + return callable.get_bound_arguments_count() - argcount; +} + +void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { + Vector<Variant> sub_args; + int sub_count; + callable.get_bound_arguments_ref(sub_args, sub_count); + + r_argcount = sub_args.size() - argcount; + + if (argcount >= sub_args.size()) { + r_arguments = Vector<Variant>(); + } else { + sub_args.resize(sub_args.size() - argcount); + r_arguments = sub_args; + } +} + void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { if (argcount > p_argcount) { r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index f7351d29e0..278ed335d0 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* callable_bind.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* callable_bind.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef CALLABLE_BIND_H #define CALLABLE_BIND_H @@ -51,7 +51,8 @@ public: virtual ObjectID get_object() const override; //must always be able to provide an object virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; - + virtual int get_bound_arguments_count() const override; + virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; Callable get_callable() { return callable; } Vector<Variant> get_binds() { return binds; } @@ -76,6 +77,8 @@ public: virtual ObjectID get_object() const override; //must always be able to provide an object virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; + virtual int get_bound_arguments_count() const override; + virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; Callable get_callable() { return callable; } int get_unbinds() { return argcount; } diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h index 6171c8c88f..377be03bdf 100644 --- a/core/variant/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* container_type_validate.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* container_type_validate.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef CONTAINER_TYPE_VALIDATE_H #define CONTAINER_TYPE_VALIDATE_H @@ -74,23 +74,41 @@ struct ContainerTypeValidate { return true; } - _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") { + // Coerces String and StringName into each other when needed. + _FORCE_INLINE_ bool validate(Variant &inout_variant, const char *p_operation = "use") { if (type == Variant::NIL) { return true; } - ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); - if (type != p_variant.get_type()) { - return false; + if (type != inout_variant.get_type()) { + if (inout_variant.get_type() == Variant::NIL && type == Variant::OBJECT) { + return true; + } + if (type == Variant::STRING && inout_variant.get_type() == Variant::STRING_NAME) { + inout_variant = String(inout_variant); + return true; + } else if (type == Variant::STRING_NAME && inout_variant.get_type() == Variant::STRING) { + inout_variant = StringName(inout_variant); + return true; + } + + ERR_FAIL_V_MSG(false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(inout_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); } if (type != Variant::OBJECT) { return true; } + + return validate_object(inout_variant, p_operation); + } + + _FORCE_INLINE_ bool validate_object(const Variant &p_variant, const char *p_operation = "use") { + ERR_FAIL_COND_V(p_variant.get_type() != Variant::OBJECT, false); + #ifdef DEBUG_ENABLED ObjectID object_id = p_variant; if (object_id == ObjectID()) { - return true; //fine its null; + return true; // This is fine, it's null. } Object *object = ObjectDB::get_instance(object_id); ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); @@ -101,7 +119,7 @@ struct ContainerTypeValidate { } #endif if (class_name == StringName()) { - return true; //all good, no class type requested + return true; // All good, no class type requested. } StringName obj_class = object->get_class_name(); @@ -110,12 +128,12 @@ struct ContainerTypeValidate { } if (script.is_null()) { - return true; //all good + return true; // All good, no script requested. } Ref<Script> other_script = object->get_script(); - //check base script.. + // Check base script.. ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index c1cb782a57..0429508cc5 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* dictionary.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* dictionary.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "dictionary.h" @@ -42,7 +42,7 @@ struct DictionaryPrivate { SafeRefCount refcount; Variant *read_only = nullptr; // If enabled, a pointer is used to a temporary value that is used to return read-only values. - HashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map; + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator> variant_map; }; void Dictionary::get_key_list(List<Variant> *p_keys) const { @@ -100,24 +100,12 @@ Variant &Dictionary::operator[](const Variant &p_key) { } const Variant &Dictionary::operator[](const Variant &p_key) const { - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - return _p->variant_map[sn->operator String()]; - } else { - return _p->variant_map[p_key]; - } + // Will not insert key, so no conversion is necessary. + return _p->variant_map[p_key]; } const Variant *Dictionary::getptr(const Variant &p_key) const { - HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator E; - - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); - } else { - E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); - } - + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(p_key)); if (!E) { return nullptr; } @@ -125,14 +113,7 @@ const Variant *Dictionary::getptr(const Variant &p_key) const { } Variant *Dictionary::getptr(const Variant &p_key) { - HashMap<Variant, Variant, VariantHasher, VariantComparator>::Iterator E; - - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - E = ((HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); - } else { - E = ((HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); - } + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E(_p->variant_map.find(p_key)); if (!E) { return nullptr; } @@ -145,14 +126,7 @@ Variant *Dictionary::getptr(const Variant &p_key) { } Variant Dictionary::get_valid(const Variant &p_key) const { - HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator E; - - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); - } else { - E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); - } + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(p_key)); if (!E) { return Variant(); @@ -178,12 +152,7 @@ bool Dictionary::is_empty() const { } bool Dictionary::has(const Variant &p_key) const { - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - return _p->variant_map.has(sn->operator String()); - } else { - return _p->variant_map.has(p_key); - } + return _p->variant_map.has(p_key); } bool Dictionary::has_all(const Array &p_keys) const { @@ -206,12 +175,7 @@ Variant Dictionary::find_key(const Variant &p_value) const { bool Dictionary::erase(const Variant &p_key) { ERR_FAIL_COND_V_MSG(_p->read_only, false, "Dictionary is in read-only state."); - if (p_key.get_type() == Variant::STRING_NAME) { - const StringName *sn = VariantInternal::get_string_name(&p_key); - return _p->variant_map.erase(sn->operator String()); - } else { - return _p->variant_map.erase(p_key); - } + return _p->variant_map.erase(p_key); } bool Dictionary::operator==(const Dictionary &p_dictionary) const { @@ -238,7 +202,7 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c } recursion_count++; for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) { - HashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstIterator other_E = ((const HashMap<Variant, Variant, VariantHasher, VariantComparator> *)&p_dictionary._p->variant_map)->find(this_E.key); + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key)); if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count)) { return false; } @@ -247,16 +211,6 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c } void Dictionary::_ref(const Dictionary &p_from) const { - if (unlikely(p_from._p->read_only != nullptr)) { - // If p_from is a read-only dictionary, just copy the contents to avoid further modification. - if (_p) { - _unref(); - } - _p = memnew(DictionaryPrivate); - _p->refcount.init(); - _p->variant_map = p_from._p->variant_map; - return; - } //make a copy first (thread safe) if (!p_from._p->refcount.ref()) { return; // couldn't copy @@ -360,7 +314,7 @@ const Variant *Dictionary::next(const Variant *p_key) const { } return nullptr; } - HashMap<Variant, Variant, VariantHasher, VariantComparator>::Iterator E = _p->variant_map.find(*p_key); + HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::Iterator E = _p->variant_map.find(*p_key); if (!E) { return nullptr; @@ -379,15 +333,9 @@ Dictionary Dictionary::duplicate(bool p_deep) const { return recursive_duplicate(p_deep, 0); } -void Dictionary::set_read_only(bool p_enable) { - if (p_enable == bool(_p->read_only != nullptr)) { - return; - } - if (p_enable) { +void Dictionary::make_read_only() { + if (_p->read_only == nullptr) { _p->read_only = memnew(Variant); - } else { - memdelete(_p->read_only); - _p->read_only = nullptr; } } bool Dictionary::is_read_only() const { diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h index d9c9db56cf..8935d35ed9 100644 --- a/core/variant/dictionary.h +++ b/core/variant/dictionary.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* dictionary.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* dictionary.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef DICTIONARY_H #define DICTIONARY_H @@ -86,7 +86,7 @@ public: Dictionary duplicate(bool p_deep = false) const; Dictionary recursive_duplicate(bool p_deep, int recursion_count) const; - void set_read_only(bool p_enable); + void make_read_only(); bool is_read_only() const; const void *id() const; diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index 0ed70a5504..df1e524494 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* method_ptrcall.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* method_ptrcall.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef METHOD_PTRCALL_H #define METHOD_PTRCALL_H diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index ed68e0f6c9..ea811daabf 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* native_ptr.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* native_ptr.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef NATIVE_PTR_H #define NATIVE_PTR_H @@ -36,90 +36,90 @@ #include "core/variant/type_info.h" template <class T> -struct GDNativeConstPtr { +struct GDExtensionConstPtr { const T *data = nullptr; - GDNativeConstPtr(const T *p_assign) { data = p_assign; } + GDExtensionConstPtr(const T *p_assign) { data = p_assign; } static const char *get_name() { return "const void"; } operator const T *() const { return data; } operator Variant() const { return uint64_t(data); } }; template <class T> -struct GDNativePtr { +struct GDExtensionPtr { T *data = nullptr; - GDNativePtr(T *p_assign) { data = p_assign; } + GDExtensionPtr(T *p_assign) { data = p_assign; } static const char *get_name() { return "void"; } operator T *() 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()); \ - } \ +#define GDVIRTUAL_NATIVE_PTR(m_type) \ + template <> \ + struct GDExtensionConstPtr<const m_type> { \ + const m_type *data = nullptr; \ + GDExtensionConstPtr() {} \ + GDExtensionConstPtr(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<GDExtensionConstPtr<const m_type>> { \ + static _FORCE_INLINE_ GDExtensionConstPtr<const m_type> cast(const Variant &p_variant) { \ + return GDExtensionConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct GDExtensionPtr<m_type> { \ + m_type *data = nullptr; \ + GDExtensionPtr() {} \ + GDExtensionPtr(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<GDExtensionPtr<m_type>> { \ + static _FORCE_INLINE_ GDExtensionPtr<m_type> cast(const Variant &p_variant) { \ + return GDExtensionPtr<m_type>((m_type *)p_variant.operator uint64_t()); \ + } \ }; template <class T> -struct GetTypeInfo<GDNativeConstPtr<T>> { +struct GetTypeInfo<GDExtensionConstPtr<T>> { static const Variant::Type VARIANT_TYPE = Variant::NIL; static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativeConstPtr<T>::get_name()); + return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDExtensionConstPtr<T>::get_name()); } }; template <class T> -struct GetTypeInfo<GDNativePtr<T>> { +struct GetTypeInfo<GDExtensionPtr<T>> { static const Variant::Type VARIANT_TYPE = Variant::NIL; static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativePtr<T>::get_name()); + return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDExtensionPtr<T>::get_name()); } }; template <class T> -struct PtrToArg<GDNativeConstPtr<T>> { - _FORCE_INLINE_ static GDNativeConstPtr<T> convert(const void *p_ptr) { - return GDNativeConstPtr<T>(reinterpret_cast<const T *>(p_ptr)); +struct PtrToArg<GDExtensionConstPtr<T>> { + _FORCE_INLINE_ static GDExtensionConstPtr<T> convert(const void *p_ptr) { + return GDExtensionConstPtr<T>(reinterpret_cast<const T *>(p_ptr)); } typedef const T *EncodeT; - _FORCE_INLINE_ static void encode(GDNativeConstPtr<T> p_val, void *p_ptr) { + _FORCE_INLINE_ static void encode(GDExtensionConstPtr<T> p_val, void *p_ptr) { *((const T **)p_ptr) = p_val.data; } }; template <class T> -struct PtrToArg<GDNativePtr<T>> { - _FORCE_INLINE_ static GDNativePtr<T> convert(const void *p_ptr) { - return GDNativePtr<T>(reinterpret_cast<const T *>(p_ptr)); +struct PtrToArg<GDExtensionPtr<T>> { + _FORCE_INLINE_ static GDExtensionPtr<T> convert(const void *p_ptr) { + return GDExtensionPtr<T>(reinterpret_cast<const T *>(p_ptr)); } typedef T *EncodeT; - _FORCE_INLINE_ static void encode(GDNativePtr<T> p_val, void *p_ptr) { + _FORCE_INLINE_ static void encode(GDExtensionPtr<T> p_val, void *p_ptr) { *((T **)p_ptr) = p_val.data; } }; diff --git a/core/variant/type_info.h b/core/variant/type_info.h index e355053296..e89658d25b 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* type_info.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* type_info.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef TYPE_INFO_H #define TYPE_INFO_H @@ -287,10 +287,14 @@ class BitField { int64_t value = 0; public: - _FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; } - _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; } - _FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; } + _FORCE_INLINE_ void set_flag(T p_flag) { value |= (int64_t)p_flag; } + _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & (int64_t)p_flag; } + _FORCE_INLINE_ bool is_empty() const { return value == 0; } + _FORCE_INLINE_ void clear_flag(T p_flag) { value &= ~(int64_t)p_flag; } + _FORCE_INLINE_ void clear() { value = 0; } + _FORCE_INLINE_ BitField() = default; _FORCE_INLINE_ BitField(int64_t p_value) { value = p_value; } + _FORCE_INLINE_ BitField(T p_value) { value = (int64_t)p_value; } _FORCE_INLINE_ operator int64_t() const { return value; } _FORCE_INLINE_ operator Variant() const { return value; } }; diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h index aadd6fee89..5aeabbacf8 100644 --- a/core/variant/typed_array.h +++ b/core/variant/typed_array.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* typed_array.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* typed_array.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef TYPED_ARRAY_H #define TYPED_ARRAY_H diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index f24ffeb1a9..672b030806 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant.h" @@ -47,146 +47,126 @@ String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { case NIL: { return "Nil"; - } break; + } - // atomic types + // Atomic types. case BOOL: { return "bool"; - } break; + } case INT: { return "int"; - - } break; + } case FLOAT: { return "float"; - - } break; + } case STRING: { return "String"; - } break; + } - // math types + // Math types. case VECTOR2: { return "Vector2"; - } break; + } case VECTOR2I: { return "Vector2i"; - } break; + } case RECT2: { return "Rect2"; - } break; + } case RECT2I: { return "Rect2i"; - } break; + } case TRANSFORM2D: { return "Transform2D"; - } break; + } case VECTOR3: { return "Vector3"; - } break; + } case VECTOR3I: { return "Vector3i"; - } break; + } case VECTOR4: { return "Vector4"; - } break; + } case VECTOR4I: { return "Vector4i"; - } break; + } case PLANE: { return "Plane"; - - } break; + } case AABB: { return "AABB"; - } break; + } case QUATERNION: { return "Quaternion"; - - } break; + } case BASIS: { return "Basis"; - - } break; + } case TRANSFORM3D: { return "Transform3D"; - - } break; + } case PROJECTION: { return "Projection"; + } - } break; - - // misc types + // Miscellaneous types. case COLOR: { return "Color"; - - } break; + } case RID: { return "RID"; - } break; + } case OBJECT: { return "Object"; - } break; + } case CALLABLE: { return "Callable"; - } break; + } case SIGNAL: { return "Signal"; - } break; + } case STRING_NAME: { return "StringName"; - - } break; + } case NODE_PATH: { return "NodePath"; - - } break; + } case DICTIONARY: { return "Dictionary"; - - } break; + } case ARRAY: { return "Array"; + } - } break; - - // arrays + // Arrays. case PACKED_BYTE_ARRAY: { return "PackedByteArray"; - - } break; + } case PACKED_INT32_ARRAY: { return "PackedInt32Array"; - - } break; + } case PACKED_INT64_ARRAY: { return "PackedInt64Array"; - - } break; + } case PACKED_FLOAT32_ARRAY: { return "PackedFloat32Array"; - - } break; + } case PACKED_FLOAT64_ARRAY: { return "PackedFloat64Array"; - - } break; + } case PACKED_STRING_ARRAY: { return "PackedStringArray"; - } break; + } case PACKED_VECTOR2_ARRAY: { return "PackedVector2Array"; - - } break; + } case PACKED_VECTOR3_ARRAY: { return "PackedVector3Array"; - - } break; + } case PACKED_COLOR_ARRAY: { return "PackedColorArray"; - - } break; + } default: { } } @@ -880,157 +860,126 @@ bool Variant::is_zero() const { switch (type) { case NIL: { return true; - } break; + } - // atomic types + // Atomic types. case BOOL: { return !(_data._bool); - } break; + } case INT: { return _data._int == 0; - - } break; + } case FLOAT: { return _data._float == 0; - - } break; + } case STRING: { return *reinterpret_cast<const String *>(_data._mem) == String(); + } - } break; - - // math types + // Math types. case VECTOR2: { return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(); - - } break; + } case VECTOR2I: { return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(); - - } break; + } case RECT2: { return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(); - - } break; + } case RECT2I: { return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(); - - } break; + } case TRANSFORM2D: { return *_data._transform2d == Transform2D(); - - } break; + } case VECTOR3: { return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(); - - } break; + } case VECTOR3I: { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(); - - } break; + } case VECTOR4: { return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(); - - } break; + } case VECTOR4I: { return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(); - - } break; + } case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(); - - } break; + } case AABB: { return *_data._aabb == ::AABB(); - } break; + } case QUATERNION: { return *reinterpret_cast<const Quaternion *>(_data._mem) == Quaternion(); - - } break; + } case BASIS: { return *_data._basis == Basis(); - - } break; + } case TRANSFORM3D: { return *_data._transform3d == Transform3D(); - - } break; + } case PROJECTION: { return *_data._projection == Projection(); + } - } break; - - // misc types + // Miscellaneous types. case COLOR: { return *reinterpret_cast<const Color *>(_data._mem) == Color(); - - } break; + } case RID: { return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID(); - } break; + } case OBJECT: { return _get_obj().obj == nullptr; - } break; + } case CALLABLE: { return reinterpret_cast<const Callable *>(_data._mem)->is_null(); - } break; + } case SIGNAL: { return reinterpret_cast<const Signal *>(_data._mem)->is_null(); - } break; + } case STRING_NAME: { - return *reinterpret_cast<const StringName *>(_data._mem) != StringName(); - - } break; + return *reinterpret_cast<const StringName *>(_data._mem) == StringName(); + } case NODE_PATH: { return reinterpret_cast<const NodePath *>(_data._mem)->is_empty(); - - } break; + } case DICTIONARY: { return reinterpret_cast<const Dictionary *>(_data._mem)->is_empty(); - - } break; + } case ARRAY: { return reinterpret_cast<const Array *>(_data._mem)->is_empty(); + } - } break; - - // arrays + // Arrays. case PACKED_BYTE_ARRAY: { return PackedArrayRef<uint8_t>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_INT32_ARRAY: { return PackedArrayRef<int32_t>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_INT64_ARRAY: { return PackedArrayRef<int64_t>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_FLOAT32_ARRAY: { return PackedArrayRef<float>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_FLOAT64_ARRAY: { return PackedArrayRef<double>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_STRING_ARRAY: { return PackedArrayRef<String>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_VECTOR2_ARRAY: { return PackedArrayRef<Vector2>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_VECTOR3_ARRAY: { return PackedArrayRef<Vector3>::get_array(_data.packed_array).size() == 0; - - } break; + } case PACKED_COLOR_ARRAY: { return PackedArrayRef<Color>::get_array(_data.packed_array).size() == 0; - - } break; + } default: { } } @@ -1042,67 +991,54 @@ bool Variant::is_one() const { switch (type) { case NIL: { return true; - } break; + } - // atomic types case BOOL: { return _data._bool; - } break; + } case INT: { return _data._int == 1; - - } break; + } case FLOAT: { return _data._float == 1; + } - } break; case VECTOR2: { return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(1, 1); - - } break; + } case VECTOR2I: { return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(1, 1); - - } break; + } case RECT2: { return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(1, 1, 1, 1); - - } break; + } case RECT2I: { return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(1, 1, 1, 1); - - } break; + } case VECTOR3: { return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(1, 1, 1); - - } break; + } case VECTOR3I: { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1); - - } break; + } case VECTOR4: { return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1); - - } break; + } case VECTOR4I: { return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1); - - } break; + } case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1); + } - } break; case COLOR: { return *reinterpret_cast<const Color *>(_data._mem) == Color(1, 1, 1, 1); - - } break; + } default: { return !is_zero(); } } - - return false; } bool Variant::is_null() const { @@ -1135,10 +1071,10 @@ void Variant::reference(const Variant &p_variant) { switch (p_variant.type) { case NIL: { - // none + // None. } break; - // atomic types + // Atomic types. case BOOL: { _data._bool = p_variant._data._bool; } break; @@ -1152,7 +1088,7 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem))); } break; - // math types + // Math types. case VECTOR2: { memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem))); } break; @@ -1204,10 +1140,9 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._projection, Projection(*p_variant._data._projection)); } break; - // misc types + // Miscellaneous types. case COLOR: { memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem))); - } break; case RID: { memnew_placement(_data._mem, ::RID(*reinterpret_cast<const ::RID *>(p_variant._data._mem))); @@ -1226,7 +1161,6 @@ void Variant::reference(const Variant &p_variant) { _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj); _get_obj().id = p_variant._get_obj().id; - } break; case CALLABLE: { memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem))); @@ -1236,84 +1170,71 @@ void Variant::reference(const Variant &p_variant) { } break; case STRING_NAME: { memnew_placement(_data._mem, StringName(*reinterpret_cast<const StringName *>(p_variant._data._mem))); - } break; case NODE_PATH: { memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem))); - } break; case DICTIONARY: { memnew_placement(_data._mem, Dictionary(*reinterpret_cast<const Dictionary *>(p_variant._data._mem))); - } break; case ARRAY: { memnew_placement(_data._mem, Array(*reinterpret_cast<const Array *>(p_variant._data._mem))); - } break; - // arrays + // Arrays. case PACKED_BYTE_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<uint8_t> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<uint8_t>::create(); } - } break; case PACKED_INT32_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<int32_t> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<int32_t>::create(); } - } break; case PACKED_INT64_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<int64_t> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<int64_t>::create(); } - } break; case PACKED_FLOAT32_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<float> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<float>::create(); } - } break; case PACKED_FLOAT64_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<double> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<double>::create(); } - } break; case PACKED_STRING_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<String> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<String>::create(); } - } break; case PACKED_VECTOR2_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<Vector2> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<Vector2>::create(); } - } break; case PACKED_VECTOR3_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<Vector3> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<Vector3>::create(); } - } break; case PACKED_COLOR_ARRAY: { _data.packed_array = static_cast<PackedArrayRef<Color> *>(p_variant._data.packed_array)->reference(); if (!_data.packed_array) { _data.packed_array = PackedArrayRef<Color>::create(); } - } break; default: { } @@ -1333,6 +1254,7 @@ void Variant::zero() { case FLOAT: this->_data._float = 0; break; + case VECTOR2: *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2(); break; @@ -1363,9 +1285,11 @@ void Variant::zero() { case QUATERNION: *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion(); break; + case COLOR: *reinterpret_cast<Color *>(this->_data._mem) = Color(); break; + default: this->clear(); break; @@ -1377,15 +1301,8 @@ void Variant::_clear_internal() { case STRING: { reinterpret_cast<String *>(_data._mem)->~String(); } break; - /* - // no point, they don't allocate memory - VECTOR3, - PLANE, - QUATERNION, - COLOR, - VECTOR2, - RECT2 - */ + + // Math types. case TRANSFORM2D: { if (_data._transform2d) { _data._transform2d->~Transform2D(); @@ -1421,7 +1338,8 @@ void Variant::_clear_internal() { _data._projection = nullptr; } } break; - // misc types + + // Miscellaneous types. case STRING_NAME: { reinterpret_cast<StringName *>(_data._mem)->~StringName(); } break; @@ -1430,7 +1348,7 @@ void Variant::_clear_internal() { } break; case OBJECT: { if (_get_obj().id.is_ref_counted()) { - //we are safe that there is a reference here + // We are safe that there is a reference here. RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj); if (ref_counted->unreference()) { memdelete(ref_counted); @@ -1440,8 +1358,8 @@ void Variant::_clear_internal() { _get_obj().id = ObjectID(); } break; case RID: { - // not much need probably - // Can't seem to use destructor + scoping operator, so hack. + // Not much need probably. + // HACK: Can't seem to use destructor + scoping operator, so hack. typedef ::RID RID_Class; reinterpret_cast<RID_Class *>(_data._mem)->~RID_Class(); } break; @@ -1457,7 +1375,8 @@ void Variant::_clear_internal() { case ARRAY: { reinterpret_cast<Array *>(_data._mem)->~Array(); } break; - // arrays + + // Arrays. case PACKED_BYTE_ARRAY: { PackedArrayRefBase::destroy(_data.packed_array); } break; @@ -1486,7 +1405,9 @@ void Variant::_clear_internal() { PackedArrayRefBase::destroy(_data.packed_array); } break; default: { - } /* not needed */ + // Not needed, there is no point. The following do not allocate memory: + // VECTOR2, VECTOR3, RECT2, PLANE, QUATERNION, COLOR. + } } } @@ -1835,11 +1756,13 @@ String Variant::stringify(int recursion_count) const { case DICTIONARY: { const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem); if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Max recursion reached"); - return "{...}"; + ERR_PRINT("Maximum dictionary recursion reached!"); + return "{ ... }"; } - String str("{"); + // Add leading and trailing space to Dictionary printing. This distinguishes it + // from array printing on fonts that have similar-looking {} and [] characters. + String str("{ "); List<Variant> keys; d.get_key_list(&keys); @@ -1858,49 +1781,48 @@ String Variant::stringify(int recursion_count) const { if (i > 0) { str += ", "; } - str += pairs[i].key + ":" + pairs[i].value; + str += pairs[i].key + ": " + pairs[i].value; } - str += "}"; + str += " }"; return str; - } break; + } case PACKED_VECTOR2_ARRAY: { return stringify_vector(operator Vector<Vector2>(), recursion_count); - } break; + } case PACKED_VECTOR3_ARRAY: { return stringify_vector(operator Vector<Vector3>(), recursion_count); - } break; + } case PACKED_COLOR_ARRAY: { return stringify_vector(operator Vector<Color>(), recursion_count); - } break; + } case PACKED_STRING_ARRAY: { return stringify_vector(operator Vector<String>(), recursion_count); - } break; + } case PACKED_BYTE_ARRAY: { return stringify_vector(operator Vector<uint8_t>(), recursion_count); - } break; + } case PACKED_INT32_ARRAY: { return stringify_vector(operator Vector<int32_t>(), recursion_count); - } break; + } case PACKED_INT64_ARRAY: { return stringify_vector(operator Vector<int64_t>(), recursion_count); - } break; + } case PACKED_FLOAT32_ARRAY: { return stringify_vector(operator Vector<float>(), recursion_count); - } break; + } case PACKED_FLOAT64_ARRAY: { return stringify_vector(operator Vector<double>(), recursion_count); - } break; + } case ARRAY: { Array arr = operator Array(); if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Max recursion reached"); + ERR_PRINT("Maximum array recursion reached!"); return "[...]"; } return stringify_vector(arr, recursion_count); - - } break; + } case OBJECT: { if (_get_obj().obj) { if (!_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) { @@ -1911,31 +1833,27 @@ String Variant::stringify(int recursion_count) const { } else { return "<Object#null>"; } - - } break; + } case CALLABLE: { const Callable &c = *reinterpret_cast<const Callable *>(_data._mem); return c; - } break; + } case SIGNAL: { const Signal &s = *reinterpret_cast<const Signal *>(_data._mem); return s; - } break; + } case RID: { const ::RID &s = *reinterpret_cast<const ::RID *>(_data._mem); return "RID(" + itos(s.get_id()) + ")"; - } break; + } default: { return "<" + get_type_name(type) + ">"; } } - - return ""; } String Variant::to_json_string() const { - JSON json; - return json.stringify(*this); + return JSON::stringify(*this); } Variant::operator Vector2() const { @@ -3121,22 +3039,22 @@ uint32_t Variant::recursive_hash(int recursion_count) const { case PROJECTION: { uint32_t h = HASH_MURMUR3_SEED; const Projection &t = *_data._projection; - h = hash_murmur3_one_real(t.matrix[0].x, h); - h = hash_murmur3_one_real(t.matrix[0].y, h); - h = hash_murmur3_one_real(t.matrix[0].z, h); - h = hash_murmur3_one_real(t.matrix[0].w, h); - h = hash_murmur3_one_real(t.matrix[1].x, h); - h = hash_murmur3_one_real(t.matrix[1].y, h); - h = hash_murmur3_one_real(t.matrix[1].z, h); - h = hash_murmur3_one_real(t.matrix[1].w, h); - h = hash_murmur3_one_real(t.matrix[2].x, h); - h = hash_murmur3_one_real(t.matrix[2].y, h); - h = hash_murmur3_one_real(t.matrix[2].z, h); - h = hash_murmur3_one_real(t.matrix[2].w, h); - h = hash_murmur3_one_real(t.matrix[3].x, h); - h = hash_murmur3_one_real(t.matrix[3].y, h); - h = hash_murmur3_one_real(t.matrix[3].z, h); - h = hash_murmur3_one_real(t.matrix[3].w, h); + h = hash_murmur3_one_real(t.columns[0].x, h); + h = hash_murmur3_one_real(t.columns[0].y, h); + h = hash_murmur3_one_real(t.columns[0].z, h); + h = hash_murmur3_one_real(t.columns[0].w, h); + h = hash_murmur3_one_real(t.columns[1].x, h); + h = hash_murmur3_one_real(t.columns[1].y, h); + h = hash_murmur3_one_real(t.columns[1].z, h); + h = hash_murmur3_one_real(t.columns[1].w, h); + h = hash_murmur3_one_real(t.columns[2].x, h); + h = hash_murmur3_one_real(t.columns[2].y, h); + h = hash_murmur3_one_real(t.columns[2].z, h); + h = hash_murmur3_one_real(t.columns[2].w, h); + h = hash_murmur3_one_real(t.columns[3].x, h); + h = hash_murmur3_one_real(t.columns[3].y, h); + h = hash_murmur3_one_real(t.columns[3].z, h); + h = hash_murmur3_one_real(t.columns[3].w, h); return hash_fmix32(h); } break; // misc types @@ -3322,33 +3240,34 @@ uint32_t Variant::recursive_hash(int recursion_count) const { } #define hash_compare_scalar(p_lhs, p_rhs) \ - ((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs)) - -#define hash_compare_vector2(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ - (hash_compare_scalar((p_lhs).y, (p_rhs).y)) - -#define hash_compare_vector3(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ - (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ - (hash_compare_scalar((p_lhs).z, (p_rhs).z)) -#define hash_compare_vector4(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ - (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ - (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \ - (hash_compare_scalar((p_lhs).w, (p_rhs).w)) - -#define hash_compare_quaternion(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ - (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ - (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \ - (hash_compare_scalar((p_lhs).w, (p_rhs).w)) - -#define hash_compare_color(p_lhs, p_rhs) \ - (hash_compare_scalar((p_lhs).r, (p_rhs).r)) && \ - (hash_compare_scalar((p_lhs).g, (p_rhs).g)) && \ - (hash_compare_scalar((p_lhs).b, (p_rhs).b)) && \ - (hash_compare_scalar((p_lhs).a, (p_rhs).a)) + (((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs))) + +#define hash_compare_vector2(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ + hash_compare_scalar((p_lhs).y, (p_rhs).y)) + +#define hash_compare_vector3(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ + hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ + hash_compare_scalar((p_lhs).z, (p_rhs).z)) + +#define hash_compare_vector4(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ + hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ + hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ + hash_compare_scalar((p_lhs).w, (p_rhs).w)) + +#define hash_compare_quaternion(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ + hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ + hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ + hash_compare_scalar((p_lhs).w, (p_rhs).w)) + +#define hash_compare_color(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).r, (p_rhs).r) && \ + hash_compare_scalar((p_lhs).g, (p_rhs).g) && \ + hash_compare_scalar((p_lhs).b, (p_rhs).b) && \ + hash_compare_scalar((p_lhs).a, (p_rhs).a)) #define hash_compare_packed_array(p_lhs, p_rhs, p_type, p_compare_func) \ const Vector<p_type> &l = PackedArrayRef<p_type>::get_array(p_lhs); \ @@ -3405,8 +3324,8 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Rect2 *l = reinterpret_cast<const Rect2 *>(_data._mem); const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem); - return (hash_compare_vector2(l->position, r->position)) && - (hash_compare_vector2(l->size, r->size)); + return hash_compare_vector2(l->position, r->position) && + hash_compare_vector2(l->size, r->size); } break; case RECT2I: { const Rect2i *l = reinterpret_cast<const Rect2i *>(_data._mem); @@ -3420,7 +3339,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const Transform2D *r = p_variant._data._transform2d; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector2(l->columns[i], r->columns[i]))) { + if (!hash_compare_vector2(l->columns[i], r->columns[i])) { return false; } } @@ -3457,16 +3376,16 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Plane *l = reinterpret_cast<const Plane *>(_data._mem); const Plane *r = reinterpret_cast<const Plane *>(p_variant._data._mem); - return (hash_compare_vector3(l->normal, r->normal)) && - (hash_compare_scalar(l->d, r->d)); + return hash_compare_vector3(l->normal, r->normal) && + hash_compare_scalar(l->d, r->d); } break; case AABB: { const ::AABB *l = _data._aabb; const ::AABB *r = p_variant._data._aabb; - return (hash_compare_vector3(l->position, r->position) && - (hash_compare_vector3(l->size, r->size))); + return hash_compare_vector3(l->position, r->position) && + hash_compare_vector3(l->size, r->size); } break; @@ -3482,7 +3401,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Basis *r = p_variant._data._basis; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector3(l->rows[i], r->rows[i]))) { + if (!hash_compare_vector3(l->rows[i], r->rows[i])) { return false; } } @@ -3495,7 +3414,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Transform3D *r = p_variant._data._transform3d; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector3(l->basis.rows[i], r->basis.rows[i]))) { + if (!hash_compare_vector3(l->basis.rows[i], r->basis.rows[i])) { return false; } } @@ -3507,7 +3426,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Projection *r = p_variant._data._projection; for (int i = 0; i < 4; i++) { - if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) { + if (!hash_compare_vector4(l->columns[i], r->columns[i])) { return false; } } @@ -3571,7 +3490,58 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const evaluate(OP_EQUAL, *this, p_variant, r, v); return r; } +} + +bool Variant::identity_compare(const Variant &p_variant) const { + if (type != p_variant.type) { + return false; + } + + switch (type) { + case OBJECT: { + return _get_obj().obj == p_variant._get_obj().obj; + } break; + + case DICTIONARY: { + const Dictionary &l = *(reinterpret_cast<const Dictionary *>(_data._mem)); + const Dictionary &r = *(reinterpret_cast<const Dictionary *>(p_variant._data._mem)); + return l.id() == r.id(); + } break; + + case ARRAY: { + const Array &l = *(reinterpret_cast<const Array *>(_data._mem)); + const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem)); + return l.id() == r.id(); + } break; + + case PACKED_BYTE_ARRAY: + case PACKED_INT32_ARRAY: + case PACKED_INT64_ARRAY: + case PACKED_FLOAT32_ARRAY: + case PACKED_FLOAT64_ARRAY: + case PACKED_STRING_ARRAY: + case PACKED_VECTOR2_ARRAY: + case PACKED_VECTOR3_ARRAY: + case PACKED_COLOR_ARRAY: { + return _data.packed_array == p_variant._data.packed_array; + } break; + + default: { + return hash_compare(p_variant); + } + } +} +bool StringLikeVariantComparator::compare(const Variant &p_lhs, const Variant &p_rhs) { + if (p_lhs.hash_compare(p_rhs)) { + return true; + } + if (p_lhs.get_type() == Variant::STRING && p_rhs.get_type() == Variant::STRING_NAME) { + return *VariantInternal::get_string(&p_lhs) == *VariantInternal::get_string_name(&p_rhs); + } + if (p_lhs.get_type() == Variant::STRING_NAME && p_rhs.get_type() == Variant::STRING) { + return *VariantInternal::get_string_name(&p_lhs) == *VariantInternal::get_string(&p_rhs); + } return false; } @@ -3693,16 +3663,16 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { int errorarg = ce.argument; if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; + err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)); } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; + err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)); } } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; + err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount); } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; + err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount); } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; + err_text = "Method not found"; } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { err_text = "Instance is null"; } else if (ce.error == Callable::CallError::CALL_ERROR_METHOD_NOT_CONST) { @@ -3724,7 +3694,22 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, } String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce); + Vector<Variant> binds; + int args_bound; + p_callable.get_bound_arguments_ref(binds, args_bound); + if (args_bound <= 0) { + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, MAX(0, p_argcount + args_bound), ce); + } else { + Vector<const Variant *> argptrs; + argptrs.resize(p_argcount + binds.size()); + for (int i = 0; i < p_argcount; i++) { + argptrs.write[i] = p_argptrs[i]; + } + for (int i = 0; i < binds.size(); i++) { + argptrs.write[i + p_argcount] = &binds[i]; + } + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), (const Variant **)argptrs.ptr(), argptrs.size(), ce); + } } void Variant::register_types() { diff --git a/core/variant/variant.h b/core/variant/variant.h index b0738e7d44..b2f31a6d57 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_H #define VARIANT_H @@ -490,6 +490,7 @@ public: } // Only enum classes that need to be bound need this to be defined. + VARIANT_ENUM_CLASS_CONSTRUCTOR(EulerOrder) VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis) VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton) VARIANT_ENUM_CLASS_CONSTRUCTOR(Key) @@ -654,6 +655,7 @@ public: static bool has_indexing(Variant::Type p_type); static Variant::Type get_indexed_element_type(Variant::Type p_type); + static uint32_t get_indexed_element_usage(Variant::Type p_type); typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool *oob); typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool *oob); @@ -746,6 +748,7 @@ public: uint32_t recursive_hash(int recursion_count) const; bool hash_compare(const Variant &p_variant, int recursion_count = 0) const; + bool identity_compare(const Variant &p_variant) const; bool booleanize() const; String stringify(int recursion_count = 0) const; String to_json_string() const; @@ -796,6 +799,10 @@ struct VariantComparator { static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); } }; +struct StringLikeVariantComparator { + static bool compare(const Variant &p_lhs, const Variant &p_rhs); +}; + Variant::ObjData &Variant::_get_obj() { return *reinterpret_cast<ObjData *>(&_data._mem[0]); } diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 1831f7b72a..07e1442faf 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_call.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_call.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant.h" @@ -65,14 +65,40 @@ static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...) const, Variant *b template <class T, class... P> static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals); } template <class T, class... P> static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); call_with_variant_argsc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals); } +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_variant_args_ret_dv(&converted, method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_method_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_variant_args_retc_dv(&converted, method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_method_call(void (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_variant_args_dv(&converted, method, p_args, p_argcount, r_error, p_defvals); +} + +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_method_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_variant_argsc_dv(&converted, method, p_args, p_argcount, r_error, p_defvals); +} + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_method_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, p_defvals, r_error); @@ -102,6 +128,29 @@ static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Vari call_with_validated_variant_argsc(base, method, p_args); } +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_validated_variant_args_ret_helper<T, R, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_validated_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_validated_variant_args_retc_helper<T, R, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_validated_call(void (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_validated_variant_args_helper<T, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_validated_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) { + T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base))); + call_with_validated_variant_argsc_helper<T, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_validated_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) { call_with_validated_variant_args_static_retc(base, method, p_args, r_ret); @@ -142,6 +191,30 @@ static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_bas call_with_ptr_argsc(reinterpret_cast<T *>(p_base), method, p_args); } +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + T converted(*reinterpret_cast<From *>(p_base)); + call_with_ptr_args_ret(&converted, method, p_args, r_ret); +} + +template <class From, class R, class T, class... P> +static _FORCE_INLINE_ void vc_convert_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + T converted(*reinterpret_cast<From *>(p_base)); + call_with_ptr_args_retc(&converted, method, p_args, r_ret); +} + +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + T converted(*reinterpret_cast<From *>(p_base)); + call_with_ptr_args(&converted, method, p_args); +} + +template <class From, class T, class... P> +static _FORCE_INLINE_ void vc_convert_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + T converted(*reinterpret_cast<From *>(p_base)); + call_with_ptr_argsc(&converted, method, p_args); +} + template <class R, class T, class... P> static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...)) { return sizeof...(P); @@ -337,6 +410,46 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con } \ }; +#define CONVERT_METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_convert_method_call<m_class>(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + vc_convert_validated_call<m_class>(m_method_ptr, base, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_convert_ptrcall<m_class>(m_method_ptr, p_base, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type(m_method_ptr); \ + } \ + static bool is_const() { \ + return vc_is_const(m_method_ptr); \ + } \ + static bool is_static() { \ + return false; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + template <class R, class... P> static _FORCE_INLINE_ void vc_static_ptrcall(R (*method)(P...), const void **p_args, void *r_ret) { call_with_ptr_args_static_method_ret<R, P...>(method, p_args, r_ret); @@ -1422,6 +1535,16 @@ int Variant::get_enum_value(Variant::Type p_type, StringName p_enum_name, String #endif #ifdef DEBUG_METHODS_ENABLED +#define bind_convert_method(m_type_from, m_type_to, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_method, &m_type_to::m_method); \ + register_builtin_method<Method_##m_type_from##_##m_method>(m_arg_names, m_default_args); +#else +#define bind_convert_method(m_type_from, m_type_to, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_method, &m_type_to ::m_method); \ + register_builtin_method<Method_##m_type_from##_##m_method>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED #define bind_static_method(m_type, m_method, m_arg_names, m_default_args) \ STATIC_METHOD_CLASS(m_type, m_method, m_type::m_method); \ register_builtin_method<Method_##m_type##_##m_method>(m_arg_names, m_default_args); @@ -1442,6 +1565,16 @@ int Variant::get_enum_value(Variant::Type p_type, StringName p_enum_name, String #endif #ifdef DEBUG_METHODS_ENABLED +#define bind_convert_methodv(m_type_from, m_type_to, m_name, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_name, m_method); \ + register_builtin_method<Method_##m_type_from##_##m_name>(m_arg_names, m_default_args); +#else +#define bind_convert_methodv(m_type_from, m_type_to, m_name, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_name, m_method); \ + register_builtin_method<Method_##m_type_from##_##m_name>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ FUNCTION_CLASS(m_type, m_name, m_method, true); \ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); @@ -1461,6 +1594,14 @@ int Variant::get_enum_value(Variant::Type p_type, StringName p_enum_name, String register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); #endif +#define bind_string_method(m_method, m_arg_names, m_default_args) \ + bind_method(String, m_method, m_arg_names, m_default_args); \ + bind_convert_method(StringName, String, m_method, m_arg_names, m_default_args); + +#define bind_string_methodv(m_name, m_method, m_arg_names, m_default_args) \ + bind_methodv(String, m_name, m_method, m_arg_names, m_default_args); \ + bind_convert_methodv(StringName, String, m_name, m_method, m_arg_names, m_default_args); + #define bind_custom(m_type, m_name, m_method, m_has_return, m_ret_type) \ VARARG_CLASS(m_type, m_name, m_method, m_has_return, m_ret_type) \ register_builtin_method<Method_##m_type##_##m_name>(sarray(), Vector<Variant>()); @@ -1477,108 +1618,108 @@ static void _register_variant_builtin_methods() { /* String */ - bind_method(String, casecmp_to, sarray("to"), varray()); - bind_method(String, nocasecmp_to, sarray("to"), varray()); - bind_method(String, naturalnocasecmp_to, sarray("to"), varray()); - bind_method(String, length, sarray(), varray()); - bind_method(String, substr, sarray("from", "len"), varray(-1)); - bind_method(String, get_slice, sarray("delimiter", "slice"), varray()); - bind_method(String, get_slicec, sarray("delimiter", "slice"), varray()); - bind_method(String, get_slice_count, sarray("delimiter"), varray()); - bind_methodv(String, find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0)); - bind_method(String, count, sarray("what", "from", "to"), varray(0, 0)); - bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0)); - bind_method(String, findn, sarray("what", "from"), varray(0)); - bind_method(String, rfind, sarray("what", "from"), varray(-1)); - bind_method(String, rfindn, sarray("what", "from"), varray(-1)); - bind_method(String, match, sarray("expr"), varray()); - bind_method(String, matchn, sarray("expr"), varray()); - 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_ofn, sarray("text"), varray()); - bind_method(String, bigrams, sarray(), varray()); - bind_method(String, similarity, sarray("text"), varray()); - - bind_method(String, format, sarray("values", "placeholder"), varray("{_}")); - bind_methodv(String, replace, static_cast<String (String::*)(const String &, const String &) const>(&String::replace), sarray("what", "forwhat"), varray()); - bind_method(String, replacen, sarray("what", "forwhat"), varray()); - bind_method(String, repeat, sarray("count"), varray()); - bind_method(String, insert, sarray("position", "what"), varray()); - bind_method(String, capitalize, sarray(), varray()); - bind_method(String, to_camel_case, sarray(), varray()); - bind_method(String, to_pascal_case, sarray(), varray()); - bind_method(String, to_snake_case, sarray(), varray()); - bind_method(String, split, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); - bind_method(String, rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray(true, 0)); - bind_method(String, split_floats, sarray("delimiter", "allow_empty"), varray(true)); - bind_method(String, join, sarray("parts"), varray()); - - bind_method(String, to_upper, sarray(), varray()); - bind_method(String, to_lower, sarray(), varray()); - - bind_method(String, left, sarray("length"), varray()); - bind_method(String, right, sarray("length"), varray()); - - bind_method(String, strip_edges, sarray("left", "right"), varray(true, true)); - bind_method(String, strip_escapes, sarray(), varray()); - bind_method(String, lstrip, sarray("chars"), varray()); - bind_method(String, rstrip, sarray("chars"), varray()); - bind_method(String, get_extension, sarray(), varray()); - bind_method(String, get_basename, sarray(), varray()); - bind_method(String, path_join, sarray("file"), varray()); - bind_method(String, unicode_at, sarray("at"), varray()); - bind_method(String, indent, sarray("prefix"), varray()); - bind_method(String, dedent, sarray(), varray()); + bind_string_method(casecmp_to, sarray("to"), varray()); + bind_string_method(nocasecmp_to, sarray("to"), varray()); + bind_string_method(naturalnocasecmp_to, sarray("to"), varray()); + bind_string_method(length, sarray(), varray()); + bind_string_method(substr, sarray("from", "len"), varray(-1)); + bind_string_method(get_slice, sarray("delimiter", "slice"), varray()); + bind_string_method(get_slicec, sarray("delimiter", "slice"), varray()); + bind_string_method(get_slice_count, sarray("delimiter"), varray()); + bind_string_methodv(find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0)); + bind_string_method(count, sarray("what", "from", "to"), varray(0, 0)); + bind_string_method(countn, sarray("what", "from", "to"), varray(0, 0)); + bind_string_method(findn, sarray("what", "from"), varray(0)); + bind_string_method(rfind, sarray("what", "from"), varray(-1)); + bind_string_method(rfindn, sarray("what", "from"), varray(-1)); + bind_string_method(match, sarray("expr"), varray()); + bind_string_method(matchn, sarray("expr"), varray()); + bind_string_methodv(begins_with, static_cast<bool (String::*)(const String &) const>(&String::begins_with), sarray("text"), varray()); + bind_string_method(ends_with, sarray("text"), varray()); + bind_string_method(is_subsequence_of, sarray("text"), varray()); + bind_string_method(is_subsequence_ofn, sarray("text"), varray()); + bind_string_method(bigrams, sarray(), varray()); + bind_string_method(similarity, sarray("text"), varray()); + + bind_string_method(format, sarray("values", "placeholder"), varray("{_}")); + bind_string_methodv(replace, static_cast<String (String::*)(const String &, const String &) const>(&String::replace), sarray("what", "forwhat"), varray()); + bind_string_method(replacen, sarray("what", "forwhat"), varray()); + bind_string_method(repeat, sarray("count"), varray()); + bind_string_method(insert, sarray("position", "what"), varray()); + bind_string_method(capitalize, sarray(), varray()); + bind_string_method(to_camel_case, sarray(), varray()); + bind_string_method(to_pascal_case, sarray(), varray()); + bind_string_method(to_snake_case, sarray(), varray()); + bind_string_method(split, sarray("delimiter", "allow_empty", "maxsplit"), varray("", true, 0)); + bind_string_method(rsplit, sarray("delimiter", "allow_empty", "maxsplit"), varray("", true, 0)); + bind_string_method(split_floats, sarray("delimiter", "allow_empty"), varray(true)); + bind_string_method(join, sarray("parts"), varray()); + + bind_string_method(to_upper, sarray(), varray()); + bind_string_method(to_lower, sarray(), varray()); + + bind_string_method(left, sarray("length"), varray()); + bind_string_method(right, sarray("length"), varray()); + + bind_string_method(strip_edges, sarray("left", "right"), varray(true, true)); + bind_string_method(strip_escapes, sarray(), varray()); + bind_string_method(lstrip, sarray("chars"), varray()); + bind_string_method(rstrip, sarray("chars"), varray()); + bind_string_method(get_extension, sarray(), varray()); + bind_string_method(get_basename, sarray(), varray()); + bind_string_method(path_join, sarray("file"), varray()); + bind_string_method(unicode_at, sarray("at"), varray()); + bind_string_method(indent, sarray("prefix"), varray()); + bind_string_method(dedent, sarray(), varray()); bind_method(String, hash, sarray(), varray()); - bind_method(String, md5_text, sarray(), varray()); - bind_method(String, sha1_text, sarray(), varray()); - bind_method(String, sha256_text, sarray(), varray()); - bind_method(String, md5_buffer, sarray(), varray()); - 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()); - bind_method(String, simplify_path, sarray(), varray()); - bind_method(String, get_base_dir, sarray(), varray()); - bind_method(String, get_file, sarray(), varray()); - bind_method(String, xml_escape, sarray("escape_quotes"), varray(false)); - bind_method(String, xml_unescape, sarray(), varray()); - bind_method(String, uri_encode, sarray(), varray()); - bind_method(String, uri_decode, sarray(), varray()); - bind_method(String, c_escape, sarray(), varray()); - bind_method(String, c_unescape, sarray(), varray()); - bind_method(String, json_escape, sarray(), varray()); - - bind_method(String, validate_node_name, sarray(), varray()); - - bind_method(String, is_valid_identifier, sarray(), varray()); - bind_method(String, is_valid_int, sarray(), varray()); - bind_method(String, is_valid_float, sarray(), varray()); - bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false)); - bind_method(String, is_valid_html_color, sarray(), varray()); - bind_method(String, is_valid_ip_address, sarray(), varray()); - bind_method(String, is_valid_filename, sarray(), varray()); - - bind_method(String, to_int, sarray(), varray()); - bind_method(String, to_float, sarray(), varray()); - bind_method(String, hex_to_int, sarray(), varray()); - bind_method(String, bin_to_int, sarray(), varray()); - - bind_method(String, lpad, sarray("min_length", "character"), varray(" ")); - bind_method(String, rpad, sarray("min_length", "character"), varray(" ")); - bind_method(String, pad_decimals, sarray("digits"), varray()); - bind_method(String, pad_zeros, sarray("digits"), varray()); - bind_method(String, trim_prefix, sarray("prefix"), varray()); - bind_method(String, trim_suffix, sarray("suffix"), varray()); - - bind_method(String, to_ascii_buffer, sarray(), varray()); - bind_method(String, to_utf8_buffer, sarray(), varray()); - bind_method(String, to_utf16_buffer, sarray(), varray()); - bind_method(String, to_utf32_buffer, sarray(), varray()); + bind_string_method(md5_text, sarray(), varray()); + bind_string_method(sha1_text, sarray(), varray()); + bind_string_method(sha256_text, sarray(), varray()); + bind_string_method(md5_buffer, sarray(), varray()); + bind_string_method(sha1_buffer, sarray(), varray()); + bind_string_method(sha256_buffer, sarray(), varray()); + bind_string_method(is_empty, sarray(), varray()); + bind_string_methodv(contains, static_cast<bool (String::*)(const String &) const>(&String::contains), sarray("what"), varray()); + + bind_string_method(is_absolute_path, sarray(), varray()); + bind_string_method(is_relative_path, sarray(), varray()); + bind_string_method(simplify_path, sarray(), varray()); + bind_string_method(get_base_dir, sarray(), varray()); + bind_string_method(get_file, sarray(), varray()); + bind_string_method(xml_escape, sarray("escape_quotes"), varray(false)); + bind_string_method(xml_unescape, sarray(), varray()); + bind_string_method(uri_encode, sarray(), varray()); + bind_string_method(uri_decode, sarray(), varray()); + bind_string_method(c_escape, sarray(), varray()); + bind_string_method(c_unescape, sarray(), varray()); + bind_string_method(json_escape, sarray(), varray()); + + bind_string_method(validate_node_name, sarray(), varray()); + + bind_string_method(is_valid_identifier, sarray(), varray()); + bind_string_method(is_valid_int, sarray(), varray()); + bind_string_method(is_valid_float, sarray(), varray()); + bind_string_method(is_valid_hex_number, sarray("with_prefix"), varray(false)); + bind_string_method(is_valid_html_color, sarray(), varray()); + bind_string_method(is_valid_ip_address, sarray(), varray()); + bind_string_method(is_valid_filename, sarray(), varray()); + + bind_string_method(to_int, sarray(), varray()); + bind_string_method(to_float, sarray(), varray()); + bind_string_method(hex_to_int, sarray(), varray()); + bind_string_method(bin_to_int, sarray(), varray()); + + bind_string_method(lpad, sarray("min_length", "character"), varray(" ")); + bind_string_method(rpad, sarray("min_length", "character"), varray(" ")); + bind_string_method(pad_decimals, sarray("digits"), varray()); + bind_string_method(pad_zeros, sarray("digits"), varray()); + bind_string_method(trim_prefix, sarray("prefix"), varray()); + bind_string_method(trim_suffix, sarray("suffix"), varray()); + + bind_string_method(to_ascii_buffer, sarray(), varray()); + bind_string_method(to_utf8_buffer, sarray(), varray()); + bind_string_method(to_utf16_buffer, sarray(), varray()); + bind_string_method(to_utf32_buffer, sarray(), varray()); bind_static_method(String, num_scientific, sarray("number"), varray()); bind_static_method(String, num, sarray("number", "decimals"), varray(-1)); @@ -1606,6 +1747,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, is_normalized, sarray(), varray()); bind_method(Vector2, is_equal_approx, sarray("to"), varray()); bind_method(Vector2, is_zero_approx, sarray(), varray()); + bind_method(Vector2, is_finite, sarray(), varray()); bind_method(Vector2, posmod, sarray("mod"), varray()); bind_method(Vector2, posmodv, sarray("modv"), varray()); bind_method(Vector2, project, sarray("b"), varray()); @@ -1614,6 +1756,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Vector2, cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray()); bind_method(Vector2, bezier_interpolate, sarray("control_1", "control_2", "end", "t"), varray()); + bind_method(Vector2, bezier_derivative, sarray("control_1", "control_2", "end", "t"), varray()); bind_method(Vector2, max_axis_index, sarray(), varray()); bind_method(Vector2, min_axis_index, sarray(), varray()); bind_method(Vector2, move_toward, sarray("to", "delta"), varray()); @@ -1645,6 +1788,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2i, sign, sarray(), varray()); bind_method(Vector2i, abs, sarray(), varray()); bind_method(Vector2i, clamp, sarray("min", "max"), varray()); + bind_method(Vector2i, snapped, sarray("step"), varray()); /* Rect2 */ @@ -1653,6 +1797,7 @@ static void _register_variant_builtin_methods() { bind_method(Rect2, has_area, sarray(), varray()); bind_method(Rect2, has_point, sarray("point"), varray()); bind_method(Rect2, is_equal_approx, sarray("rect"), varray()); + bind_method(Rect2, is_finite, sarray(), varray()); bind_method(Rect2, intersects, sarray("b", "include_borders"), varray(false)); bind_method(Rect2, encloses, sarray("b"), varray()); bind_method(Rect2, intersection, sarray("b"), varray()); @@ -1695,6 +1840,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, is_normalized, sarray(), varray()); bind_method(Vector3, is_equal_approx, sarray("to"), varray()); bind_method(Vector3, is_zero_approx, sarray(), varray()); + bind_method(Vector3, is_finite, sarray(), varray()); bind_method(Vector3, inverse, sarray(), varray()); bind_method(Vector3, clamp, sarray("min", "max"), varray()); bind_method(Vector3, snapped, sarray("step"), varray()); @@ -1704,6 +1850,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Vector3, cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray()); bind_method(Vector3, bezier_interpolate, sarray("control_1", "control_2", "end", "t"), varray()); + bind_method(Vector3, bezier_derivative, sarray("control_1", "control_2", "end", "t"), varray()); bind_method(Vector3, move_toward, sarray("to", "delta"), varray()); bind_method(Vector3, dot, sarray("with"), varray()); bind_method(Vector3, cross, sarray("with"), varray()); @@ -1731,6 +1878,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, sign, sarray(), varray()); bind_method(Vector3i, abs, sarray(), varray()); bind_method(Vector3i, clamp, sarray("min", "max"), varray()); + bind_method(Vector3i, snapped, sarray("step"), varray()); /* Vector4 */ @@ -1759,6 +1907,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector4, inverse, sarray(), varray()); bind_method(Vector4, is_equal_approx, sarray("with"), varray()); bind_method(Vector4, is_zero_approx, sarray(), varray()); + bind_method(Vector4, is_finite, sarray(), varray()); /* Vector4i */ @@ -1769,12 +1918,14 @@ static void _register_variant_builtin_methods() { bind_method(Vector4i, sign, sarray(), varray()); bind_method(Vector4i, abs, sarray(), varray()); bind_method(Vector4i, clamp, sarray("min", "max"), varray()); + bind_method(Vector4i, snapped, sarray("step"), varray()); /* Plane */ bind_method(Plane, normalized, sarray(), varray()); - bind_method(Plane, center, sarray(), varray()); + bind_method(Plane, get_center, sarray(), varray()); bind_method(Plane, is_equal_approx, sarray("to_plane"), varray()); + bind_method(Plane, is_finite, sarray(), varray()); bind_method(Plane, is_point_over, sarray("point"), varray()); bind_method(Plane, distance_to, sarray("point"), varray()); bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON)); @@ -1790,6 +1941,7 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, normalized, sarray(), varray()); bind_method(Quaternion, is_normalized, sarray(), varray()); bind_method(Quaternion, is_equal_approx, sarray("to"), varray()); + bind_method(Quaternion, is_finite, sarray(), varray()); bind_method(Quaternion, inverse, sarray(), varray()); bind_method(Quaternion, log, sarray(), varray()); bind_method(Quaternion, exp, sarray(), varray()); @@ -1799,7 +1951,8 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Quaternion, spherical_cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray()); - bind_method(Quaternion, get_euler, sarray(), varray()); + bind_method(Quaternion, get_euler, sarray("order"), varray((int64_t)EulerOrder::YXZ)); + bind_static_method(Quaternion, from_euler, sarray("euler"), varray()); bind_method(Quaternion, get_axis, sarray(), varray()); bind_method(Quaternion, get_angle, sarray(), varray()); @@ -1829,10 +1982,6 @@ static void _register_variant_builtin_methods() { bind_static_method(Color, hex64, sarray("hex"), varray()); bind_static_method(Color, html, sarray("rgba"), varray()); bind_static_method(Color, html_is_valid, sarray("color"), varray()); - bind_static_method(Color, find_named_color, sarray("name"), varray()); - bind_static_method(Color, get_named_color_count, sarray(), varray()); - bind_static_method(Color, get_named_color_name, sarray("idx"), varray()); - bind_static_method(Color, get_named_color, sarray("idx"), varray()); bind_static_method(Color, from_string, sarray("str", "default"), varray()); bind_static_method(Color, from_hsv, sarray("h", "s", "v", "alpha"), varray(1.0)); bind_static_method(Color, from_ok_hsl, sarray("h", "s", "l", "alpha"), varray(1.0)); @@ -1867,7 +2016,10 @@ static void _register_variant_builtin_methods() { bind_method(Callable, get_object, sarray(), varray()); bind_method(Callable, get_object_id, sarray(), varray()); bind_method(Callable, get_method, sarray(), varray()); + bind_method(Callable, get_bound_arguments_count, sarray(), varray()); + bind_method(Callable, get_bound_arguments, sarray(), varray()); bind_method(Callable, hash, sarray(), varray()); + bind_method(Callable, bindv, sarray("arguments"), varray()); bind_method(Callable, unbind, sarray("argcount"), varray()); bind_custom(Callable, call, _VariantCall::func_Callable_call, true, Variant); @@ -1909,9 +2061,8 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform2D, is_equal_approx, sarray("xform"), varray()); - bind_method(Transform2D, set_rotation, sarray("rotation"), varray()); - bind_method(Transform2D, set_scale, sarray("scale"), varray()); - bind_method(Transform2D, set_skew, sarray("skew"), varray()); + bind_method(Transform2D, is_finite, sarray(), varray()); + // Do not bind functions like set_rotation, set_scale, set_skew, etc because this type is immutable and can't be modified. bind_method(Transform2D, looking_at, sarray("target"), varray(Vector2())); /* Basis */ @@ -1923,16 +2074,17 @@ static void _register_variant_builtin_methods() { bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "angle"), varray()); bind_method(Basis, scaled, sarray("scale"), varray()); bind_method(Basis, get_scale, sarray(), varray()); - bind_method(Basis, get_euler, sarray("order"), varray(Basis::EULER_ORDER_YXZ)); + bind_method(Basis, get_euler, sarray("order"), varray((int64_t)EulerOrder::YXZ)); bind_method(Basis, tdotx, sarray("with"), varray()); bind_method(Basis, tdoty, sarray("with"), varray()); bind_method(Basis, tdotz, sarray("with"), varray()); bind_method(Basis, slerp, sarray("to", "weight"), varray()); bind_method(Basis, is_equal_approx, sarray("b"), varray()); + bind_method(Basis, is_finite, sarray(), varray()); bind_method(Basis, get_rotation_quaternion, sarray(), varray()); bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); bind_static_method(Basis, from_scale, sarray("scale"), varray()); - bind_static_method(Basis, from_euler, sarray("euler", "order"), varray(Basis::EULER_ORDER_YXZ)); + bind_static_method(Basis, from_euler, sarray("euler", "order"), varray((int64_t)EulerOrder::YXZ)); /* AABB */ @@ -1943,6 +2095,7 @@ static void _register_variant_builtin_methods() { bind_method(AABB, has_surface, sarray(), varray()); bind_method(AABB, has_point, sarray("point"), varray()); bind_method(AABB, is_equal_approx, sarray("aabb"), varray()); + bind_method(AABB, is_finite, sarray(), varray()); bind_method(AABB, intersects, sarray("with"), varray()); bind_method(AABB, encloses, sarray("with"), varray()); bind_method(AABB, intersects_plane, sarray("plane"), varray()); @@ -1975,13 +2128,14 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); + bind_method(Transform3D, is_finite, sarray(), varray()); /* Projection */ bind_static_method(Projection, create_depth_correction, sarray("flip_y"), varray()); bind_static_method(Projection, create_light_atlas_rect, sarray("rect"), varray()); bind_static_method(Projection, create_perspective, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); - bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", " convergence_dist"), varray()); + bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", "convergence_dist"), varray()); bind_static_method(Projection, create_for_hmd, sarray("eye", "aspect", "intraocular_dist", "display_width", "display_to_lens", "oversample", "z_near", "z_far"), varray()); bind_static_method(Projection, create_orthogonal, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray()); bind_static_method(Projection, create_orthogonal_aspect, sarray("size", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); @@ -2025,6 +2179,8 @@ static void _register_variant_builtin_methods() { bind_method(Dictionary, values, sarray(), varray()); bind_method(Dictionary, duplicate, sarray("deep"), varray(false)); bind_method(Dictionary, get, sarray("key", "default"), varray(Variant())); + bind_method(Dictionary, make_read_only, sarray(), varray()); + bind_method(Dictionary, is_read_only, sarray(), varray()); /* Array */ @@ -2043,9 +2199,9 @@ static void _register_variant_builtin_methods() { bind_method(Array, erase, sarray("value"), varray()); bind_method(Array, front, sarray(), varray()); bind_method(Array, back, sarray(), varray()); + bind_method(Array, pick_random, sarray(), varray()); bind_method(Array, find, sarray("what", "from"), varray(0)); bind_method(Array, rfind, sarray("what", "from"), varray(-1)); - bind_method(Array, find_last, sarray("value"), varray()); bind_method(Array, count, sarray("value"), varray()); bind_method(Array, has, sarray("value"), varray()); bind_method(Array, pop_back, sarray(), varray()); @@ -2072,7 +2228,7 @@ static void _register_variant_builtin_methods() { 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, make_read_only, sarray(), varray()); bind_method(Array, is_read_only, sarray(), varray()); /* Byte Array */ @@ -2426,25 +2582,11 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1)); _VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1)); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XYZ", Basis::EULER_ORDER_XYZ); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XZY", Basis::EULER_ORDER_XZY); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YXZ", Basis::EULER_ORDER_YXZ); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YZX", Basis::EULER_ORDER_YZX); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZXY", Basis::EULER_ORDER_ZXY); - _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZYX", Basis::EULER_ORDER_ZYX); - - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_XYZ", Basis::EULER_ORDER_XYZ); - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_XZY", Basis::EULER_ORDER_XZY); - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_YXZ", Basis::EULER_ORDER_YXZ); - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_YZX", Basis::EULER_ORDER_YZX); - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_ZXY", Basis::EULER_ORDER_ZXY); - _VariantCall::add_enum_constant(Variant::BASIS, "EulerOrder", "EULER_ORDER_ZYX", Basis::EULER_ORDER_ZYX); - _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D()); _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0)); _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0)); - Transform3D identity_transform = Transform3D(); + Transform3D identity_transform; Transform3D flip_x_transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); Transform3D flip_y_transform = Transform3D(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); Transform3D flip_z_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); @@ -2453,7 +2595,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Y", flip_y_transform); _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Z", flip_z_transform); - Basis identity_basis = Basis(); + Basis identity_basis; Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1); Basis flip_y_basis = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1); Basis flip_z_basis = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 3b88dc11ca..950f4a62d8 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_construct.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_construct.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant_construct.h" @@ -68,11 +68,13 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<int64_t, int64_t>>(sarray("from")); add_constructor<VariantConstructor<int64_t, double>>(sarray("from")); add_constructor<VariantConstructor<int64_t, bool>>(sarray("from")); + add_constructor<VariantConstructorFromString<int64_t>>(sarray("from")); add_constructor<VariantConstructNoArgs<double>>(sarray()); add_constructor<VariantConstructor<double, double>>(sarray("from")); add_constructor<VariantConstructor<double, int64_t>>(sarray("from")); add_constructor<VariantConstructor<double, bool>>(sarray("from")); + add_constructor<VariantConstructorFromString<double>>(sarray("from")); add_constructor<VariantConstructNoArgs<String>>(sarray()); add_constructor<VariantConstructor<String, String>>(sarray("from")); @@ -141,7 +143,6 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle")); add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to")); add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w")); - add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler_yxz")); add_constructor<VariantConstructNoArgs<::AABB>>(sarray()); add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from")); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index 34d228f4d2..ef7bf2dfc2 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_construct.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_construct.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_CONSTRUCT_H #define VARIANT_CONSTRUCT_H @@ -222,6 +222,64 @@ public: } }; +template <class T> +class VariantConstructorFromString { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::STRING) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::STRING; + return; + } + + VariantTypeChanger<T>::change(&r_ret); + const String &src_str = *VariantGetInternalPtr<String>::get_ptr(p_args[0]); + + if (r_ret.get_type() == Variant::Type::INT) { + r_ret = src_str.to_int(); + } else if (r_ret.get_type() == Variant::Type::FLOAT) { + r_ret = src_str.to_float(); + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(r_ret); + const String &src_str = *VariantGetInternalPtr<String>::get_ptr(p_args[0]); + T ret = Variant(); + if (r_ret->get_type() == Variant::Type::INT) { + ret = src_str.to_int(); + } else if (r_ret->get_type() == Variant::Type::FLOAT) { + ret = src_str.to_float(); + } + *r_ret = ret; + } + + static void ptr_construct(void *base, const void **p_args) { + String src_str = PtrToArg<String>::convert(p_args[0]); + T dst_var = Variant(); + Variant type_test = Variant(dst_var); + if (type_test.get_type() == Variant::Type::INT) { + dst_var = src_str.to_int(); + } else if (type_test.get_type() == Variant::Type::FLOAT) { + dst_var = src_str.to_float(); + } + PtrConstruct<T>::construct(dst_var, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::STRING; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + class VariantConstructorCallableArgs { public: static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { diff --git a/core/variant/variant_destruct.cpp b/core/variant/variant_destruct.cpp index ab8303f3ae..5308eba97d 100644 --- a/core/variant/variant_destruct.cpp +++ b/core/variant/variant_destruct.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_destruct.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_destruct.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant_destruct.h" @@ -41,13 +41,8 @@ static void add_destructor() { void Variant::_register_variant_destructors() { add_destructor<VariantDestruct<String>>(); - add_destructor<VariantDestruct<Transform2D>>(); - add_destructor<VariantDestruct<::AABB>>(); - add_destructor<VariantDestruct<Basis>>(); - add_destructor<VariantDestruct<Transform3D>>(); add_destructor<VariantDestruct<StringName>>(); add_destructor<VariantDestruct<NodePath>>(); - add_destructor<VariantDestruct<::RID>>(); add_destructor<VariantDestruct<Callable>>(); add_destructor<VariantDestruct<Signal>>(); add_destructor<VariantDestruct<Dictionary>>(); diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h index 5e3478635d..c5f9c260c0 100644 --- a/core/variant/variant_destruct.h +++ b/core/variant/variant_destruct.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_destruct.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_destruct.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_DESTRUCT_H #define VARIANT_DESTRUCT_H @@ -50,13 +50,8 @@ struct VariantDestruct {}; } MAKE_PTRDESTRUCT(String); -MAKE_PTRDESTRUCT(Transform2D); -MAKE_PTRDESTRUCT(AABB); -MAKE_PTRDESTRUCT(Basis); -MAKE_PTRDESTRUCT(Transform3D); MAKE_PTRDESTRUCT(StringName); MAKE_PTRDESTRUCT(NodePath); -MAKE_PTRDESTRUCT(RID); MAKE_PTRDESTRUCT(Callable); MAKE_PTRDESTRUCT(Signal); MAKE_PTRDESTRUCT(Dictionary); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 874a183d29..21e1d21342 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_internal.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_internal.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_INTERNAL_H #define VARIANT_INTERNAL_H @@ -824,9 +824,9 @@ VARIANT_ACCESSOR_NUMBER(Vector4i::Axis) VARIANT_ACCESSOR_NUMBER(Projection::Planes) template <> -struct VariantInternalAccessor<Basis::EulerOrder> { - static _FORCE_INLINE_ Basis::EulerOrder get(const Variant *v) { return Basis::EulerOrder(*VariantInternal::get_int(v)); } - static _FORCE_INLINE_ void set(Variant *v, Basis::EulerOrder p_value) { *VariantInternal::get_int(v) = p_value; } +struct VariantInternalAccessor<EulerOrder> { + static _FORCE_INLINE_ EulerOrder get(const Variant *v) { return EulerOrder(*VariantInternal::get_int(v)); } + static _FORCE_INLINE_ void set(Variant *v, EulerOrder p_value) { *VariantInternal::get_int(v) = (int64_t)p_value; } }; template <> @@ -1047,7 +1047,7 @@ struct VariantInternalAccessor<PackedColorArray> { template <> struct VariantInternalAccessor<Object *> { static _FORCE_INLINE_ Object *get(const Variant *v) { return const_cast<Object *>(*VariantInternal::get_object(v)); } - static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { *VariantInternal::get_object(v) = const_cast<Object *>(p_value); } + static _FORCE_INLINE_ void set(Variant *v, const Object *p_value) { VariantInternal::object_assign(v, p_value); } }; template <> @@ -1314,7 +1314,7 @@ struct VariantZeroAssigner<float> { template <> struct VariantZeroAssigner<String> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string(v) = String(); } }; template <> @@ -1399,12 +1399,12 @@ struct VariantZeroAssigner<Color> { template <> struct VariantZeroAssigner<StringName> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string_name(v) = StringName(); } }; template <> struct VariantZeroAssigner<NodePath> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_node_path(v) = NodePath(); } }; template <> @@ -1414,12 +1414,12 @@ struct VariantZeroAssigner<::RID> { template <> struct VariantZeroAssigner<Callable> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_callable(v) = Callable(); } }; template <> struct VariantZeroAssigner<Signal> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_signal(v) = Signal(); } }; template <> @@ -1434,47 +1434,47 @@ struct VariantZeroAssigner<Array> { template <> struct VariantZeroAssigner<PackedByteArray> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_byte_array(v) = PackedByteArray(); } }; template <> struct VariantZeroAssigner<PackedInt32Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int32_array(v) = PackedInt32Array(); } }; template <> struct VariantZeroAssigner<PackedInt64Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int64_array(v) = PackedInt64Array(); } }; template <> struct VariantZeroAssigner<PackedFloat32Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float32_array(v) = PackedFloat32Array(); } }; template <> struct VariantZeroAssigner<PackedFloat64Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float64_array(v) = PackedFloat64Array(); } }; template <> struct VariantZeroAssigner<PackedStringArray> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string_array(v) = PackedStringArray(); } }; template <> struct VariantZeroAssigner<PackedVector2Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2_array(v) = PackedVector2Array(); } }; template <> struct VariantZeroAssigner<PackedVector3Array> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3_array(v) = PackedVector3Array(); } }; template <> struct VariantZeroAssigner<PackedColorArray> { - static _FORCE_INLINE_ void zero(Variant *v) {} + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color_array(v) = PackedColorArray(); } }; template <class T> @@ -1517,7 +1517,7 @@ struct VariantTypeAdjust<Object *> { } }; -// GDNative extension helpers. +// GDExtension helpers. template <class T> struct VariantTypeConstructor { @@ -1532,27 +1532,4 @@ struct VariantTypeConstructor { } }; -template <> -struct VariantTypeConstructor<Object *> { - _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) { - Variant *variant = reinterpret_cast<Variant *>(p_variant); - VariantInitializer<Object *>::init(variant); - Object *object = *(reinterpret_cast<Object **>(p_value)); - if (object) { - if (object->is_ref_counted()) { - if (!VariantInternal::initialize_ref(object)) { - return; - } - } - VariantInternalAccessor<Object *>::set(variant, object); - VariantInternalAccessor<ObjectID>::set(variant, object->get_instance_id()); - } - } - - _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) { - Object **value = reinterpret_cast<Object **>(p_value); - *value = VariantInternalAccessor<Object *>::get(reinterpret_cast<Variant *>(p_variant)); - } -}; - #endif // VARIANT_INTERNAL_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 6cca7955ae..59f562865d 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_op.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_op.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant_op.h" @@ -229,6 +229,20 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } }; +#define register_string_op(m_op_type, m_op_code) \ + do { \ + register_op<m_op_type<String, String>>(m_op_code, Variant::STRING, Variant::STRING); \ + register_op<m_op_type<String, StringName>>(m_op_code, Variant::STRING, Variant::STRING_NAME); \ + register_op<m_op_type<StringName, String>>(m_op_code, Variant::STRING_NAME, Variant::STRING); \ + register_op<m_op_type<StringName, StringName>>(m_op_code, Variant::STRING_NAME, Variant::STRING_NAME); \ + } while (false) + +#define register_string_modulo_op(m_class, m_type) \ + do { \ + register_op<OperatorEvaluatorStringFormat<String, m_class>>(Variant::OP_MODULE, Variant::STRING, m_type); \ + register_op<OperatorEvaluatorStringFormat<StringName, m_class>>(Variant::OP_MODULE, Variant::STRING_NAME, m_type); \ + } while (false) + void Variant::_register_variant_operators() { memset(operator_return_type_table, 0, sizeof(operator_return_type_table)); memset(operator_evaluator_table, 0, sizeof(operator_evaluator_table)); @@ -239,9 +253,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAdd<double, int64_t, double>>(Variant::OP_ADD, Variant::INT, Variant::FLOAT); register_op<OperatorEvaluatorAdd<double, double, int64_t>>(Variant::OP_ADD, Variant::FLOAT, Variant::INT); register_op<OperatorEvaluatorAdd<double, double, double>>(Variant::OP_ADD, Variant::FLOAT, Variant::FLOAT); - register_op<OperatorEvaluatorAdd<String, String, String>>(Variant::OP_ADD, Variant::STRING, Variant::STRING); - register_op<OperatorEvaluatorAdd<String, char32_t, String>>(Variant::OP_ADD, Variant::INT, Variant::STRING); - register_op<OperatorEvaluatorAdd<String, String, char32_t>>(Variant::OP_ADD, Variant::STRING, Variant::INT); + register_string_op(OperatorEvaluatorStringConcat, Variant::OP_ADD); register_op<OperatorEvaluatorAdd<Vector2, Vector2, Vector2>>(Variant::OP_ADD, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); @@ -384,10 +396,6 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDivNZ<Vector2, Vector2i, double>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::INT); - register_op<OperatorEvaluatorDiv<Vector2, Vector2, Vector2>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::VECTOR2); - register_op<OperatorEvaluatorDiv<Vector2, Vector2, double>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::FLOAT); - register_op<OperatorEvaluatorDiv<Vector2, Vector2, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::INT); - register_op<OperatorEvaluatorDiv<Vector3, Vector3, Vector3>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorDiv<Vector3, Vector3, double>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::FLOAT); register_op<OperatorEvaluatorDiv<Vector3, Vector3, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::INT); @@ -421,46 +429,46 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::INT); - register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL); - - register_op<OperatorEvaluatorStringModT<bool>>(Variant::OP_MODULE, Variant::STRING, Variant::BOOL); - register_op<OperatorEvaluatorStringModT<int64_t>>(Variant::OP_MODULE, Variant::STRING, Variant::INT); - register_op<OperatorEvaluatorStringModT<double>>(Variant::OP_MODULE, Variant::STRING, Variant::FLOAT); - register_op<OperatorEvaluatorStringModT<String>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING); - register_op<OperatorEvaluatorStringModT<Vector2>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR2); - register_op<OperatorEvaluatorStringModT<Vector2i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR2I); - register_op<OperatorEvaluatorStringModT<Rect2>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2); - register_op<OperatorEvaluatorStringModT<Rect2i>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2I); - register_op<OperatorEvaluatorStringModT<Vector3>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3); - register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I); - register_op<OperatorEvaluatorStringModT<Vector4>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4); - register_op<OperatorEvaluatorStringModT<Vector4i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4I); - register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); - register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); - register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION); - register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); - register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); - register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D); - register_op<OperatorEvaluatorStringModT<Projection>>(Variant::OP_MODULE, Variant::STRING, Variant::PROJECTION); - - register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR); - register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME); - register_op<OperatorEvaluatorStringModT<NodePath>>(Variant::OP_MODULE, Variant::STRING, Variant::NODE_PATH); - register_op<OperatorEvaluatorStringModObject>(Variant::OP_MODULE, Variant::STRING, Variant::OBJECT); - register_op<OperatorEvaluatorStringModT<Callable>>(Variant::OP_MODULE, Variant::STRING, Variant::CALLABLE); - register_op<OperatorEvaluatorStringModT<Signal>>(Variant::OP_MODULE, Variant::STRING, Variant::SIGNAL); - register_op<OperatorEvaluatorStringModT<Dictionary>>(Variant::OP_MODULE, Variant::STRING, Variant::DICTIONARY); - register_op<OperatorEvaluatorStringModArray>(Variant::OP_MODULE, Variant::STRING, Variant::ARRAY); - - register_op<OperatorEvaluatorStringModT<PackedByteArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_BYTE_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedInt32Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_INT32_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedInt64Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_INT64_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedFloat32Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_FLOAT32_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedFloat64Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_FLOAT64_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedStringArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_STRING_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedVector2Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_VECTOR2_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedVector3Array>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_VECTOR3_ARRAY); - register_op<OperatorEvaluatorStringModT<PackedColorArray>>(Variant::OP_MODULE, Variant::STRING, Variant::PACKED_COLOR_ARRAY); + register_string_modulo_op(void, Variant::NIL); + + register_string_modulo_op(bool, Variant::BOOL); + register_string_modulo_op(int64_t, Variant::INT); + register_string_modulo_op(double, Variant::FLOAT); + register_string_modulo_op(String, Variant::STRING); + register_string_modulo_op(Vector2, Variant::VECTOR2); + register_string_modulo_op(Vector2i, Variant::VECTOR2I); + register_string_modulo_op(Rect2, Variant::RECT2); + register_string_modulo_op(Rect2i, Variant::RECT2I); + register_string_modulo_op(Vector3, Variant::VECTOR3); + register_string_modulo_op(Vector3i, Variant::VECTOR3I); + register_string_modulo_op(Vector4, Variant::VECTOR4); + register_string_modulo_op(Vector4i, Variant::VECTOR4I); + register_string_modulo_op(Transform2D, Variant::TRANSFORM2D); + register_string_modulo_op(Plane, Variant::PLANE); + register_string_modulo_op(Quaternion, Variant::QUATERNION); + register_string_modulo_op(::AABB, Variant::AABB); + register_string_modulo_op(Basis, Variant::BASIS); + register_string_modulo_op(Transform3D, Variant::TRANSFORM3D); + register_string_modulo_op(Projection, Variant::PROJECTION); + + register_string_modulo_op(Color, Variant::COLOR); + register_string_modulo_op(StringName, Variant::STRING_NAME); + register_string_modulo_op(NodePath, Variant::NODE_PATH); + register_string_modulo_op(Object, Variant::OBJECT); + register_string_modulo_op(Callable, Variant::CALLABLE); + register_string_modulo_op(Signal, Variant::SIGNAL); + register_string_modulo_op(Dictionary, Variant::DICTIONARY); + register_string_modulo_op(Array, Variant::ARRAY); + + register_string_modulo_op(PackedByteArray, Variant::PACKED_BYTE_ARRAY); + register_string_modulo_op(PackedInt32Array, Variant::PACKED_INT32_ARRAY); + register_string_modulo_op(PackedInt64Array, Variant::PACKED_INT64_ARRAY); + register_string_modulo_op(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY); + register_string_modulo_op(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY); + register_string_modulo_op(PackedStringArray, Variant::PACKED_STRING_ARRAY); + register_string_modulo_op(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY); + register_string_modulo_op(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY); + register_string_modulo_op(PackedColorArray, Variant::PACKED_COLOR_ARRAY); register_op<OperatorEvaluatorPow<int64_t, int64_t, int64_t>>(Variant::OP_POWER, Variant::INT, Variant::INT); register_op<OperatorEvaluatorPow<double, int64_t, double>>(Variant::OP_POWER, Variant::INT, Variant::FLOAT); @@ -498,15 +506,13 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorBitXor<int64_t, int64_t, int64_t>>(Variant::OP_BIT_XOR, Variant::INT, Variant::INT); register_op<OperatorEvaluatorBitNeg<int64_t, int64_t>>(Variant::OP_BIT_NEGATE, Variant::INT, Variant::NIL); - register_op<OperatorEvaluatorBitNeg<int64_t, int64_t>>(Variant::OP_BIT_NEGATE, Variant::INT, Variant::NIL); - register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_EQUAL, Variant::NIL, Variant::NIL>>(Variant::OP_EQUAL, Variant::NIL, Variant::NIL); register_op<OperatorEvaluatorEqual<bool, bool>>(Variant::OP_EQUAL, Variant::BOOL, Variant::BOOL); register_op<OperatorEvaluatorEqual<int64_t, int64_t>>(Variant::OP_EQUAL, Variant::INT, Variant::INT); register_op<OperatorEvaluatorEqual<int64_t, double>>(Variant::OP_EQUAL, Variant::INT, Variant::FLOAT); register_op<OperatorEvaluatorEqual<double, int64_t>>(Variant::OP_EQUAL, Variant::FLOAT, Variant::INT); register_op<OperatorEvaluatorEqual<double, double>>(Variant::OP_EQUAL, Variant::FLOAT, Variant::FLOAT); - register_op<OperatorEvaluatorEqual<String, String>>(Variant::OP_EQUAL, Variant::STRING, Variant::STRING); + register_string_op(OperatorEvaluatorEqual, Variant::OP_EQUAL); register_op<OperatorEvaluatorEqual<Vector2, Vector2>>(Variant::OP_EQUAL, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorEqual<Vector2i, Vector2i>>(Variant::OP_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorEqual<Rect2, Rect2>>(Variant::OP_EQUAL, Variant::RECT2, Variant::RECT2); @@ -524,10 +530,6 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorEqual<Projection, Projection>>(Variant::OP_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); - register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING); - register_op<OperatorEvaluatorEqual<String, StringName>>(Variant::OP_EQUAL, Variant::STRING, Variant::STRING_NAME); - register_op<OperatorEvaluatorEqual<StringName, StringName>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING_NAME); - register_op<OperatorEvaluatorEqual<NodePath, NodePath>>(Variant::OP_EQUAL, Variant::NODE_PATH, Variant::NODE_PATH); register_op<OperatorEvaluatorEqual<::RID, ::RID>>(Variant::OP_EQUAL, Variant::RID, Variant::RID); @@ -567,6 +569,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::AABB, Variant::NIL>>(Variant::OP_EQUAL, Variant::AABB, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::BASIS, Variant::NIL>>(Variant::OP_EQUAL, Variant::BASIS, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::NIL>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::NIL); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::PROJECTION, Variant::NIL>>(Variant::OP_EQUAL, Variant::PROJECTION, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::COLOR, Variant::NIL>>(Variant::OP_EQUAL, Variant::COLOR, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::STRING_NAME, Variant::NIL>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NODE_PATH, Variant::NIL>>(Variant::OP_EQUAL, Variant::NODE_PATH, Variant::NIL); @@ -603,6 +606,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::AABB>>(Variant::OP_EQUAL, Variant::NIL, Variant::AABB); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::BASIS>>(Variant::OP_EQUAL, Variant::NIL, Variant::BASIS); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM3D>>(Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::PROJECTION>>(Variant::OP_EQUAL, Variant::NIL, Variant::PROJECTION); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::COLOR>>(Variant::OP_EQUAL, Variant::NIL, Variant::COLOR); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::STRING_NAME>>(Variant::OP_EQUAL, Variant::NIL, Variant::STRING_NAME); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::NODE_PATH>>(Variant::OP_EQUAL, Variant::NIL, Variant::NODE_PATH); @@ -627,7 +631,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotEqual<int64_t, double>>(Variant::OP_NOT_EQUAL, Variant::INT, Variant::FLOAT); register_op<OperatorEvaluatorNotEqual<double, int64_t>>(Variant::OP_NOT_EQUAL, Variant::FLOAT, Variant::INT); register_op<OperatorEvaluatorNotEqual<double, double>>(Variant::OP_NOT_EQUAL, Variant::FLOAT, Variant::FLOAT); - register_op<OperatorEvaluatorNotEqual<String, String>>(Variant::OP_NOT_EQUAL, Variant::STRING, Variant::STRING); + register_string_op(OperatorEvaluatorNotEqual, Variant::OP_NOT_EQUAL); register_op<OperatorEvaluatorNotEqual<Vector2, Vector2>>(Variant::OP_NOT_EQUAL, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorNotEqual<Vector2i, Vector2i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorNotEqual<Rect2, Rect2>>(Variant::OP_NOT_EQUAL, Variant::RECT2, Variant::RECT2); @@ -645,10 +649,6 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotEqual<Projection, Projection>>(Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); - register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING); - register_op<OperatorEvaluatorNotEqual<String, StringName>>(Variant::OP_NOT_EQUAL, Variant::STRING, Variant::STRING_NAME); - register_op<OperatorEvaluatorNotEqual<StringName, StringName>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING_NAME); - register_op<OperatorEvaluatorNotEqual<NodePath, NodePath>>(Variant::OP_NOT_EQUAL, Variant::NODE_PATH, Variant::NODE_PATH); register_op<OperatorEvaluatorNotEqual<::RID, ::RID>>(Variant::OP_NOT_EQUAL, Variant::RID, Variant::RID); @@ -688,6 +688,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::NIL); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NODE_PATH, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::NODE_PATH, Variant::NIL); @@ -724,6 +725,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::AABB>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::AABB); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::BASIS>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::BASIS); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM3D>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PROJECTION>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PROJECTION); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::COLOR>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::COLOR); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::STRING_NAME>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::STRING_NAME); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::NODE_PATH>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::NODE_PATH); @@ -899,10 +901,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotFloat>(Variant::OP_NOT, Variant::FLOAT, Variant::NIL); register_op<OperatorEvaluatorNotObject>(Variant::OP_NOT, Variant::OBJECT, Variant::NIL); - register_op<OperatorEvaluatorInStringFind<String>>(Variant::OP_IN, Variant::STRING, Variant::STRING); - register_op<OperatorEvaluatorInStringFind<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::STRING); - register_op<OperatorEvaluatorInStringNameFind<String>>(Variant::OP_IN, Variant::STRING, Variant::STRING_NAME); - register_op<OperatorEvaluatorInStringNameFind<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::STRING_NAME); + register_string_op(OperatorEvaluatorInStringFind, Variant::OP_IN); register_op<OperatorEvaluatorInDictionaryHasNil>(Variant::OP_IN, Variant::NIL, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<bool>>(Variant::OP_IN, Variant::BOOL, Variant::DICTIONARY); @@ -1000,6 +999,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInArrayFind<float, PackedFloat64Array>>(Variant::OP_IN, Variant::FLOAT, Variant::PACKED_FLOAT64_ARRAY); register_op<OperatorEvaluatorInArrayFind<String, PackedStringArray>>(Variant::OP_IN, Variant::STRING, Variant::PACKED_STRING_ARRAY); + register_op<OperatorEvaluatorInArrayFind<StringName, PackedStringArray>>(Variant::OP_IN, Variant::STRING_NAME, Variant::PACKED_STRING_ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector2, PackedVector2Array>>(Variant::OP_IN, Variant::VECTOR2, Variant::PACKED_VECTOR2_ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector3, PackedVector3Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::PACKED_VECTOR3_ARRAY); @@ -1010,6 +1010,9 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorObjectHasPropertyStringName>(Variant::OP_IN, Variant::STRING_NAME, Variant::OBJECT); } +#undef register_string_op +#undef register_string_modulo_op + void Variant::_unregister_variant_operators() { } diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index ec1ce67445..d2163cf92d 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_op.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_op.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_OP_H #define VARIANT_OP_H @@ -875,7 +875,33 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } }; -class OperatorEvaluatorStringModNil { +template <class Left, class Right> +class OperatorEvaluatorStringConcat { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String a(*VariantGetInternalPtr<Left>::get_ptr(&p_left)); + const String b(*VariantGetInternalPtr<Right>::get_ptr(&p_right)); + *r_ret = a + b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const String a(*VariantGetInternalPtr<Left>::get_ptr(left)); + const String b(*VariantGetInternalPtr<Right>::get_ptr(right)); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = a + b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + const String a(PtrToArg<Left>::convert(left)); + const String b(PtrToArg<Right>::convert(right)); + PtrToArg<String>::encode(a + b, r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <class S, class T> +class OperatorEvaluatorStringFormat; + +template <class S> +class OperatorEvaluatorStringFormat<S, void> { public: _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { Array values; @@ -888,20 +914,22 @@ public: return a; } static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, &r_valid); - r_valid = true; + *r_ret = do_mod(*VariantGetInternalPtr<S>::get_ptr(&p_left), &r_valid); } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); + bool valid = true; + String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), &valid); + ERR_FAIL_COND_MSG(!valid, result); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); + PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), nullptr), r_ret); } static Variant::Type get_return_type() { return Variant::STRING; } }; -class OperatorEvaluatorStringModArray { +template <class S> +class OperatorEvaluatorStringFormat<S, Array> { public: _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { String a = s.sprintf(p_values, r_valid); @@ -911,20 +939,22 @@ public: return a; } static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); - r_valid = true; + *r_ret = do_mod(*VariantGetInternalPtr<S>::get_ptr(&p_left), *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); + bool valid = true; + String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), &valid); + ERR_FAIL_COND_MSG(!valid, result); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); + PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); } static Variant::Type get_return_type() { return Variant::STRING; } }; -class OperatorEvaluatorStringModObject { +template <class S> +class OperatorEvaluatorStringFormat<S, Object> { public: _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { Array values; @@ -937,21 +967,22 @@ public: return a; } static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); - r_valid = true; + *r_ret = do_mod(*VariantGetInternalPtr<S>::get_ptr(&p_left), p_right.get_validated_object(), &r_valid); } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); + bool valid = true; + String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), right->get_validated_object(), &valid); + ERR_FAIL_COND_MSG(!valid, result); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); + PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); } static Variant::Type get_return_type() { return Variant::STRING; } }; -template <class T> -class OperatorEvaluatorStringModT { +template <class S, class T> +class OperatorEvaluatorStringFormat { public: _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { Array values; @@ -963,15 +994,16 @@ public: return a; } static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); - r_valid = true; + *r_ret = do_mod(*VariantGetInternalPtr<S>::get_ptr(&p_left), *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); } static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); + bool valid = true; + String result = do_mod(*VariantGetInternalPtr<S>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), &valid); + ERR_FAIL_COND_MSG(!valid, result); + *VariantGetInternalPtr<String>::get_ptr(r_ret) = result; } static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); + PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); } static Variant::Type get_return_type() { return Variant::STRING; } }; @@ -1280,8 +1312,11 @@ public: //// +template <class Left, class Right> +class OperatorEvaluatorInStringFind; + template <class Left> -class OperatorEvaluatorInStringFind { +class OperatorEvaluatorInStringFind<Left, String> { public: static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(&p_left); @@ -1302,7 +1337,7 @@ public: }; template <class Left> -class OperatorEvaluatorInStringNameFind { +class OperatorEvaluatorInStringFind<Left, StringName> { public: static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(&p_left); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 8151ff2102..87874deb8d 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_parser.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_parser.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant_parser.h" @@ -35,39 +35,93 @@ #include "core/os/keyboard.h" #include "core/string/string_buffer.h" -char32_t VariantParser::StreamFile::get_char() { - return f->get_8(); +char32_t VariantParser::Stream::get_char() { + // is within buffer? + if (readahead_pointer < readahead_filled) { + return readahead_buffer[readahead_pointer++]; + } + + // attempt to readahead + readahead_filled = _read_buffer(readahead_buffer, readahead_enabled ? READAHEAD_SIZE : 1); + if (readahead_filled) { + readahead_pointer = 0; + } else { + // EOF + readahead_pointer = 1; + eof = true; + return 0; + } + return get_char(); +} + +bool VariantParser::Stream::is_eof() const { + if (readahead_enabled) { + return eof; + } + return _is_eof(); } bool VariantParser::StreamFile::is_utf8() const { return true; } -bool VariantParser::StreamFile::is_eof() const { +bool VariantParser::StreamFile::_is_eof() const { return f->eof_reached(); } -char32_t VariantParser::StreamString::get_char() { - if (pos > s.length()) { - return 0; - } else if (pos == s.length()) { - // You need to try to read again when you have reached the end for EOF to be reported, - // so this works the same as files (like StreamFile does) - pos++; - return 0; - } else { - return s[pos++]; +uint32_t VariantParser::StreamFile::_read_buffer(char32_t *p_buffer, uint32_t p_num_chars) { + // The buffer is assumed to include at least one character (for null terminator) + ERR_FAIL_COND_V(!p_num_chars, 0); + + uint8_t *temp = (uint8_t *)alloca(p_num_chars); + uint64_t num_read = f->get_buffer(temp, p_num_chars); + ERR_FAIL_COND_V(num_read == UINT64_MAX, 0); + + // translate to wchar + for (uint32_t n = 0; n < num_read; n++) { + p_buffer[n] = temp[n]; } + + // could be less than p_num_chars, or zero + return num_read; } bool VariantParser::StreamString::is_utf8() const { return false; } -bool VariantParser::StreamString::is_eof() const { +bool VariantParser::StreamString::_is_eof() const { return pos > s.length(); } +uint32_t VariantParser::StreamString::_read_buffer(char32_t *p_buffer, uint32_t p_num_chars) { + // The buffer is assumed to include at least one character (for null terminator) + ERR_FAIL_COND_V(!p_num_chars, 0); + + int available = MAX(s.length() - pos, 0); + if (available >= (int)p_num_chars) { + const char32_t *src = s.ptr(); + src += pos; + memcpy(p_buffer, src, p_num_chars * sizeof(char32_t)); + pos += p_num_chars; + + return p_num_chars; + } + + // going to reach EOF + if (available) { + const char32_t *src = s.ptr(); + src += pos; + memcpy(p_buffer, src, available * sizeof(char32_t)); + pos += available; + } + + // add a zero + p_buffer[available] = 0; + + return available; +} + ///////////////////////////////////////////////////////////////////////////////////////////////// const char *VariantParser::tk_name[TK_MAX] = { @@ -1283,7 +1337,7 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int Variant v; err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser); - if (err) { + if (err && err != ERR_FILE_MISSING_DEPENDENCIES) { return err; } object[key] = v; @@ -1304,6 +1358,7 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin if (p_simple_tag) { r_tag.name = ""; r_tag.fields.clear(); + bool escaping = false; if (p_stream->is_utf8()) { CharString cs; @@ -1314,7 +1369,15 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin return ERR_PARSE_ERROR; } if (c == ']') { - break; + if (escaping) { + escaping = false; + } else { + break; + } + } else if (c == '\\') { + escaping = true; + } else { + escaping = false; } cs += c; } @@ -1327,7 +1390,15 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin return ERR_PARSE_ERROR; } if (c == ']') { - break; + if (escaping) { + escaping = false; + } else { + break; + } + } else if (c == '\\') { + escaping = true; + } else { + escaping = false; } r_tag.name += String::chr(c); } @@ -1651,7 +1722,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(t.matrix[i][j]); + s += rtos_fix(t.columns[i][j]); } } diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index 56b484c8bc..88be99e551 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_parser.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_parser.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_PARSER_H #define VARIANT_PARSER_H @@ -38,35 +38,55 @@ class VariantParser { public: struct Stream { - virtual char32_t get_char() = 0; - virtual bool is_utf8() const = 0; - virtual bool is_eof() const = 0; - + private: + enum { READAHEAD_SIZE = 2048 }; + char32_t readahead_buffer[READAHEAD_SIZE]; + uint32_t readahead_pointer = 0; + uint32_t readahead_filled = 0; + bool eof = false; + + protected: + bool readahead_enabled = true; + virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) = 0; + virtual bool _is_eof() const = 0; + + public: char32_t saved = 0; + char32_t get_char(); + virtual bool is_utf8() const = 0; + bool is_eof() const; + Stream() {} virtual ~Stream() {} }; struct StreamFile : public Stream { + protected: + virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) override; + virtual bool _is_eof() const override; + + public: Ref<FileAccess> f; - virtual char32_t get_char() override; virtual bool is_utf8() const override; - virtual bool is_eof() const override; - StreamFile() {} + StreamFile(bool p_readahead_enabled = true) { readahead_enabled = p_readahead_enabled; } }; struct StreamString : public Stream { String s; + + private: int pos = 0; - virtual char32_t get_char() override; - virtual bool is_utf8() const override; - virtual bool is_eof() const override; + protected: + virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) override; + virtual bool _is_eof() const override; - StreamString() {} + public: + virtual bool is_utf8() const override; + StreamString(bool p_readahead_enabled = true) { readahead_enabled = p_readahead_enabled; } }; typedef Error (*ParseResourceFunc)(void *p_self, Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index ff67b187ef..30fb5d0e9f 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_setget.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_setget.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant_setget.h" @@ -151,8 +151,8 @@ void unregister_named_setters_getters() { bool Variant::has_member(Variant::Type p_type, const StringName &p_member) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); - for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { - if (variant_setters_getters_names[p_type][i] == p_member) { + for (const StringName &member : variant_setters_getters_names[p_type]) { + if (member == p_member) { return true; } } @@ -172,8 +172,8 @@ Variant::Type Variant::get_member_type(Variant::Type p_type, const StringName &p } void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members) { - for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { - r_members->push_back(variant_setters_getters_names[p_type][i]); + for (const StringName &member : variant_setters_getters_names[p_type]) { + r_members->push_back(member); } } @@ -389,6 +389,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.write[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -460,6 +461,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.write[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -515,6 +517,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -564,6 +567,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v m_accessor[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -613,6 +617,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.m_set(index, PtrToArg<m_elem_type>::convert(member)); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -683,6 +688,7 @@ struct VariantIndexedSetGet_Array { v.set(index, PtrToArg<Variant>::convert(member)); } static Variant::Type get_index_type() { return Variant::NIL; } + static uint32_t get_index_usage() { return PROPERTY_USAGE_NIL_IS_VARIANT; } static uint64_t get_indexed_size(const Variant *base) { return 0; } }; @@ -768,6 +774,7 @@ struct VariantIndexedSetGet_String { } } static Variant::Type get_index_type() { return Variant::STRING; } + static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; } static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); } }; @@ -812,6 +819,7 @@ struct VariantIndexedSetGet_String { v[index] = PtrToArg<Variant>::convert(member); \ } \ static Variant::Type get_index_type() { return Variant::NIL; } \ + static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -826,7 +834,7 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3) -INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .matrix, 4) +INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .columns, 4) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) @@ -852,7 +860,8 @@ struct VariantIndexedSetterGetterInfo { uint64_t (*get_indexed_size)(const Variant *base) = nullptr; - Variant::Type index_type; + Variant::Type index_type = Variant::NIL; + uint32_t index_usage = PROPERTY_USAGE_DEFAULT; bool valid = false; }; @@ -872,6 +881,7 @@ static void register_indexed_member(Variant::Type p_type) { sgi.ptr_getter = T::ptr_get; sgi.index_type = T::get_index_type(); + sgi.index_usage = T::get_index_usage(); sgi.get_indexed_size = T::get_indexed_size; sgi.valid = true; @@ -920,6 +930,11 @@ Variant::Type Variant::get_indexed_element_type(Variant::Type p_type) { return variant_indexed_setters_getters[p_type].index_type; } +uint32_t Variant::get_indexed_element_usage(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, PROPERTY_USAGE_DEFAULT); + return variant_indexed_setters_getters[p_type].index_usage; +} + Variant::ValidatedIndexedSetter Variant::get_member_validated_indexed_setter(Variant::Type p_type) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); return variant_indexed_setters_getters[p_type].validated_setter; @@ -1253,7 +1268,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { return _data._int > 0; } break; case FLOAT: { - r_iter = 0; + r_iter = 0.0; return _data._float > 0.0; } break; case VECTOR2: { @@ -1457,7 +1472,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { return true; } break; case FLOAT: { - int64_t idx = r_iter; + double idx = r_iter; idx++; if (idx >= _data._float) { return false; diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h index 570277dc7a..176967344f 100644 --- a/core/variant/variant_setget.h +++ b/core/variant/variant_setget.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_setget.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_setget.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef VARIANT_SETGET_H #define VARIANT_SETGET_H @@ -325,10 +325,10 @@ SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2) SETGET_STRUCT(Transform3D, Basis, basis) SETGET_STRUCT(Transform3D, Vector3, origin) -SETGET_STRUCT_CUSTOM(Projection, Vector4, x, matrix[0]) -SETGET_STRUCT_CUSTOM(Projection, Vector4, y, matrix[1]) -SETGET_STRUCT_CUSTOM(Projection, Vector4, z, matrix[2]) -SETGET_STRUCT_CUSTOM(Projection, Vector4, w, matrix[3]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, x, columns[0]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, y, columns[1]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, z, columns[2]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, w, columns[3]) SETGET_NUMBER_STRUCT(Color, double, r) SETGET_NUMBER_STRUCT(Color, double, g) diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 670b66d53e..042ebe368a 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* variant_utility.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* variant_utility.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "variant.h" @@ -310,6 +310,10 @@ struct VariantUtilityFunctions { return Math::is_zero_approx(x); } + static inline bool is_finite(double x) { + return Math::is_finite(x); + } + static inline double ease(float x, float curve) { return Math::ease(x, curve); } @@ -318,8 +322,52 @@ struct VariantUtilityFunctions { return Math::step_decimals(step); } - static inline double snapped(double value, double step) { - return Math::snapped(value, step); + static inline Variant snapped(const Variant &x, const Variant &step, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + if (x.get_type() != step.get_type() && !((x.get_type() == Variant::INT && step.get_type() == Variant::FLOAT) || (x.get_type() == Variant::FLOAT && step.get_type() == Variant::INT))) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + return Variant(); + } + + switch (step.get_type()) { + case Variant::INT: { + return snappedi(x, VariantInternalAccessor<int64_t>::get(&step)); + } break; + case Variant::FLOAT: { + return snappedf(x, VariantInternalAccessor<double>::get(&step)); + } break; + case Variant::VECTOR2: { + return VariantInternalAccessor<Vector2>::get(&x).snapped(VariantInternalAccessor<Vector2>::get(&step)); + } break; + case Variant::VECTOR2I: { + return VariantInternalAccessor<Vector2i>::get(&x).snapped(VariantInternalAccessor<Vector2i>::get(&step)); + } break; + case Variant::VECTOR3: { + return VariantInternalAccessor<Vector3>::get(&x).snapped(VariantInternalAccessor<Vector3>::get(&step)); + } break; + case Variant::VECTOR3I: { + return VariantInternalAccessor<Vector3i>::get(&x).snapped(VariantInternalAccessor<Vector3i>::get(&step)); + } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).snapped(VariantInternalAccessor<Vector4>::get(&step)); + } break; + case Variant::VECTOR4I: { + return VariantInternalAccessor<Vector4i>::get(&x).snapped(VariantInternalAccessor<Vector4i>::get(&step)); + } break; + default: { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return Variant(); + } + } + } + + static inline double snappedf(double x, double step) { + return Math::snapped(x, step); + } + + static inline int64_t snappedi(double x, int64_t step) { + return Math::snapped(x, step); } static inline Variant lerp(const Variant &from, const Variant &to, double weight, Callable::CallError &r_error) { @@ -331,6 +379,9 @@ struct VariantUtilityFunctions { } switch (from.get_type()) { + case Variant::INT: { + return lerpf(VariantInternalAccessor<int64_t>::get(&from), to, weight); + } break; case Variant::FLOAT: { return lerpf(VariantInternalAccessor<double>::get(&from), to, weight); } break; @@ -385,6 +436,10 @@ struct VariantUtilityFunctions { return Math::bezier_interpolate(p_start, p_control_1, p_control_2, p_end, p_t); } + static inline double bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { + return Math::bezier_derivative(p_start, p_control_1, p_control_2, p_end, p_t); + } + static inline double lerp_angle(double from, double to, double weight) { return Math::lerp_angle(from, to, weight); } @@ -952,9 +1007,14 @@ struct VariantUtilityFunctions { static inline uint64_t rid_allocate_id() { return RID_AllocBase::_gen_id(); } + static inline RID rid_from_int64(uint64_t p_base) { return RID::from_uint64(p_base); } + + static inline bool is_same(const Variant &p_a, const Variant &p_b) { + return p_a.identity_compare(p_b); + } }; #ifdef DEBUG_METHODS_ENABLED @@ -1128,6 +1188,40 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) { }; \ register_utility_function<Func_##m_func>(#m_func, m_args) +#define FUNCBINDVR2(m_func, m_args, m_category) \ + class Func_##m_func { \ + public: \ + static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ + r_error.error = Callable::CallError::CALL_OK; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], r_error); \ + } \ + static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ + Callable::CallError ce; \ + *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], ce); \ + } \ + static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ + Callable::CallError ce; \ + Variant r; \ + r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), ce); \ + PtrToArg<Variant>::encode(r, ret); \ + } \ + static int get_argument_count() { \ + return 2; \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return Variant::NIL; \ + } \ + static Variant::Type get_return_type() { \ + return Variant::NIL; \ + } \ + static bool has_return_type() { \ + return true; \ + } \ + static bool is_vararg() { return false; } \ + static Variant::UtilityFunctionType get_type() { return m_category; } \ + }; \ + register_utility_function<Func_##m_func>(#m_func, m_args) + #define FUNCBINDVR3(m_func, m_args, m_category) \ class Func_##m_func { \ public: \ @@ -1411,6 +1505,10 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(signf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(signi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDVR2(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(snappedf, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(snappedi, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(pow, sarray("base", "exp"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(log, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(exp, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1420,10 +1518,10 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(is_equal_approx, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(is_zero_approx, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(is_finite, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(ease, sarray("x", "curve"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDVR3(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(lerpf, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1432,6 +1530,7 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(cubic_interpolate_in_time, sarray("from", "to", "pre", "post", "weight", "to_t", "pre_t", "post_t"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(cubic_interpolate_angle_in_time, sarray("from", "to", "pre", "post", "weight", "to_t", "pre_t", "post_t"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(bezier_interpolate, sarray("start", "control_1", "control_2", "end", "t"), Variant::UTILITY_FUNC_TYPE_MATH); + FUNCBINDR(bezier_derivative, sarray("start", "control_1", "control_2", "end", "t"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(lerp_angle, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(inverse_lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(remap, sarray("value", "istart", "istop", "ostart", "ostop"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1507,6 +1606,8 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(rid_allocate_id, Vector<String>(), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(rid_from_int64, sarray("base"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(is_same, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_GENERAL); } void Variant::_unregister_variant_utility_functions() { |