2021-06-03 16:05:57 -03:00
|
|
|
/**************************************************************************/
|
|
|
|
|
/* 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. */
|
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "variant.h"
|
|
|
|
|
|
|
|
|
|
#include "core/debugger/engine_debugger.h"
|
|
|
|
|
#include "core/object/class_db.h"
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
template <typename Evaluator>
|
|
|
|
|
class CommonEvaluate {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-11-24 17:57:45 -05:00
|
|
|
VariantTypeChanger<typename Evaluator::ReturnType>::change(r_ret);
|
|
|
|
|
Evaluator::validated_evaluate(&p_left, &p_right, r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
r_valid = true;
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<typename Evaluator::ReturnType>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
|
|
|
|
class OperatorEvaluatorAdd : public CommonEvaluate<OperatorEvaluatorAdd<R, A, B>> {
|
|
|
|
|
public:
|
2021-06-03 16:05:57 -03:00
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) + VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorSub : public CommonEvaluate<OperatorEvaluatorSub<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) - VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorMul : public CommonEvaluate<OperatorEvaluatorMul<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) * VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2022-03-07 20:25:21 +03:00
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorPow : public CommonEvaluate<OperatorEvaluatorPow<R, A, B>> {
|
2022-03-07 20:25:21 +03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = R(Math::pow((double)VariantInternalAccessor<A>::get(left), (double)VariantInternalAccessor<B>::get(right)));
|
2022-03-07 20:25:21 +03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(R(Math::pow((double)PtrToArg<A>::convert(left), (double)PtrToArg<B>::convert(right))), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2022-03-07 20:25:21 +03:00
|
|
|
};
|
|
|
|
|
|
2021-06-03 16:05:57 -03:00
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorXForm : public CommonEvaluate<OperatorEvaluatorXForm<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left).xform(VariantInternalAccessor<B>::get(right));
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorXFormInv : public CommonEvaluate<OperatorEvaluatorXFormInv<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<B>::get(right).xform_inv(VariantInternalAccessor<A>::get(left));
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorDiv : public CommonEvaluate<OperatorEvaluatorDiv<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) / VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
|
|
|
|
class OperatorEvaluatorDivNZ {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const A &a = VariantInternalAccessor<A>::get(&p_left);
|
|
|
|
|
const B &b = VariantInternalAccessor<B>::get(&p_right);
|
2021-06-03 16:05:57 -03:00
|
|
|
if (b == 0) {
|
|
|
|
|
r_valid = false;
|
|
|
|
|
*r_ret = "Division by zero error";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*r_ret = a / b;
|
|
|
|
|
r_valid = true;
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) / VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-15 22:18:17 +02:00
|
|
|
template <>
|
|
|
|
|
class OperatorEvaluatorDivNZ<Vector2i, Vector2i, Vector2i> {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector2i &a = VariantInternalAccessor<Vector2i>::get(&p_left);
|
|
|
|
|
const Vector2i &b = VariantInternalAccessor<Vector2i>::get(&p_right);
|
2021-08-15 22:18:17 +02:00
|
|
|
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);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector2i>::get(r_ret) = VariantInternalAccessor<Vector2i>::get(left) / VariantInternalAccessor<Vector2i>::get(right);
|
2021-08-15 22:18:17 +02:00
|
|
|
}
|
|
|
|
|
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) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector3i &a = VariantInternalAccessor<Vector3i>::get(&p_left);
|
|
|
|
|
const Vector3i &b = VariantInternalAccessor<Vector3i>::get(&p_right);
|
2021-08-15 22:18:17 +02:00
|
|
|
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);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector3i>::get(r_ret) = VariantInternalAccessor<Vector3i>::get(left) / VariantInternalAccessor<Vector3i>::get(right);
|
2021-08-15 22:18:17 +02:00
|
|
|
}
|
|
|
|
|
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; }
|
|
|
|
|
};
|
|
|
|
|
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
template <>
|
|
|
|
|
class OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i> {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector4i &a = VariantInternalAccessor<Vector4i>::get(&p_left);
|
|
|
|
|
const Vector4i &b = VariantInternalAccessor<Vector4i>::get(&p_right);
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 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<Vector4i>::change(r_ret);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector4i>::get(r_ret) = VariantInternalAccessor<Vector4i>::get(left) / VariantInternalAccessor<Vector4i>::get(right);
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) / PtrToArg<Vector4i>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-03 16:05:57 -03:00
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorMod : public CommonEvaluate<OperatorEvaluatorMod<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) % VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
|
|
|
|
class OperatorEvaluatorModNZ {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const A &a = VariantInternalAccessor<A>::get(&p_left);
|
|
|
|
|
const B &b = VariantInternalAccessor<B>::get(&p_right);
|
2021-06-03 16:05:57 -03:00
|
|
|
if (b == 0) {
|
|
|
|
|
r_valid = false;
|
2023-08-01 04:47:18 -07:00
|
|
|
*r_ret = "Modulo by zero error";
|
2021-06-03 16:05:57 -03:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*r_ret = a % b;
|
|
|
|
|
r_valid = true;
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) % VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-15 22:18:17 +02:00
|
|
|
template <>
|
|
|
|
|
class OperatorEvaluatorModNZ<Vector2i, Vector2i, Vector2i> {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector2i &a = VariantInternalAccessor<Vector2i>::get(&p_left);
|
|
|
|
|
const Vector2i &b = VariantInternalAccessor<Vector2i>::get(&p_right);
|
2021-08-15 22:18:17 +02:00
|
|
|
if (unlikely(b.x == 0 || b.y == 0)) {
|
|
|
|
|
r_valid = false;
|
2023-08-01 04:47:18 -07:00
|
|
|
*r_ret = "Modulo by zero error";
|
2021-08-15 22:18:17 +02:00
|
|
|
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);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector2i>::get(r_ret) = VariantInternalAccessor<Vector2i>::get(left) % VariantInternalAccessor<Vector2i>::get(right);
|
2021-08-15 22:18:17 +02:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2024-11-22 13:13:41 -06:00
|
|
|
PtrToArg<Vector2i>::encode(PtrToArg<Vector2i>::convert(left) % PtrToArg<Vector2i>::convert(right), r_ret);
|
2021-08-15 22:18:17 +02:00
|
|
|
}
|
|
|
|
|
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) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector3i &a = VariantInternalAccessor<Vector3i>::get(&p_left);
|
|
|
|
|
const Vector3i &b = VariantInternalAccessor<Vector3i>::get(&p_right);
|
2021-08-15 22:18:17 +02:00
|
|
|
if (unlikely(b.x == 0 || b.y == 0 || b.z == 0)) {
|
|
|
|
|
r_valid = false;
|
2023-08-01 04:47:18 -07:00
|
|
|
*r_ret = "Modulo by zero error";
|
2021-08-15 22:18:17 +02:00
|
|
|
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);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector3i>::get(r_ret) = VariantInternalAccessor<Vector3i>::get(left) % VariantInternalAccessor<Vector3i>::get(right);
|
2021-08-15 22:18:17 +02:00
|
|
|
}
|
|
|
|
|
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; }
|
|
|
|
|
};
|
|
|
|
|
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
template <>
|
|
|
|
|
class OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i> {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Vector4i &a = VariantInternalAccessor<Vector4i>::get(&p_left);
|
|
|
|
|
const Vector4i &b = VariantInternalAccessor<Vector4i>::get(&p_right);
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) {
|
|
|
|
|
r_valid = false;
|
2023-08-01 04:47:18 -07:00
|
|
|
*r_ret = "Modulo by zero error";
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*r_ret = a % b;
|
|
|
|
|
r_valid = true;
|
|
|
|
|
}
|
|
|
|
|
static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
|
|
|
|
VariantTypeChanger<Vector4i>::change(r_ret);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector4i>::get(r_ret) = VariantInternalAccessor<Vector4i>::get(left) % VariantInternalAccessor<Vector4i>::get(right);
|
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) % PtrToArg<Vector4i>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-06-03 16:05:57 -03:00
|
|
|
template <typename R, typename A>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNeg : public CommonEvaluate<OperatorEvaluatorNeg<R, A>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = -VariantInternalAccessor<A>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorPos : public CommonEvaluate<OperatorEvaluatorPos<R, A>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
|
|
|
|
class OperatorEvaluatorShiftLeft {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const A &a = VariantInternalAccessor<A>::get(&p_left);
|
|
|
|
|
const B &b = VariantInternalAccessor<B>::get(&p_right);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
|
|
|
|
#if defined(DEBUG_ENABLED)
|
|
|
|
|
if (b < 0 || a < 0) {
|
|
|
|
|
*r_ret = "Invalid operands for bit shifting. Only positive operands are supported.";
|
|
|
|
|
r_valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
*r_ret = a << b;
|
|
|
|
|
r_valid = true;
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) << VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
|
|
|
|
class OperatorEvaluatorShiftRight {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const A &a = VariantInternalAccessor<A>::get(&p_left);
|
|
|
|
|
const B &b = VariantInternalAccessor<B>::get(&p_right);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
|
|
|
|
#if defined(DEBUG_ENABLED)
|
|
|
|
|
if (b < 0 || a < 0) {
|
|
|
|
|
*r_ret = "Invalid operands for bit shifting. Only positive operands are supported.";
|
|
|
|
|
r_valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
*r_ret = a >> b;
|
|
|
|
|
r_valid = true;
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) >> VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorBitOr : public CommonEvaluate<OperatorEvaluatorBitOr<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) | VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorBitAnd : public CommonEvaluate<OperatorEvaluatorBitAnd<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) & VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorBitXor : public CommonEvaluate<OperatorEvaluatorBitXor<R, A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = VariantInternalAccessor<A>::get(left) ^ VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename R, typename A>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorBitNeg : public CommonEvaluate<OperatorEvaluatorBitNeg<R, A>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<R>::get(r_ret) = ~VariantInternalAccessor<A>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = R;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorEqual : public CommonEvaluate<OperatorEvaluatorEqual<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) == VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorEqualObject : public CommonEvaluate<OperatorEvaluatorEqualObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
const Object *a = left->get_validated_object();
|
|
|
|
|
const Object *b = right->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = a == b;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorEqualObjectNil : public CommonEvaluate<OperatorEvaluatorEqualObjectNil> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
const Object *a = left->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = a == nullptr;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorEqualNilObject : public CommonEvaluate<OperatorEvaluatorEqualNilObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
const Object *b = right->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = nullptr == b;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotEqual : public CommonEvaluate<OperatorEvaluatorNotEqual<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) != VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotEqualObject : public CommonEvaluate<OperatorEvaluatorNotEqualObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
Object *a = left->get_validated_object();
|
|
|
|
|
Object *b = right->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = a != b;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotEqualObjectNil : public CommonEvaluate<OperatorEvaluatorNotEqualObjectNil> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
Object *a = left->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = a != nullptr;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotEqualNilObject : public CommonEvaluate<OperatorEvaluatorNotEqualNilObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2024-07-01 14:11:43 +02:00
|
|
|
Object *b = right->get_validated_object();
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = nullptr != b;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorLess : public CommonEvaluate<OperatorEvaluatorLess<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) < VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorLessEqual : public CommonEvaluate<OperatorEvaluatorLessEqual<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) <= VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorGreater : public CommonEvaluate<OperatorEvaluatorGreater<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) > VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorGreaterEqual : public CommonEvaluate<OperatorEvaluatorGreaterEqual<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) >= VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorAnd : public CommonEvaluate<OperatorEvaluatorAnd<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) && VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorOr : public CommonEvaluate<OperatorEvaluatorOr<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) || VariantInternalAccessor<B>::get(right);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b)))
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorXor : public CommonEvaluate<OperatorEvaluatorXor<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
_FORCE_INLINE_ static bool xor_op(const A &a, const B &b) {
|
|
|
|
|
return ((a) || (b)) && !((a) && (b));
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = xor_op(VariantInternalAccessor<A>::get(left), VariantInternalAccessor<B>::get(right));
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNot : public CommonEvaluate<OperatorEvaluatorNot<A>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = VariantInternalAccessor<A>::get(left) == A();
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2023-03-10 15:58:55 -03:00
|
|
|
PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == A(), r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//// CUSTOM ////
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorAddArray : public CommonEvaluate<OperatorEvaluatorAddArray> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
_FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) {
|
|
|
|
|
int asize = array_a.size();
|
|
|
|
|
int bsize = array_b.size();
|
2023-02-22 16:38:29 -05:00
|
|
|
|
|
|
|
|
if (array_a.is_typed() && array_a.is_same_typed(array_b)) {
|
|
|
|
|
sum.set_typed(array_a.get_typed_builtin(), array_a.get_typed_class_name(), array_a.get_typed_script());
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 16:05:57 -03:00
|
|
|
sum.resize(asize + bsize);
|
|
|
|
|
for (int i = 0; i < asize; i++) {
|
|
|
|
|
sum[i] = array_a[i];
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < bsize; i++) {
|
|
|
|
|
sum[i + asize] = array_b[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2022-01-18 03:00:39 +08:00
|
|
|
*r_ret = Array();
|
2025-04-10 20:19:15 +02:00
|
|
|
_add_arrays(VariantInternalAccessor<Array>::get(r_ret), VariantInternalAccessor<Array>::get(left), VariantInternalAccessor<Array>::get(right));
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
Array ret;
|
|
|
|
|
_add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right));
|
|
|
|
|
PtrToArg<Array>::encode(ret, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = Array;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorAppendArray : public CommonEvaluate<OperatorEvaluatorAppendArray<T>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<Vector<T>>::get(r_ret) = VariantInternalAccessor<Vector<T>>::get(left);
|
|
|
|
|
VariantInternalAccessor<Vector<T>>::get(r_ret).append_array(VariantInternalAccessor<Vector<T>>::get(right));
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
Vector<T> sum = PtrToArg<Vector<T>>::convert(left);
|
|
|
|
|
sum.append_array(PtrToArg<Vector<T>>::convert(right));
|
|
|
|
|
PtrToArg<Vector<T>>::encode(sum, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = Vector<T>;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2022-12-05 21:46:47 -05:00
|
|
|
template <typename Left, typename Right>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorStringConcat : public CommonEvaluate<OperatorEvaluatorStringConcat<Left, Right>> {
|
2022-12-05 21:46:47 -05:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const String a(VariantInternalAccessor<Left>::get(left));
|
|
|
|
|
const String b(VariantInternalAccessor<Right>::get(right));
|
|
|
|
|
VariantInternalAccessor<String>::get(r_ret) = a + b;
|
2022-12-05 21:46:47 -05:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = String;
|
2022-12-05 21:46:47 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename S, typename T>
|
|
|
|
|
class OperatorEvaluatorStringFormat;
|
|
|
|
|
|
|
|
|
|
template <typename S>
|
|
|
|
|
class OperatorEvaluatorStringFormat<S, void> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
_FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) {
|
2024-03-22 22:53:26 +01:00
|
|
|
Array values = { Variant() };
|
2021-06-03 16:05:57 -03:00
|
|
|
String a = s.sprintf(values, r_valid);
|
|
|
|
|
if (r_valid) {
|
|
|
|
|
*r_valid = !*r_valid;
|
|
|
|
|
}
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
*r_ret = do_mod(VariantInternalAccessor<S>::get(&p_left), &r_valid);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2022-12-05 20:24:22 +08:00
|
|
|
bool valid = true;
|
2025-04-10 20:19:15 +02:00
|
|
|
String result = do_mod(VariantInternalAccessor<S>::get(left), &valid);
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!valid)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = VariantInternalAccessor<S>::get(left);
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = result;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2022-12-05 21:46:47 -05:00
|
|
|
PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), nullptr), r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::STRING; }
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-05 21:46:47 -05:00
|
|
|
template <typename S>
|
|
|
|
|
class OperatorEvaluatorStringFormat<S, Array> {
|
2021-06-03 16:05:57 -03:00
|
|
|
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);
|
|
|
|
|
if (r_valid) {
|
|
|
|
|
*r_valid = !*r_valid;
|
|
|
|
|
}
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
*r_ret = do_mod(VariantInternalAccessor<S>::get(&p_left), VariantInternalAccessor<Array>::get(&p_right), &r_valid);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2022-12-05 20:24:22 +08:00
|
|
|
bool valid = true;
|
2025-04-10 20:19:15 +02:00
|
|
|
String result = do_mod(VariantInternalAccessor<S>::get(left), VariantInternalAccessor<Array>::get(right), &valid);
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!valid)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = VariantInternalAccessor<S>::get(left);
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = result;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2022-12-05 21:46:47 -05:00
|
|
|
PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::STRING; }
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-05 21:46:47 -05:00
|
|
|
template <typename S>
|
|
|
|
|
class OperatorEvaluatorStringFormat<S, Object> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
_FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) {
|
2024-03-22 22:53:26 +01:00
|
|
|
Array values = { p_object };
|
2021-06-03 16:05:57 -03:00
|
|
|
String a = s.sprintf(values, r_valid);
|
|
|
|
|
if (r_valid) {
|
|
|
|
|
*r_valid = !*r_valid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
*r_ret = do_mod(VariantInternalAccessor<S>::get(&p_left), p_right.get_validated_object(), &r_valid);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2022-12-05 20:24:22 +08:00
|
|
|
bool valid = true;
|
2025-04-10 20:19:15 +02:00
|
|
|
String result = do_mod(VariantInternalAccessor<S>::get(left), right->get_validated_object(), &valid);
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!valid)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = VariantInternalAccessor<S>::get(left);
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = result;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2022-12-05 21:46:47 -05:00
|
|
|
PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::STRING; }
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-05 21:46:47 -05:00
|
|
|
template <typename S, typename T>
|
|
|
|
|
class OperatorEvaluatorStringFormat {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
_FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) {
|
2024-03-22 22:53:26 +01:00
|
|
|
Array values = { p_value };
|
2021-06-03 16:05:57 -03:00
|
|
|
String a = s.sprintf(values, r_valid);
|
|
|
|
|
if (r_valid) {
|
|
|
|
|
*r_valid = !*r_valid;
|
|
|
|
|
}
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
2025-04-10 20:19:15 +02:00
|
|
|
*r_ret = do_mod(VariantInternalAccessor<S>::get(&p_left), VariantInternalAccessor<T>::get(&p_right), &r_valid);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2022-12-05 20:24:22 +08:00
|
|
|
bool valid = true;
|
2025-04-10 20:19:15 +02:00
|
|
|
String result = do_mod(VariantInternalAccessor<S>::get(left), VariantInternalAccessor<T>::get(right), &valid);
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!valid)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = VariantInternalAccessor<S>::get(left);
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG(vformat("String formatting error: %s.", result));
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<String>::get(r_ret) = result;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2022-12-05 21:46:47 -05:00
|
|
|
PtrToArg<String>::encode(do_mod(PtrToArg<S>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::STRING; }
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorAlwaysTrue : public CommonEvaluate<OperatorEvaluatorAlwaysTrue> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = true;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(true, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorAlwaysFalse : public CommonEvaluate<OperatorEvaluatorAlwaysFalse> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = false;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(false, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
///// OR ///////
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) {
|
|
|
|
|
return p_left || p_right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) {
|
|
|
|
|
return p_left && p_right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) {
|
|
|
|
|
return (p_left || p_right) && !(p_left && p_right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) {
|
|
|
|
|
return p_ptr->get_validated_object() != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) {
|
2025-04-10 20:19:15 +02:00
|
|
|
return VariantInternalAccessor<bool>::get(p_ptr);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) {
|
2025-04-10 20:19:15 +02:00
|
|
|
return VariantInternalAccessor<int64_t>::get(p_ptr) != 0;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) {
|
2025-04-10 20:19:15 +02:00
|
|
|
return VariantInternalAccessor<double>::get(p_ptr) != 0.0;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) {
|
|
|
|
|
return p_ptr->get_validated_object() != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) {
|
|
|
|
|
return PtrToArg<bool>::convert(p_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) {
|
|
|
|
|
return PtrToArg<int64_t>::convert(p_ptr) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) {
|
|
|
|
|
return PtrToArg<double>::convert(p_ptr) != 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) {
|
|
|
|
|
return PtrToArg<Object *>::convert(p_ptr) != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-10 20:19:15 +02:00
|
|
|
#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \
|
2025-11-24 17:57:45 -05:00
|
|
|
class m_class_name : public CommonEvaluate<m_class_name> { \
|
2025-04-10 20:19:15 +02:00
|
|
|
public: \
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \
|
|
|
|
|
PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool; \
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// OR
|
|
|
|
|
|
|
|
|
|
// nil
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or)
|
|
|
|
|
|
|
|
|
|
// bool
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or)
|
|
|
|
|
|
|
|
|
|
// int
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or)
|
|
|
|
|
|
|
|
|
|
// float
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or)
|
|
|
|
|
|
|
|
|
|
// object
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or)
|
|
|
|
|
|
|
|
|
|
// AND
|
|
|
|
|
|
|
|
|
|
// nil
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and)
|
|
|
|
|
|
|
|
|
|
// bool
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and)
|
|
|
|
|
|
|
|
|
|
// int
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and)
|
|
|
|
|
|
|
|
|
|
// float
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and)
|
|
|
|
|
|
|
|
|
|
// object
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and)
|
|
|
|
|
|
|
|
|
|
// XOR
|
|
|
|
|
|
|
|
|
|
// nil
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor)
|
|
|
|
|
|
|
|
|
|
// bool
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor)
|
|
|
|
|
|
|
|
|
|
// int
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor)
|
|
|
|
|
|
|
|
|
|
// float
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor)
|
|
|
|
|
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor)
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor)
|
|
|
|
|
|
|
|
|
|
// object
|
|
|
|
|
OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor)
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotBool : public CommonEvaluate<OperatorEvaluatorNotBool> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = !VariantInternalAccessor<bool>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotInt : public CommonEvaluate<OperatorEvaluatorNotInt> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = !VariantInternalAccessor<int64_t>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotFloat : public CommonEvaluate<OperatorEvaluatorNotFloat> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = !VariantInternalAccessor<double>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorNotObject : public CommonEvaluate<OperatorEvaluatorNotObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = left->get_validated_object() == nullptr;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////
|
|
|
|
|
|
2022-12-05 21:46:47 -05:00
|
|
|
template <typename Left, typename Right>
|
|
|
|
|
class OperatorEvaluatorInStringFind;
|
|
|
|
|
|
2021-10-06 22:05:13 -03:00
|
|
|
template <typename Left>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInStringFind<Left, String> : public CommonEvaluate<OperatorEvaluatorInStringFind<Left, String>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Left &str_a = VariantInternalAccessor<Left>::get(left);
|
|
|
|
|
const String &str_b = VariantInternalAccessor<String>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = str_b.find(str_a) != -1;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
2021-10-06 22:05:13 -03:00
|
|
|
PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<Left>::convert(left)) != -1, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-10-06 22:05:13 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename Left>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInStringFind<Left, StringName> : public CommonEvaluate<OperatorEvaluatorInStringFind<Left, StringName>> {
|
2021-10-06 22:05:13 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Left &str_a = VariantInternalAccessor<Left>::get(left);
|
|
|
|
|
const String str_b = VariantInternalAccessor<StringName>::get(right).operator String();
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = str_b.find(str_a) != -1;
|
2021-10-06 22:05:13 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<StringName>::convert(right).operator String().find(PtrToArg<Left>::convert(left)) != -1, r_ret);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A, typename B>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInArrayFind : public CommonEvaluate<OperatorEvaluatorInArrayFind<A, B>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const A &a = VariantInternalAccessor<A>::get(left);
|
|
|
|
|
const B &b = VariantInternalAccessor<B>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.find(a) != -1;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInArrayFindNil : public CommonEvaluate<OperatorEvaluatorInArrayFindNil> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Array &b = VariantInternalAccessor<Array>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.find(Variant()) != -1;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInArrayFindObject : public CommonEvaluate<OperatorEvaluatorInArrayFindObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Array &b = VariantInternalAccessor<Array>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.find(*left) != -1;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename A>
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInDictionaryHas : public CommonEvaluate<OperatorEvaluatorInDictionaryHas<A>> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Dictionary &b = VariantInternalAccessor<Dictionary>::get(right);
|
|
|
|
|
const A &a = VariantInternalAccessor<A>::get(left);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.has(a);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInDictionaryHasNil : public CommonEvaluate<OperatorEvaluatorInDictionaryHasNil> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Dictionary &b = VariantInternalAccessor<Dictionary>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.has(Variant());
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-24 17:57:45 -05:00
|
|
|
class OperatorEvaluatorInDictionaryHasObject : public CommonEvaluate<OperatorEvaluatorInDictionaryHasObject> {
|
2021-06-03 16:05:57 -03:00
|
|
|
public:
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
2025-04-10 20:19:15 +02:00
|
|
|
const Dictionary &b = VariantInternalAccessor<Dictionary>::get(right);
|
|
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = b.has(*left);
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret);
|
|
|
|
|
}
|
2025-11-24 17:57:45 -05:00
|
|
|
using ReturnType = bool;
|
2021-06-03 16:05:57 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class OperatorEvaluatorObjectHasPropertyString {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
|
|
|
|
Object *b = p_right.get_validated_object();
|
|
|
|
|
if (!b) {
|
|
|
|
|
*r_ret = "Invalid base object for 'in'";
|
|
|
|
|
r_valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-10 20:19:15 +02:00
|
|
|
const String &a = VariantInternalAccessor<String>::get(&p_left);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
2021-06-30 21:22:23 +02:00
|
|
|
bool exist;
|
|
|
|
|
b->get(a, &exist);
|
|
|
|
|
*r_ret = exist;
|
|
|
|
|
r_valid = true;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
|
|
|
|
Object *l = right->get_validated_object();
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!l)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = false;
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG("Invalid base object for 'in'.");
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
const String &a = VariantInternalAccessor<String>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
|
|
|
|
bool valid;
|
|
|
|
|
l->get(a, &valid);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = valid;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
bool valid;
|
|
|
|
|
PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid);
|
|
|
|
|
PtrToArg<bool>::encode(valid, r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::BOOL; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class OperatorEvaluatorObjectHasPropertyStringName {
|
|
|
|
|
public:
|
|
|
|
|
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
|
|
|
|
|
Object *b = p_right.get_validated_object();
|
|
|
|
|
if (!b) {
|
|
|
|
|
*r_ret = "Invalid base object for 'in'";
|
|
|
|
|
r_valid = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-10 20:19:15 +02:00
|
|
|
const StringName &a = VariantInternalAccessor<StringName>::get(&p_left);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
2021-06-30 21:22:23 +02:00
|
|
|
bool exist;
|
|
|
|
|
b->get(a, &exist);
|
|
|
|
|
*r_ret = exist;
|
|
|
|
|
r_valid = true;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
|
|
|
|
|
Object *l = right->get_validated_object();
|
2024-08-05 11:03:14 -04:00
|
|
|
if (unlikely(!l)) {
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = false;
|
2024-08-05 11:03:14 -04:00
|
|
|
ERR_FAIL_MSG("Invalid base object for 'in'.");
|
|
|
|
|
}
|
2025-04-10 20:19:15 +02:00
|
|
|
const StringName &a = VariantInternalAccessor<StringName>::get(left);
|
2021-06-03 16:05:57 -03:00
|
|
|
|
|
|
|
|
bool valid;
|
|
|
|
|
l->get(a, &valid);
|
2025-04-10 20:19:15 +02:00
|
|
|
VariantInternalAccessor<bool>::get(r_ret) = valid;
|
2021-06-03 16:05:57 -03:00
|
|
|
}
|
|
|
|
|
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
|
|
|
|
|
bool valid;
|
|
|
|
|
PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid);
|
|
|
|
|
PtrToArg<bool>::encode(valid, r_ret);
|
|
|
|
|
}
|
|
|
|
|
static Variant::Type get_return_type() { return Variant::BOOL; }
|
|
|
|
|
};
|