summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp37
-rw-r--r--core/variant/array.h3
-rw-r--r--core/variant/variant.cpp4
-rw-r--r--core/variant/variant_call.cpp3
-rw-r--r--core/variant/variant_op.cpp8
-rw-r--r--core/variant/variant_op.h96
6 files changed, 137 insertions, 14 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 09cf785390..8373cbd4e8 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -203,9 +203,9 @@ Error Array::resize(int p_new_size) {
return _p->array.resize(p_new_size);
}
-void Array::insert(int p_pos, const Variant &p_value) {
- ERR_FAIL_COND(!_p->typed.validate(p_value, "insert"));
- _p->array.insert(p_pos, p_value);
+Error Array::insert(int p_pos, const Variant &p_value) {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "insert"), ERR_INVALID_PARAMETER);
+ return _p->array.insert(p_pos, p_value);
}
void Array::fill(const Variant &p_value) {
@@ -535,8 +535,8 @@ void Array::push_front(const Variant &p_value) {
Variant Array::pop_back() {
if (!_p->array.is_empty()) {
- int n = _p->array.size() - 1;
- Variant ret = _p->array.get(n);
+ const int n = _p->array.size() - 1;
+ const Variant ret = _p->array.get(n);
_p->array.resize(n);
return ret;
}
@@ -545,13 +545,38 @@ Variant Array::pop_back() {
Variant Array::pop_front() {
if (!_p->array.is_empty()) {
- Variant ret = _p->array.get(0);
+ const Variant ret = _p->array.get(0);
_p->array.remove(0);
return ret;
}
return Variant();
}
+Variant Array::pop_at(int p_pos) {
+ if (_p->array.is_empty()) {
+ // Return `null` without printing an error to mimic `pop_back()` and `pop_front()` behavior.
+ return Variant();
+ }
+
+ if (p_pos < 0) {
+ // Relative offset from the end
+ p_pos = _p->array.size() + p_pos;
+ }
+
+ ERR_FAIL_INDEX_V_MSG(
+ p_pos,
+ _p->array.size(),
+ Variant(),
+ vformat(
+ "The calculated index %s is out of bounds (the array has %s elements). Leaving the array untouched and returning `null`.",
+ p_pos,
+ _p->array.size()));
+
+ const Variant ret = _p->array.get(p_pos);
+ _p->array.remove(p_pos);
+ return ret;
+}
+
Variant Array::min() const {
Variant minval;
for (int i = 0; i < size(); i++) {
diff --git a/core/variant/array.h b/core/variant/array.h
index 540dcb1f4e..4a1b25c4a9 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -72,7 +72,7 @@ public:
void append_array(const Array &p_array);
Error resize(int p_new_size);
- void insert(int p_pos, const Variant &p_value);
+ Error insert(int p_pos, const Variant &p_value);
void remove(int p_pos);
void fill(const Variant &p_value);
@@ -97,6 +97,7 @@ public:
void push_front(const Variant &p_value);
Variant pop_back();
Variant pop_front();
+ Variant pop_at(int p_pos);
Array duplicate(bool p_deep = false) const;
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index d538b9faff..c5cada674f 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -1627,9 +1627,9 @@ Variant::operator String() const {
String Variant::stringify(List<const void *> &stack) const {
switch (type) {
case NIL:
- return "Null";
+ return "null";
case BOOL:
- return _data._bool ? "True" : "False";
+ return _data._bool ? "true" : "false";
case INT:
return itos(_data._int);
case FLOAT:
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index a4817eb7d2..c9c7eca40d 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1421,7 +1421,7 @@ static void _register_variant_builtin_methods() {
//bind_method(String, humanize_size, sarray("size"), varray());
bind_method(String, is_absolute_path, sarray(), varray());
- bind_method(String, is_rel_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());
@@ -1807,6 +1807,7 @@ static void _register_variant_builtin_methods() {
bind_method(Array, has, sarray("value"), varray());
bind_method(Array, pop_back, sarray(), varray());
bind_method(Array, pop_front, sarray(), varray());
+ bind_method(Array, pop_at, sarray("position"), varray());
bind_method(Array, sort, sarray(), varray());
bind_method(Array, sort_custom, sarray("func"), varray());
bind_method(Array, shuffle, sarray(), varray());
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index 16c7428781..a245aff35b 100644
--- a/core/variant/variant_op.cpp
+++ b/core/variant/variant_op.cpp
@@ -171,7 +171,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDiv<Vector2, Vector2, double>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::FLOAT);
register_op<OperatorEvaluatorDiv<Vector2, Vector2, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::INT);
- register_op<OperatorEvaluatorDiv<Vector2i, Vector2i, Vector2i>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::VECTOR2I);
+ register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, Vector2i>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, double>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::FLOAT);
register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::INT);
@@ -183,7 +183,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDiv<Vector3, Vector3, double>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::FLOAT);
register_op<OperatorEvaluatorDiv<Vector3, Vector3, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::INT);
- register_op<OperatorEvaluatorDiv<Vector3i, Vector3i, Vector3i>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT);
register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT);
@@ -195,10 +195,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDiv<Color, Color, int64_t>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::INT);
register_op<OperatorEvaluatorModNZ<int64_t, int64_t, int64_t>>(Variant::OP_MODULE, Variant::INT, Variant::INT);
- register_op<OperatorEvaluatorMod<Vector2i, Vector2i, Vector2i>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::VECTOR2I);
+ register_op<OperatorEvaluatorModNZ<Vector2i, Vector2i, Vector2i>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorModNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::INT);
- register_op<OperatorEvaluatorMod<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT);
register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL);
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index cbdd60f404..3c9f849a4f 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -168,6 +168,54 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
+template <>
+class OperatorEvaluatorDivNZ<Vector2i, Vector2i, Vector2i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector2i &a = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_left);
+ const Vector2i &b = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0)) {
+ r_valid = false;
+ *r_ret = "Division by zero error";
+ return;
+ }
+ *r_ret = a / b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector2i>::change(r_ret);
+ *VariantGetInternalPtr<Vector2i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector2i>::get_ptr(left) / *VariantGetInternalPtr<Vector2i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector2i>::encode(PtrToArg<Vector2i>::convert(left) / PtrToArg<Vector2i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector2i>::VARIANT_TYPE; }
+};
+
+template <>
+class OperatorEvaluatorDivNZ<Vector3i, Vector3i, Vector3i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector3i &a = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_left);
+ const Vector3i &b = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0 || b.z == 0)) {
+ r_valid = false;
+ *r_ret = "Division by zero error";
+ return;
+ }
+ *r_ret = a / b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector3i>::change(r_ret);
+ *VariantGetInternalPtr<Vector3i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector3i>::get_ptr(left) / *VariantGetInternalPtr<Vector3i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector3i>::encode(PtrToArg<Vector3i>::convert(left) / PtrToArg<Vector3i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; }
+};
+
template <class R, class A, class B>
class OperatorEvaluatorMod {
public:
@@ -209,6 +257,54 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
+template <>
+class OperatorEvaluatorModNZ<Vector2i, Vector2i, Vector2i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector2i &a = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_left);
+ const Vector2i &b = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0)) {
+ r_valid = false;
+ *r_ret = "Module by zero error";
+ return;
+ }
+ *r_ret = a % b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector2i>::change(r_ret);
+ *VariantGetInternalPtr<Vector2i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector2i>::get_ptr(left) % *VariantGetInternalPtr<Vector2i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector2i>::encode(PtrToArg<Vector2i>::convert(left) / PtrToArg<Vector2i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector2i>::VARIANT_TYPE; }
+};
+
+template <>
+class OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector3i &a = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_left);
+ const Vector3i &b = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0 || b.z == 0)) {
+ r_valid = false;
+ *r_ret = "Module by zero error";
+ return;
+ }
+ *r_ret = a % b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector3i>::change(r_ret);
+ *VariantGetInternalPtr<Vector3i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector3i>::get_ptr(left) % *VariantGetInternalPtr<Vector3i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector3i>::encode(PtrToArg<Vector3i>::convert(left) % PtrToArg<Vector3i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; }
+};
+
template <class R, class A>
class OperatorEvaluatorNeg {
public: