Add Variant `in` operator for any String/StringName operands

Allow using String or StringName types as operand in any position of the
`in` operator, which is more convenient in scripting when interacting
with data in the engine (such as a Node name).
This commit is contained in:
George Marques 2021-10-06 22:05:13 -03:00
parent 69f80b6631
commit 13a2d03dde
No known key found for this signature in database
GPG Key ID: 046BD46A3201E43D
2 changed files with 29 additions and 4 deletions

View File

@ -641,7 +641,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorNotFloat>(Variant::OP_NOT, Variant::FLOAT, Variant::NIL);
register_op<OperatorEvaluatorNotObject>(Variant::OP_NOT, Variant::OBJECT, Variant::NIL);
register_op<OperatorEvaluatorInStringFind>(Variant::OP_IN, Variant::STRING, Variant::STRING);
register_op<OperatorEvaluatorInStringFind<String>>(Variant::OP_IN, Variant::STRING, Variant::STRING);
register_op<OperatorEvaluatorInStringFind<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::STRING);
register_op<OperatorEvaluatorInStringNameFind<String>>(Variant::OP_IN, Variant::STRING, Variant::STRING_NAME);
register_op<OperatorEvaluatorInStringNameFind<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::STRING_NAME);
register_op<OperatorEvaluatorInDictionaryHasNil>(Variant::OP_IN, Variant::NIL, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<bool>>(Variant::OP_IN, Variant::BOOL, Variant::DICTIONARY);

View File

@ -1213,22 +1213,44 @@ public:
////
template <class Left>
class OperatorEvaluatorInStringFind {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left);
const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(&p_left);
const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right);
*r_ret = str_b.find(str_a) != -1;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left);
const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(left);
const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right);
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret);
PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<Left>::convert(left)) != -1, r_ret);
}
static Variant::Type get_return_type() { return Variant::BOOL; }
};
template <class Left>
class OperatorEvaluatorInStringNameFind {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(&p_left);
const String str_b = VariantGetInternalPtr<StringName>::get_ptr(&p_right)->operator String();
*r_ret = str_b.find(str_a) != -1;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
const Left &str_a = *VariantGetInternalPtr<Left>::get_ptr(left);
const String str_b = VariantGetInternalPtr<StringName>::get_ptr(right)->operator String();
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1;
}
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);
}
static Variant::Type get_return_type() { return Variant::BOOL; }
};