summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp311
-rw-r--r--core/variant/array.h74
-rw-r--r--core/variant/binder_common.h97
-rw-r--r--core/variant/callable.cpp111
-rw-r--r--core/variant/callable.h64
-rw-r--r--core/variant/callable_bind.cpp118
-rw-r--r--core/variant/callable_bind.h63
-rw-r--r--core/variant/container_type_validate.h127
-rw-r--r--core/variant/dictionary.cpp134
-rw-r--r--core/variant/dictionary.h60
-rw-r--r--core/variant/method_ptrcall.h58
-rw-r--r--core/variant/native_ptr.h150
-rw-r--r--core/variant/type_info.h68
-rw-r--r--core/variant/typed_array.h100
-rw-r--r--core/variant/variant.cpp224
-rw-r--r--core/variant/variant.h68
-rw-r--r--core/variant/variant_call.cpp439
-rw-r--r--core/variant/variant_construct.cpp60
-rw-r--r--core/variant/variant_construct.h116
-rw-r--r--core/variant/variant_destruct.cpp58
-rw-r--r--core/variant/variant_destruct.h58
-rw-r--r--core/variant/variant_internal.h107
-rw-r--r--core/variant/variant_op.cpp182
-rw-r--r--core/variant/variant_op.h147
-rw-r--r--core/variant/variant_parser.cpp311
-rw-r--r--core/variant/variant_parser.h100
-rw-r--r--core/variant/variant_setget.cpp87
-rw-r--r--core/variant/variant_setget.h58
-rw-r--r--core/variant/variant_utility.cpp160
29 files changed, 2255 insertions, 1455 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index c6bbd43dc4..d156c35343 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* 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"
@@ -38,6 +38,7 @@
#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 {
@@ -53,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
}
@@ -73,7 +64,7 @@ void Array::_ref(const Array &p_from) const {
_unref();
- _p = p_from._p;
+ _p = _fp;
}
void Array::_unref() const {
@@ -200,94 +191,128 @@ uint32_t Array::recursive_hash(int recursion_count) const {
return hash_fmix32(h);
}
-bool Array::_assign(const Array &p_array) {
- 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
+void Array::operator=(const Array &p_array) {
+ if (this == &p_array) {
+ return;
+ }
+ _ref(p_array);
+}
+
+void Array::assign(const Array &p_array) {
+ const ContainerTypeValidate &typed = _p->typed;
+ const ContainerTypeValidate &source_typed = p_array._p->typed;
+
+ if (typed == source_typed || typed.type == Variant::NIL || (source_typed.type == Variant::OBJECT && typed.can_reference(source_typed))) {
+ // from same to same or
+ // from anything to variants or
+ // from subclasses to base classes
_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
- 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")) {
- return false;
- }
- }
- _p->array = p_array._p->array; //then just copy, which is cheap anyway
+ return;
+ }
- } else {
- //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case.
- Vector<Variant> new_array;
- new_array.resize(p_array._p->array.size());
- for (int i = 0; i < p_array._p->array.size(); i++) {
- Variant src_val = p_array._p->array[i];
- if (src_val.get_type() == _p->typed.type) {
- new_array.write[i] = src_val;
- } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) {
- Variant *ptr = &src_val;
- Callable::CallError ce;
- Variant::construct(_p->typed.type, new_array.write[i], (const Variant **)&ptr, 1, ce);
- if (ce.error != Callable::CallError::CALL_OK) {
- ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
- }
- } else {
- ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
- }
+ const Variant *source = p_array._p->array.ptr();
+ int size = p_array._p->array.size();
+
+ if ((source_typed.type == Variant::NIL && typed.type == Variant::OBJECT) || (source_typed.type == Variant::OBJECT && source_typed.can_reference(typed))) {
+ // from variants to objects or
+ // from base classes to subclasses
+ for (int i = 0; i < size; i++) {
+ const Variant &element = source[i];
+ if (element.get_type() != Variant::NIL && (element.get_type() != Variant::OBJECT || !typed.validate_object(element, "assign"))) {
+ ERR_FAIL_MSG(vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(element.get_type()), Variant::get_type_name(typed.type)));
}
+ }
+ _p->array = p_array._p->array;
+ return;
+ }
+ if (typed.type == Variant::OBJECT || source_typed.type == Variant::OBJECT) {
+ ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type)));
+ }
- _p->array = new_array;
+ Vector<Variant> array;
+ array.resize(size);
+ Variant *data = array.ptrw();
+
+ if (source_typed.type == Variant::NIL && typed.type != Variant::OBJECT) {
+ // from variants to primitives
+ for (int i = 0; i < size; i++) {
+ const Variant *value = source + i;
+ if (value->get_type() == typed.type) {
+ data[i] = *value;
+ continue;
+ }
+ if (!Variant::can_convert_strict(value->get_type(), typed.type)) {
+ ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(value->get_type()) + "' to '" + Variant::get_type_name(typed.type) + "'.");
+ }
+ Callable::CallError ce;
+ Variant::construct(typed.type, data[i], &value, 1, ce);
+ ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type)));
+ }
+ } else if (Variant::can_convert_strict(source_typed.type, typed.type)) {
+ // from primitives to different convertible primitives
+ for (int i = 0; i < size; i++) {
+ const Variant *value = source + i;
+ Callable::CallError ce;
+ Variant::construct(typed.type, data[i], &value, 1, ce);
+ ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type)));
}
- } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
- _ref(p_array);
} else {
- ERR_FAIL_V_MSG(false, "Assignment of arrays of incompatible types.");
+ ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type)));
}
- return true;
-}
-void Array::operator=(const Array &p_array) {
- if (this == &p_array) {
- return;
- }
- _ref(p_array);
+ _p->array = 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) {
ERR_FAIL_COND_V_MSG(_p->read_only, ERR_LOCKED, "Array is in read-only state.");
- return _p->array.resize(p_new_size);
+ Variant::Type &variant_type = _p->typed.type;
+ int old_size = _p->array.size();
+ Error err = _p->array.resize_zeroed(p_new_size);
+ if (!err && variant_type != Variant::NIL && variant_type != Variant::OBJECT) {
+ for (int i = old_size; i < p_new_size; i++) {
+ VariantInternal::initialize(&_p->array.write[i], variant_type);
+ }
+ }
+ return err;
}
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 {
@@ -306,15 +331,34 @@ Variant Array::pick_random() const {
}
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
@@ -326,7 +370,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;
}
}
@@ -334,20 +378,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++;
}
}
@@ -356,9 +396,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) {
@@ -368,9 +409,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 {
@@ -383,24 +425,22 @@ Array Array::duplicate(bool p_deep) const {
Array Array::recursive_duplicate(bool p_deep, int recursion_count) const {
Array new_arr;
+ new_arr._p->typed = _p->typed;
if (recursion_count > MAX_RECURSION) {
ERR_PRINT("Max recursion reached");
return new_arr;
}
- int element_count = size();
- new_arr.resize(element_count);
- new_arr._p->typed = _p->typed;
if (p_deep) {
recursion_count++;
+ int element_count = size();
+ new_arr.resize(element_count);
for (int i = 0; i < element_count; i++) {
new_arr[i] = get(i).recursive_duplicate(true, recursion_count);
}
} else {
- for (int i = 0; i < element_count; i++) {
- new_arr[i] = get(i);
- }
+ new_arr._p->array = _p->array;
}
return new_arr;
@@ -592,16 +632,18 @@ 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);
+int Array::bsearch(const Variant &p_value, bool p_before) const {
+ 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);
+int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) const {
+ 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() {
@@ -611,8 +653,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() {
@@ -714,11 +757,7 @@ Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_nam
_p = memnew(ArrayPrivate);
_p->refcount.init();
set_typed(p_type, p_class_name, p_script);
- _assign(p_from);
-}
-
-bool Array::typed_assign(const Array &p_other) {
- return _assign(p_other);
+ assign(p_from);
}
void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
@@ -740,6 +779,10 @@ bool Array::is_typed() const {
return _p->typed.type != Variant::NIL;
}
+bool Array::is_same_typed(const Array &p_other) const {
+ return _p->typed == p_other._p->typed;
+}
+
uint32_t Array::get_typed_builtin() const {
return _p->typed.type;
}
@@ -752,15 +795,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 ee265a9ffd..8b1f8c0678 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
@@ -43,13 +43,11 @@ class Callable;
class Array {
mutable ArrayPrivate *_p;
- void _ref(const Array &p_from) const;
void _unref() const;
-protected:
- bool _assign(const Array &p_array);
-
public:
+ void _ref(const Array &p_from) const;
+
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
@@ -68,6 +66,7 @@ public:
uint32_t recursive_hash(int recursion_count) const;
void operator=(const Array &p_array);
+ void assign(const Array &p_array);
void push_back(const Variant &p_value);
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
void append_array(const Array &p_array);
@@ -84,13 +83,12 @@ public:
void sort();
void sort_custom(const Callable &p_callable);
void shuffle();
- int bsearch(const Variant &p_value, bool p_before = true);
- int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true);
+ int bsearch(const Variant &p_value, bool p_before = true) const;
+ int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true) const;
void reverse();
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;
@@ -121,14 +119,14 @@ public:
const void *id() const;
- bool typed_assign(const Array &p_other);
void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
bool is_typed() const;
+ bool is_same_typed(const Array &p_other) const;
uint32_t get_typed_builtin() const;
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 696b27f9f2..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
@@ -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 79532d9aca..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();
}
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 32770bd663..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
@@ -98,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;
@@ -106,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;
@@ -146,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 427a337aab..ffe1dc90a3 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
@@ -41,55 +41,72 @@ struct ContainerTypeValidate {
const char *where = "container";
_FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const {
- if (type == p_type.type) {
- if (type != Variant::OBJECT) {
- return true; //nothing else to check
- }
- } else {
+ if (type != p_type.type) {
return false;
+ } else if (type != Variant::OBJECT) {
+ return true;
}
- //both are object
-
- if ((class_name != StringName()) != (p_type.class_name != StringName())) {
- return false; //both need to have class or none
- }
-
- if (class_name != p_type.class_name) {
- if (!ClassDB::is_parent_class(p_type.class_name, class_name)) {
- return false;
- }
- }
-
- if (script.is_null() != p_type.script.is_null()) {
+ if (class_name == StringName()) {
+ return true;
+ } else if (p_type.class_name == StringName()) {
+ return false;
+ } else if (class_name != p_type.class_name && !ClassDB::is_parent_class(p_type.class_name, class_name)) {
return false;
}
- if (script != p_type.script) {
- if (!p_type.script->inherits_script(script)) {
- return false;
- }
+ if (script.is_null()) {
+ return true;
+ } else if (p_type.script.is_null()) {
+ return false;
+ } else if (script != p_type.script && !p_type.script->inherits_script(script)) {
+ return false;
}
return true;
}
- _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") {
+ _FORCE_INLINE_ bool operator==(const ContainerTypeValidate &p_type) const {
+ return type == p_type.type && class_name == p_type.class_name && script == p_type.script;
+ }
+ _FORCE_INLINE_ bool operator!=(const ContainerTypeValidate &p_type) const {
+ return type != p_type.type || class_name != p_type.class_name || script != p_type.script;
+ }
+
+ // Coerces String and StringName into each other and int into float when needed.
+ _FORCE_INLINE_ bool validate(Variant &inout_variant, const char *p_operation = "use") const {
if (type == Variant::NIL) {
return true;
}
- if (type != p_variant.get_type()) {
- if (p_variant.get_type() == Variant::NIL && type == Variant::OBJECT) {
+ 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;
+ } else if (type == Variant::FLOAT && inout_variant.get_type() == Variant::INT) {
+ inout_variant = (float)inout_variant;
return true;
}
- ERR_FAIL_V_MSG(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) + "'.");
+ 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") const {
+ ERR_FAIL_COND_V(p_variant.get_type() != Variant::OBJECT, false);
+
#ifdef DEBUG_ENABLED
ObjectID object_id = p_variant;
if (object_id == ObjectID()) {
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..03e557819b 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
@@ -40,14 +40,9 @@
template <class T>
class TypedArray : public Array {
public:
- template <class U>
- _FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) {
- static_assert(__is_base_of(T, U));
- _assign(p_array);
- }
-
_FORCE_INLINE_ void operator=(const Array &p_array) {
- _assign(p_array);
+ ERR_FAIL_COND_MSG(!is_same_typed(p_array), "Cannot assign an array with a different element type.");
+ _ref(p_array);
}
_FORCE_INLINE_ TypedArray(const Variant &p_variant) :
Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
@@ -62,22 +57,23 @@ public:
//specialization for the rest of variant types
-#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
- template <> \
- class TypedArray<m_type> : public Array { \
- public: \
- _FORCE_INLINE_ void operator=(const Array &p_array) { \
- _assign(p_array); \
- } \
- _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
- Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
- } \
- _FORCE_INLINE_ TypedArray(const Array &p_array) : \
- Array(p_array, m_variant_type, StringName(), Variant()) { \
- } \
- _FORCE_INLINE_ TypedArray() { \
- set_typed(m_variant_type, StringName(), Variant()); \
- } \
+#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
+ template <> \
+ class TypedArray<m_type> : public Array { \
+ public: \
+ _FORCE_INLINE_ void operator=(const Array &p_array) { \
+ ERR_FAIL_COND_MSG(!is_same_typed(p_array), "Cannot assign an array with a different element type."); \
+ _ref(p_array); \
+ } \
+ _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
+ Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray(const Array &p_array) : \
+ Array(p_array, m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray() { \
+ set_typed(m_variant_type, StringName(), Variant()); \
+ } \
};
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index b4528e67d1..04e1561a0c 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"
@@ -940,7 +940,7 @@ bool Variant::is_zero() const {
return reinterpret_cast<const Signal *>(_data._mem)->is_null();
}
case STRING_NAME: {
- return *reinterpret_cast<const StringName *>(_data._mem) != StringName();
+ return *reinterpret_cast<const StringName *>(_data._mem) == StringName();
}
case NODE_PATH: {
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
@@ -3240,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); \
@@ -3323,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);
@@ -3338,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;
}
}
@@ -3375,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;
@@ -3400,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;
}
}
@@ -3413,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;
}
}
@@ -3425,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->columns[i], r->columns[i]))) {
+ if (!hash_compare_vector4(l->columns[i], r->columns[i])) {
return false;
}
}
@@ -3491,6 +3492,59 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const
}
}
+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;
+}
+
bool Variant::is_ref_counted() const {
return type == OBJECT && _get_obj().id.is_ref_counted();
}
@@ -3547,15 +3601,6 @@ bool Variant::is_type_shared(Variant::Type p_type) {
case OBJECT:
case ARRAY:
case DICTIONARY:
- 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 true;
default: {
}
@@ -3609,16 +3654,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) {
@@ -3640,7 +3685,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 c5be609184..f694e59051 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
@@ -346,6 +346,10 @@ public:
bool is_one() const;
bool is_null() const;
+ // Make sure Variant is not implicitly cast when accessing it with bracket notation (GH-49469).
+ Variant &operator[](const Variant &p_key) = delete;
+ const Variant &operator[](const Variant &p_key) const = delete;
+
operator bool() const;
operator signed int() const;
operator unsigned int() const; // this is the real one
@@ -655,6 +659,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);
@@ -747,6 +752,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;
@@ -797,6 +803,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 91af2bab85..0c0c8f657a 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,109 @@ 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(validate_filename, 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));
@@ -1615,6 +1757,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());
@@ -1646,6 +1789,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 */
@@ -1707,6 +1851,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());
@@ -1734,6 +1879,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 */
@@ -1773,11 +1919,12 @@ 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());
@@ -1870,7 +2017,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);
@@ -1913,9 +2063,7 @@ static void _register_variant_builtin_methods() {
bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform2D, is_equal_approx, sarray("xform"), varray());
bind_method(Transform2D, is_finite, sarray(), 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());
+ // 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 */
@@ -1988,7 +2136,7 @@ static void _register_variant_builtin_methods() {
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));
@@ -2032,6 +2180,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 */
@@ -2039,6 +2189,7 @@ static void _register_variant_builtin_methods() {
bind_method(Array, is_empty, sarray(), varray());
bind_method(Array, clear, sarray(), varray());
bind_method(Array, hash, sarray(), varray());
+ bind_method(Array, assign, sarray("array"), varray());
bind_method(Array, push_back, sarray("value"), varray());
bind_method(Array, push_front, sarray("value"), varray());
bind_method(Array, append, sarray("value"), varray());
@@ -2053,7 +2204,6 @@ static void _register_variant_builtin_methods() {
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());
@@ -2074,13 +2224,12 @@ static void _register_variant_builtin_methods() {
bind_method(Array, all, sarray("method"), varray());
bind_method(Array, max, sarray(), varray());
bind_method(Array, min, sarray(), varray());
- bind_method(Array, typed_assign, sarray("array"), varray());
- bind_method(Array, set_typed, sarray("type", "class_name", "script"), varray());
bind_method(Array, is_typed, sarray(), varray());
+ bind_method(Array, is_same_typed, sarray("array"), varray());
bind_method(Array, get_typed_builtin, sarray(), varray());
bind_method(Array, get_typed_class_name, sarray(), varray());
bind_method(Array, get_typed_script, sarray(), varray());
- bind_method(Array, set_read_only, sarray("enable"), varray());
+ bind_method(Array, make_read_only, sarray(), varray());
bind_method(Array, is_read_only, sarray(), varray());
/* Byte Array */
@@ -2254,7 +2403,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedStringArray, remove_at, sarray("index"), varray());
bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedStringArray, fill, sarray("value"), varray());
- bind_method(PackedStringArray, resize, sarray("new_size"), varray());
+ bind_methodv(PackedStringArray, resize, &PackedStringArray::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedStringArray, clear, sarray(), varray());
bind_method(PackedStringArray, has, sarray("value"), varray());
bind_method(PackedStringArray, reverse, sarray(), varray());
@@ -2278,7 +2427,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector2Array, remove_at, sarray("index"), varray());
bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector2Array, fill, sarray("value"), varray());
- bind_method(PackedVector2Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedVector2Array, resize, &PackedVector2Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedVector2Array, clear, sarray(), varray());
bind_method(PackedVector2Array, has, sarray("value"), varray());
bind_method(PackedVector2Array, reverse, sarray(), varray());
@@ -2302,7 +2451,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector3Array, remove_at, sarray("index"), varray());
bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector3Array, fill, sarray("value"), varray());
- bind_method(PackedVector3Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedVector3Array, resize, &PackedVector3Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedVector3Array, clear, sarray(), varray());
bind_method(PackedVector3Array, has, sarray("value"), varray());
bind_method(PackedVector3Array, reverse, sarray(), varray());
@@ -2326,7 +2475,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedColorArray, remove_at, sarray("index"), varray());
bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedColorArray, fill, sarray("value"), varray());
- bind_method(PackedColorArray, resize, sarray("new_size"), varray());
+ bind_methodv(PackedColorArray, resize, &PackedColorArray::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedColorArray, clear, sarray(), varray());
bind_method(PackedColorArray, has, sarray("value"), varray());
bind_method(PackedColorArray, reverse, sarray(), varray());
@@ -2438,7 +2587,7 @@ static void _register_variant_builtin_methods() {
_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);
@@ -2447,7 +2596,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 ae9727fe79..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"));
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 5117c33e2b..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"
diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h
index 2730110c0f..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
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 94e7296a99..0d55ee4ae2 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
@@ -58,7 +58,13 @@ public:
init_basis(v);
break;
case Variant::TRANSFORM3D:
- init_transform(v);
+ init_transform3d(v);
+ break;
+ case Variant::PROJECTION:
+ init_projection(v);
+ break;
+ case Variant::COLOR:
+ init_color(v);
break;
case Variant::STRING_NAME:
init_string_name(v);
@@ -209,13 +215,12 @@ public:
// Should be in the same order as Variant::Type for consistency.
// Those primitive and vector types don't need an `init_` method:
- // Nil, bool, float, Vector2/i, Rect2/i, Vector3/i, Plane, Quat, Color, RID.
+ // Nil, bool, float, Vector2/i, Rect2/i, Vector3/i, Plane, Quat, RID.
// Object is a special case, handled via `object_assign_null`.
_FORCE_INLINE_ static void init_string(Variant *v) {
memnew_placement(v->_data._mem, String);
v->type = Variant::STRING;
}
-
_FORCE_INLINE_ static void init_transform2d(Variant *v) {
v->_data._transform2d = (Transform2D *)Variant::Pools::_bucket_small.alloc();
memnew_placement(v->_data._transform2d, Transform2D);
@@ -231,7 +236,7 @@ public:
memnew_placement(v->_data._basis, Basis);
v->type = Variant::BASIS;
}
- _FORCE_INLINE_ static void init_transform(Variant *v) {
+ _FORCE_INLINE_ static void init_transform3d(Variant *v) {
v->_data._transform3d = (Transform3D *)Variant::Pools::_bucket_medium.alloc();
memnew_placement(v->_data._transform3d, Transform3D);
v->type = Variant::TRANSFORM3D;
@@ -241,6 +246,10 @@ public:
memnew_placement(v->_data._projection, Projection);
v->type = Variant::PROJECTION;
}
+ _FORCE_INLINE_ static void init_color(Variant *v) {
+ memnew_placement(v->_data._mem, Color);
+ v->type = Variant::COLOR;
+ }
_FORCE_INLINE_ static void init_string_name(Variant *v) {
memnew_placement(v->_data._mem, StringName);
v->type = Variant::STRING_NAME;
@@ -1191,7 +1200,7 @@ struct VariantInitializer<Basis> {
template <>
struct VariantInitializer<Transform3D> {
- static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); }
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform3d(v); }
};
template <>
struct VariantInitializer<Projection> {
@@ -1314,7 +1323,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 +1408,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 +1423,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 +1443,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 +1526,7 @@ struct VariantTypeAdjust<Object *> {
}
};
-// GDNative extension helpers.
+// GDExtension helpers.
template <class T>
struct VariantTypeConstructor {
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index 25bc241e9b..33c285dc6d 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,7 +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_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);
@@ -415,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,7 +512,7 @@ void Variant::_register_variant_operators() {
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);
@@ -516,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);
@@ -621,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);
@@ -639,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);
@@ -895,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);
@@ -996,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);
@@ -1006,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() {
}
@@ -1098,8 +1105,11 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
evaluate(OP_IN, p_index, *this, ret, valid);
if (r_valid) {
*r_valid = valid;
+ }
+ if (valid) {
+ ERR_FAIL_COND_V(ret.type != BOOL, false);
+ return *VariantGetInternalPtr<bool>::get_ptr(&ret);
+ } else {
return false;
}
- ERR_FAIL_COND_V(ret.type != BOOL, false);
- return *VariantGetInternalPtr<bool>::get_ptr(&ret);
}
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 d2e4d752a4..a40fcfbd47 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] = {
@@ -856,7 +910,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
bool at_key = true;
String key;
- Token token2;
bool need_comma = false;
while (true) {
@@ -866,18 +919,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
if (at_key) {
- Error err = get_token(p_stream, token2, line, r_err_str);
+ Error err = get_token(p_stream, token, line, r_err_str);
if (err != OK) {
return err;
}
- if (token2.type == TK_PARENTHESIS_CLOSE) {
+ if (token.type == TK_PARENTHESIS_CLOSE) {
value = ref.is_valid() ? Variant(ref) : Variant(obj);
return OK;
}
if (need_comma) {
- if (token2.type != TK_COMMA) {
+ if (token.type != TK_COMMA) {
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
@@ -886,31 +939,31 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- if (token2.type != TK_STRING) {
+ if (token.type != TK_STRING) {
r_err_str = "Expected property name as string";
return ERR_PARSE_ERROR;
}
- key = token2.value;
+ key = token.value;
- err = get_token(p_stream, token2, line, r_err_str);
+ err = get_token(p_stream, token, line, r_err_str);
if (err != OK) {
return err;
}
- if (token2.type != TK_COLON) {
+ if (token.type != TK_COLON) {
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key = false;
} else {
- Error err = get_token(p_stream, token2, line, r_err_str);
+ Error err = get_token(p_stream, token, line, r_err_str);
if (err != OK) {
return err;
}
Variant v;
- err = parse_value(token2, v, p_stream, line, r_err_str, p_res_parser);
+ err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
if (err) {
return err;
}
@@ -972,6 +1025,89 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
}
+ } else if (id == "Array") {
+ Error err = OK;
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_BRACKET_OPEN) {
+ r_err_str = "Expected '['";
+ return ERR_PARSE_ERROR;
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_IDENTIFIER) {
+ r_err_str = "Expected type identifier";
+ return ERR_PARSE_ERROR;
+ }
+
+ static HashMap<StringName, Variant::Type> builtin_types;
+ if (builtin_types.is_empty()) {
+ for (int i = 1; i < Variant::VARIANT_MAX; i++) {
+ builtin_types[Variant::get_type_name((Variant::Type)i)] = (Variant::Type)i;
+ }
+ }
+
+ Array array = Array();
+ bool got_bracket_token = false;
+ if (builtin_types.has(token.value)) {
+ array.set_typed(builtin_types.get(token.value), StringName(), Variant());
+ } else if (token.value == "Resource" || token.value == "SubResource" || token.value == "ExtResource") {
+ Variant resource;
+ err = parse_value(token, resource, p_stream, line, r_err_str, p_res_parser);
+ if (err) {
+ if (token.value == "Resource" && err == ERR_PARSE_ERROR && r_err_str == "Expected '('" && token.type == TK_BRACKET_CLOSE) {
+ err = OK;
+ r_err_str = String();
+ array.set_typed(Variant::OBJECT, token.value, Variant());
+ got_bracket_token = true;
+ } else {
+ return err;
+ }
+ } else {
+ Ref<Script> script = resource;
+ if (script.is_valid() && script->is_valid()) {
+ array.set_typed(Variant::OBJECT, script->get_instance_base_type(), script);
+ }
+ }
+ } else if (ClassDB::class_exists(token.value)) {
+ array.set_typed(Variant::OBJECT, token.value, Variant());
+ }
+
+ if (!got_bracket_token) {
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_BRACKET_CLOSE) {
+ r_err_str = "Expected ']'";
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_PARENTHESIS_OPEN) {
+ r_err_str = "Expected '('";
+ return ERR_PARSE_ERROR;
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_BRACKET_OPEN) {
+ r_err_str = "Expected '['";
+ return ERR_PARSE_ERROR;
+ }
+
+ Array values;
+ err = _parse_array(values, p_stream, line, r_err_str, p_res_parser);
+ if (err) {
+ return err;
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_PARENTHESIS_CLOSE) {
+ r_err_str = "Expected ')'";
+ return ERR_PARSE_ERROR;
+ }
+
+ array.assign(values);
+
+ value = array;
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
Vector<uint8_t> args;
Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
@@ -1283,7 +1419,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 +1440,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 +1451,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 +1472,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);
}
@@ -1772,6 +1925,38 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::ARRAY: {
+ Array array = p_variant;
+ if (array.get_typed_builtin() != Variant::NIL) {
+ p_store_string_func(p_store_string_ud, "Array[");
+
+ Variant::Type builtin_type = (Variant::Type)array.get_typed_builtin();
+ StringName class_name = array.get_typed_class_name();
+ Ref<Script> script = array.get_typed_script();
+
+ if (script.is_valid()) {
+ String resource_text = String();
+ if (p_encode_res_func) {
+ resource_text = p_encode_res_func(p_encode_res_ud, script);
+ }
+ if (resource_text.is_empty() && script->get_path().is_resource_file()) {
+ resource_text = "Resource(\"" + script->get_path() + "\")";
+ }
+
+ if (!resource_text.is_empty()) {
+ p_store_string_func(p_store_string_ud, resource_text);
+ } else {
+ ERR_PRINT("Failed to encode a path to a custom script for an array type.");
+ p_store_string_func(p_store_string_ud, class_name);
+ }
+ } else if (class_name != StringName()) {
+ p_store_string_func(p_store_string_ud, class_name);
+ } else {
+ p_store_string_func(p_store_string_ud, Variant::get_type_name(builtin_type));
+ }
+
+ p_store_string_func(p_store_string_ud, "](");
+ }
+
if (recursion_count > MAX_RECURSION) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "[]");
@@ -1779,7 +1964,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
recursion_count++;
p_store_string_func(p_store_string_ud, "[");
- Array array = p_variant;
int len = array.size();
for (int i = 0; i < len; i++) {
if (i > 0) {
@@ -1791,11 +1975,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "]");
}
+ if (array.get_typed_builtin() != Variant::NIL) {
+ p_store_string_func(p_store_string_ud, ")");
+ }
+
} break;
case Variant::PACKED_BYTE_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedByteArray(");
- String s;
Vector<uint8_t> data = p_variant;
int len = data.size();
const uint8_t *ptr = data.ptr();
@@ -1883,15 +2070,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
int len = data.size();
const String *ptr = data.ptr();
- String s;
- //write_string("\n");
-
for (int i = 0; i < len; i++) {
if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
}
- String str = ptr[i];
- p_store_string_func(p_store_string_ud, "\"" + str.c_escape() + "\"");
+ p_store_string_func(p_store_string_ud, "\"" + ptr[i].c_escape() + "\"");
}
p_store_string_func(p_store_string_ud, ")");
@@ -1939,9 +2122,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
}
-
p_store_string_func(p_store_string_ud, rtos_fix(ptr[i].r) + ", " + rtos_fix(ptr[i].g) + ", " + rtos_fix(ptr[i].b) + ", " + rtos_fix(ptr[i].a));
}
+
p_store_string_func(p_store_string_ud, ")");
} break;
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 188103ee5e..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(); } \
};
@@ -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 d151a85a6e..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
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 3843c32bcc..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"
@@ -322,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) {
@@ -335,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;
@@ -389,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);
}
@@ -956,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
@@ -1132,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: \
@@ -1415,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);
@@ -1428,7 +1522,6 @@ void Variant::_register_variant_utility_functions() {
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);
@@ -1437,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);
@@ -1512,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() {