Merge pull request #11388 from hpvb/fix-missing-return-fail
Be type-strict checking on equality checks
This commit is contained in:
commit
d58b0a5c9a
6 changed files with 83 additions and 172 deletions
|
@ -390,7 +390,7 @@ public:
|
||||||
uint32_t hash() const;
|
uint32_t hash() const;
|
||||||
|
|
||||||
bool hash_compare(const Variant &p_variant) const;
|
bool hash_compare(const Variant &p_variant) const;
|
||||||
bool booleanize(bool &valid) const;
|
bool booleanize() const;
|
||||||
|
|
||||||
void static_assign(const Variant &p_variant);
|
void static_assign(const Variant &p_variant);
|
||||||
static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list);
|
static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list);
|
||||||
|
|
|
@ -143,56 +143,13 @@
|
||||||
|
|
||||||
Variant::operator bool() const {
|
Variant::operator bool() const {
|
||||||
|
|
||||||
bool b;
|
return booleanize();
|
||||||
return booleanize(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::booleanize(bool &r_valid) const {
|
// We consider all unitialized or empty types to be false based on the type's
|
||||||
|
// zeroiness.
|
||||||
r_valid = true;
|
bool Variant::booleanize() const {
|
||||||
switch (type) {
|
return !is_zero();
|
||||||
case NIL:
|
|
||||||
return false;
|
|
||||||
case BOOL:
|
|
||||||
return _data._bool;
|
|
||||||
case INT:
|
|
||||||
return _data._int;
|
|
||||||
case REAL:
|
|
||||||
return _data._real;
|
|
||||||
case STRING:
|
|
||||||
return (*reinterpret_cast<const String *>(_data._mem)) != "";
|
|
||||||
case VECTOR2:
|
|
||||||
case RECT2:
|
|
||||||
case TRANSFORM2D:
|
|
||||||
case VECTOR3:
|
|
||||||
case PLANE:
|
|
||||||
case RECT3:
|
|
||||||
case QUAT:
|
|
||||||
case BASIS:
|
|
||||||
case TRANSFORM:
|
|
||||||
case COLOR:
|
|
||||||
case _RID:
|
|
||||||
return (*reinterpret_cast<const RID *>(_data._mem)).is_valid();
|
|
||||||
case OBJECT:
|
|
||||||
return _get_obj().obj;
|
|
||||||
case NODE_PATH:
|
|
||||||
return (*reinterpret_cast<const NodePath *>(_data._mem)) != NodePath();
|
|
||||||
case DICTIONARY:
|
|
||||||
case ARRAY:
|
|
||||||
case POOL_BYTE_ARRAY:
|
|
||||||
case POOL_INT_ARRAY:
|
|
||||||
case POOL_REAL_ARRAY:
|
|
||||||
case POOL_STRING_ARRAY:
|
|
||||||
case POOL_VECTOR2_ARRAY:
|
|
||||||
case POOL_VECTOR3_ARRAY:
|
|
||||||
case POOL_COLOR_ARRAY:
|
|
||||||
r_valid = false;
|
|
||||||
return false;
|
|
||||||
default: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _RETURN(m_what) \
|
#define _RETURN(m_what) \
|
||||||
|
@ -403,12 +360,6 @@ bool Variant::booleanize(bool &r_valid) const {
|
||||||
_RETURN(sum); \
|
_RETURN(sum); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_OP_FAIL(m_name) \
|
|
||||||
case m_name: { \
|
|
||||||
r_valid = false; \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
const Variant &p_b, Variant &r_ret, bool &r_valid) {
|
const Variant &p_b, Variant &r_ret, bool &r_valid) {
|
||||||
|
|
||||||
|
@ -421,11 +372,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
if (p_b.type == NIL) _RETURN(true);
|
if (p_b.type == NIL) _RETURN(true);
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type == OBJECT)
|
||||||
_RETURN(p_b._get_obj().obj == NULL);
|
_RETURN(p_b._get_obj().obj == NULL);
|
||||||
_RETURN(false);
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_EQUAL, BOOL) {
|
CASE_TYPE(math, OP_EQUAL, BOOL) {
|
||||||
if (p_b.type != BOOL) _RETURN(false);
|
if (p_b.type != BOOL)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._bool == p_b._data._bool);
|
_RETURN(p_a._data._bool == p_b._data._bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,11 +386,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN((p_a._get_obj().obj == p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj == p_b._get_obj().obj));
|
||||||
if (p_b.type == NIL)
|
if (p_b.type == NIL)
|
||||||
_RETURN(p_a._get_obj().obj == NULL);
|
_RETURN(p_a._get_obj().obj == NULL);
|
||||||
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_EQUAL, DICTIONARY) {
|
CASE_TYPE(math, OP_EQUAL, DICTIONARY) {
|
||||||
if (p_b.type != DICTIONARY)
|
if (p_b.type != DICTIONARY)
|
||||||
_RETURN(false);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
|
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
|
||||||
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
|
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
|
||||||
|
@ -448,7 +401,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
CASE_TYPE(math, OP_EQUAL, ARRAY) {
|
CASE_TYPE(math, OP_EQUAL, ARRAY) {
|
||||||
if (p_b.type != ARRAY)
|
if (p_b.type != ARRAY)
|
||||||
_RETURN(false);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
||||||
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
|
@ -495,11 +448,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
if (p_b.type == NIL) _RETURN(false);
|
if (p_b.type == NIL) _RETURN(false);
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type == OBJECT)
|
||||||
_RETURN(p_b._get_obj().obj != NULL);
|
_RETURN(p_b._get_obj().obj != NULL);
|
||||||
_RETURN(true);
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_NOT_EQUAL, BOOL) {
|
CASE_TYPE(math, OP_NOT_EQUAL, BOOL) {
|
||||||
if (p_b.type != BOOL) _RETURN(true);
|
if (p_b.type != BOOL)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._bool != p_b._data._bool);
|
_RETURN(p_a._data._bool != p_b._data._bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,11 +462,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN((p_a._get_obj().obj != p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj != p_b._get_obj().obj));
|
||||||
if (p_b.type == NIL)
|
if (p_b.type == NIL)
|
||||||
_RETURN(p_a._get_obj().obj != NULL);
|
_RETURN(p_a._get_obj().obj != NULL);
|
||||||
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) {
|
CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) {
|
||||||
if (p_b.type != DICTIONARY)
|
if (p_b.type != DICTIONARY)
|
||||||
_RETURN(true);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
|
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
|
||||||
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
|
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
|
||||||
|
@ -522,7 +477,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) {
|
CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) {
|
||||||
if (p_b.type != ARRAY)
|
if (p_b.type != ARRAY)
|
||||||
_RETURN(true);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
||||||
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
|
@ -580,13 +535,14 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_LESS, OBJECT) {
|
CASE_TYPE(math, OP_LESS, OBJECT) {
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type != OBJECT)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_LESS, ARRAY) {
|
CASE_TYPE(math, OP_LESS, ARRAY) {
|
||||||
if (p_b.type != ARRAY)
|
if (p_b.type != ARRAY)
|
||||||
_RETURN(false);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
||||||
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
|
@ -633,7 +589,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_LESS_EQUAL, p_a.type) {
|
SWITCH_OP(math, OP_LESS_EQUAL, p_a.type) {
|
||||||
CASE_TYPE(math, OP_LESS_EQUAL, OBJECT) {
|
CASE_TYPE(math, OP_LESS_EQUAL, OBJECT) {
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type != OBJECT)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN((p_a._get_obj().obj <= p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj <= p_b._get_obj().obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,13 +639,14 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_GREATER, OBJECT) {
|
CASE_TYPE(math, OP_GREATER, OBJECT) {
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type != OBJECT)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN((p_a._get_obj().obj > p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj > p_b._get_obj().obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_GREATER, ARRAY) {
|
CASE_TYPE(math, OP_GREATER, ARRAY) {
|
||||||
if (p_b.type != ARRAY)
|
if (p_b.type != ARRAY)
|
||||||
_RETURN(false);
|
_RETURN_FAIL;
|
||||||
|
|
||||||
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
const Array *arr_a = reinterpret_cast<const Array *>(p_a._data._mem);
|
||||||
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
const Array *arr_b = reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
|
@ -735,7 +693,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_GREATER_EQUAL, p_a.type) {
|
SWITCH_OP(math, OP_GREATER_EQUAL, p_a.type) {
|
||||||
CASE_TYPE(math, OP_GREATER_EQUAL, OBJECT) {
|
CASE_TYPE(math, OP_GREATER_EQUAL, OBJECT) {
|
||||||
if (p_b.type == OBJECT)
|
if (p_b.type != OBJECT)
|
||||||
|
_RETURN_FAIL;
|
||||||
_RETURN((p_a._get_obj().obj >= p_b._get_obj().obj));
|
_RETURN((p_a._get_obj().obj >= p_b._get_obj().obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,10 +730,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_ADD, p_a.type) {
|
SWITCH_OP(math, OP_ADD, p_a.type) {
|
||||||
CASE_TYPE(math, OP_ADD, ARRAY) {
|
CASE_TYPE(math, OP_ADD, ARRAY) {
|
||||||
if (p_a.type != p_b.type) {
|
if (p_a.type != p_b.type)
|
||||||
r_valid = false;
|
_RETURN_FAIL;
|
||||||
return;
|
|
||||||
}
|
|
||||||
const Array &array_a = *reinterpret_cast<const Array *>(p_a._data._mem);
|
const Array &array_a = *reinterpret_cast<const Array *>(p_a._data._mem);
|
||||||
const Array &array_b = *reinterpret_cast<const Array *>(p_b._data._mem);
|
const Array &array_b = *reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
Array sum;
|
Array sum;
|
||||||
|
@ -853,65 +811,54 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_MULTIPLY, p_a.type) {
|
SWITCH_OP(math, OP_MULTIPLY, p_a.type) {
|
||||||
CASE_TYPE(math, OP_MULTIPLY, TRANSFORM2D) {
|
CASE_TYPE(math, OP_MULTIPLY, TRANSFORM2D) {
|
||||||
if (p_b.type == TRANSFORM2D) {
|
switch (p_b.type) {
|
||||||
|
case TRANSFORM2D: {
|
||||||
_RETURN(*p_a._data._transform2d * *p_b._data._transform2d);
|
_RETURN(*p_a._data._transform2d * *p_b._data._transform2d);
|
||||||
};
|
}
|
||||||
if (p_b.type == VECTOR2) {
|
case VECTOR2: {
|
||||||
_RETURN(p_a._data._transform2d->xform(*(const Vector2 *)p_b._data._mem));
|
_RETURN(p_a._data._transform2d->xform(*(const Vector2 *)p_b._data._mem));
|
||||||
};
|
}
|
||||||
r_valid = false;
|
default: _RETURN_FAIL;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_MULTIPLY, QUAT) {
|
CASE_TYPE(math, OP_MULTIPLY, QUAT) {
|
||||||
switch (p_b.type) {
|
switch (p_b.type) {
|
||||||
case VECTOR3: {
|
case VECTOR3: {
|
||||||
|
|
||||||
_RETURN(reinterpret_cast<const Quat *>(p_a._data._mem)->xform(*(const Vector3 *)p_b._data._mem));
|
_RETURN(reinterpret_cast<const Quat *>(p_a._data._mem)->xform(*(const Vector3 *)p_b._data._mem));
|
||||||
} break;
|
}
|
||||||
case QUAT: {
|
case QUAT: {
|
||||||
|
|
||||||
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * *reinterpret_cast<const Quat *>(p_b._data._mem));
|
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * *reinterpret_cast<const Quat *>(p_b._data._mem));
|
||||||
} break;
|
}
|
||||||
case REAL: {
|
case REAL: {
|
||||||
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._real);
|
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._real);
|
||||||
} break;
|
}
|
||||||
default: {}
|
default: _RETURN_FAIL;
|
||||||
};
|
}
|
||||||
r_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_MULTIPLY, BASIS) {
|
CASE_TYPE(math, OP_MULTIPLY, BASIS) {
|
||||||
switch (p_b.type) {
|
switch (p_b.type) {
|
||||||
case VECTOR3: {
|
case VECTOR3: {
|
||||||
|
|
||||||
_RETURN(p_a._data._basis->xform(*(const Vector3 *)p_b._data._mem));
|
_RETURN(p_a._data._basis->xform(*(const Vector3 *)p_b._data._mem));
|
||||||
};
|
}
|
||||||
case BASIS: {
|
case BASIS: {
|
||||||
|
|
||||||
_RETURN(*p_a._data._basis * *p_b._data._basis);
|
_RETURN(*p_a._data._basis * *p_b._data._basis);
|
||||||
};
|
}
|
||||||
default: {}
|
default: _RETURN_FAIL;
|
||||||
};
|
}
|
||||||
r_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_MULTIPLY, TRANSFORM) {
|
CASE_TYPE(math, OP_MULTIPLY, TRANSFORM) {
|
||||||
switch (p_b.type) {
|
switch (p_b.type) {
|
||||||
case VECTOR3: {
|
case VECTOR3: {
|
||||||
|
|
||||||
_RETURN(p_a._data._transform->xform(*(const Vector3 *)p_b._data._mem));
|
_RETURN(p_a._data._transform->xform(*(const Vector3 *)p_b._data._mem));
|
||||||
};
|
}
|
||||||
case TRANSFORM: {
|
case TRANSFORM: {
|
||||||
|
|
||||||
_RETURN(*p_a._data._transform * *p_b._data._transform);
|
_RETURN(*p_a._data._transform * *p_b._data._transform);
|
||||||
};
|
}
|
||||||
default: {}
|
default: _RETURN_FAIL;
|
||||||
};
|
}
|
||||||
r_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, INT, *, _int);
|
DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, INT, *, _int);
|
||||||
|
@ -943,18 +890,15 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_DIVIDE, p_a.type) {
|
SWITCH_OP(math, OP_DIVIDE, p_a.type) {
|
||||||
CASE_TYPE(math, OP_DIVIDE, QUAT) {
|
CASE_TYPE(math, OP_DIVIDE, QUAT) {
|
||||||
if (p_b.type != REAL) {
|
if (p_b.type != REAL)
|
||||||
r_valid = false;
|
_RETURN_FAIL;
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (p_b._data._real == 0) {
|
if (p_b._data._real == 0) {
|
||||||
r_valid = false;
|
r_valid = false;
|
||||||
_RETURN("Division By Zero");
|
_RETURN("Division By Zero");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_RETURN(
|
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) / p_b._data._real);
|
||||||
*reinterpret_cast<const Quat *>(p_a._data._mem) / p_b._data._real);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, INT, _int);
|
DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, INT, _int);
|
||||||
|
@ -1054,9 +998,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_MODULE, p_a.type) {
|
SWITCH_OP(math, OP_MODULE, p_a.type) {
|
||||||
CASE_TYPE(math, OP_MODULE, INT) {
|
CASE_TYPE(math, OP_MODULE, INT) {
|
||||||
if (p_b.type != INT) {
|
if (p_b.type != INT)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (p_b._data._int == 0) {
|
if (p_b._data._int == 0) {
|
||||||
r_valid = false;
|
r_valid = false;
|
||||||
|
@ -1067,15 +1010,13 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE(math, OP_MODULE, STRING) {
|
CASE_TYPE(math, OP_MODULE, STRING) {
|
||||||
const String *format =
|
const String *format = reinterpret_cast<const String *>(p_a._data._mem);
|
||||||
reinterpret_cast<const String *>(p_a._data._mem);
|
|
||||||
|
|
||||||
String result;
|
String result;
|
||||||
bool error;
|
bool error;
|
||||||
if (p_b.type == ARRAY) {
|
if (p_b.type == ARRAY) {
|
||||||
// e.g. "frog %s %d" % ["fish", 12]
|
// e.g. "frog %s %d" % ["fish", 12]
|
||||||
const Array *args =
|
const Array *args = reinterpret_cast<const Array *>(p_b._data._mem);
|
||||||
reinterpret_cast<const Array *>(p_b._data._mem);
|
|
||||||
result = format->sprintf(*args, &error);
|
result = format->sprintf(*args, &error);
|
||||||
} else {
|
} else {
|
||||||
// e.g. "frog %d" % 12
|
// e.g. "frog %d" % 12
|
||||||
|
@ -1127,6 +1068,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._int << p_b._data._int);
|
_RETURN(p_a._data._int << p_b._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_LEFT)
|
CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_LEFT)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1137,6 +1079,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._int >> p_b._data._int);
|
_RETURN(p_a._data._int >> p_b._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_RIGHT)
|
CASE_TYPE_ALL_BUT_INT(math, OP_SHIFT_RIGHT)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1147,6 +1090,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._int & p_b._data._int);
|
_RETURN(p_a._data._int & p_b._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_AND)
|
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_AND)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1157,6 +1101,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._int | p_b._data._int);
|
_RETURN(p_a._data._int | p_b._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_OR)
|
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_OR)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1167,6 +1112,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
_RETURN(p_a._data._int ^ p_b._data._int);
|
_RETURN(p_a._data._int ^ p_b._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_XOR)
|
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_XOR)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1175,18 +1121,15 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
CASE_TYPE(math, OP_BIT_NEGATE, INT) {
|
CASE_TYPE(math, OP_BIT_NEGATE, INT) {
|
||||||
_RETURN(~p_a._data._int);
|
_RETURN(~p_a._data._int);
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_NEGATE)
|
CASE_TYPE_ALL_BUT_INT(math, OP_BIT_NEGATE)
|
||||||
_RETURN_FAIL;
|
_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_OP(math, OP_AND, p_a.type) {
|
SWITCH_OP(math, OP_AND, p_a.type) {
|
||||||
CASE_TYPE_ALL(math, OP_AND) {
|
CASE_TYPE_ALL(math, OP_AND) {
|
||||||
bool l = p_a.booleanize(r_valid);
|
bool l = p_a.booleanize();
|
||||||
if (!r_valid)
|
bool r = p_b.booleanize();
|
||||||
return;
|
|
||||||
bool r = p_b.booleanize(r_valid);
|
|
||||||
if (!r_valid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_RETURN(l && r);
|
_RETURN(l && r);
|
||||||
}
|
}
|
||||||
|
@ -1194,12 +1137,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_OR, p_a.type) {
|
SWITCH_OP(math, OP_OR, p_a.type) {
|
||||||
CASE_TYPE_ALL(math, OP_OR) {
|
CASE_TYPE_ALL(math, OP_OR) {
|
||||||
bool l = p_a.booleanize(r_valid);
|
bool l = p_a.booleanize();
|
||||||
if (!r_valid)
|
bool r = p_b.booleanize();
|
||||||
return;
|
|
||||||
bool r = p_b.booleanize(r_valid);
|
|
||||||
if (!r_valid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_RETURN(l || r);
|
_RETURN(l || r);
|
||||||
}
|
}
|
||||||
|
@ -1207,12 +1146,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_XOR, p_a.type) {
|
SWITCH_OP(math, OP_XOR, p_a.type) {
|
||||||
CASE_TYPE_ALL(math, OP_XOR) {
|
CASE_TYPE_ALL(math, OP_XOR) {
|
||||||
bool l = p_a.booleanize(r_valid);
|
bool l = p_a.booleanize();
|
||||||
if (!r_valid)
|
bool r = p_b.booleanize();
|
||||||
return;
|
|
||||||
bool r = p_b.booleanize(r_valid);
|
|
||||||
if (!r_valid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_RETURN((l || r) && !(l && r));
|
_RETURN((l || r) && !(l && r));
|
||||||
}
|
}
|
||||||
|
@ -1220,9 +1155,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
|
||||||
|
|
||||||
SWITCH_OP(math, OP_NOT, p_a.type) {
|
SWITCH_OP(math, OP_NOT, p_a.type) {
|
||||||
CASE_TYPE_ALL(math, OP_NOT) {
|
CASE_TYPE_ALL(math, OP_NOT) {
|
||||||
bool l = p_a.booleanize(r_valid);
|
bool l = p_a.booleanize();
|
||||||
if (!r_valid)
|
|
||||||
return;
|
|
||||||
_RETURN(!l);
|
_RETURN(!l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,10 +480,9 @@ godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const g
|
||||||
return self->hash_compare(*other);
|
return self->hash_compare(*other);
|
||||||
}
|
}
|
||||||
|
|
||||||
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self, godot_bool *r_valid) {
|
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self) {
|
||||||
const Variant *self = (const Variant *)p_self;
|
const Variant *self = (const Variant *)p_self;
|
||||||
bool &valid = *r_valid;
|
return self->booleanize();
|
||||||
return self->booleanize(valid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDAPI godot_variant_destroy(godot_variant *p_self) {
|
void GDAPI godot_variant_destroy(godot_variant *p_self) {
|
||||||
|
|
|
@ -190,7 +190,7 @@ godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const
|
||||||
|
|
||||||
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other);
|
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other);
|
||||||
|
|
||||||
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self, godot_bool *r_valid);
|
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self);
|
||||||
|
|
||||||
void GDAPI godot_variant_destroy(godot_variant *p_self);
|
void GDAPI godot_variant_destroy(godot_variant *p_self);
|
||||||
|
|
||||||
|
|
|
@ -534,7 +534,7 @@ extern "C" {
|
||||||
GDAPI_FUNC(godot_variant_operator_equal, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
GDAPI_FUNC(godot_variant_operator_equal, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
||||||
GDAPI_FUNC(godot_variant_operator_less, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
GDAPI_FUNC(godot_variant_operator_less, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
||||||
GDAPI_FUNC(godot_variant_hash_compare, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
GDAPI_FUNC(godot_variant_hash_compare, godot_bool, const godot_variant *p_self, const godot_variant *p_other) \
|
||||||
GDAPI_FUNC(godot_variant_booleanize, godot_bool, const godot_variant *p_self, godot_bool *r_valid) \
|
GDAPI_FUNC(godot_variant_booleanize, godot_bool, const godot_variant *p_self) \
|
||||||
GDAPI_FUNC_VOID(godot_variant_destroy, godot_variant *p_self) \
|
GDAPI_FUNC_VOID(godot_variant_destroy, godot_variant *p_self) \
|
||||||
GDAPI_FUNC_VOID(godot_string_new, godot_string *r_dest) \
|
GDAPI_FUNC_VOID(godot_string_new, godot_string *r_dest) \
|
||||||
GDAPI_FUNC_VOID(godot_string_new_copy, godot_string *r_dest, const godot_string *p_src) \
|
GDAPI_FUNC_VOID(godot_string_new_copy, godot_string *r_dest, const godot_string *p_src) \
|
||||||
|
|
|
@ -982,15 +982,8 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
|
||||||
|
|
||||||
GET_VARIANT_PTR(test, 1);
|
GET_VARIANT_PTR(test, 1);
|
||||||
|
|
||||||
bool valid;
|
bool result = test->booleanize();
|
||||||
bool result = test->booleanize(valid);
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (!valid) {
|
|
||||||
|
|
||||||
err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (result) {
|
if (result) {
|
||||||
int to = _code_ptr[ip + 2];
|
int to = _code_ptr[ip + 2];
|
||||||
GD_ERR_BREAK(to < 0 || to > _code_size);
|
GD_ERR_BREAK(to < 0 || to > _code_size);
|
||||||
|
@ -1006,15 +999,8 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
|
||||||
|
|
||||||
GET_VARIANT_PTR(test, 1);
|
GET_VARIANT_PTR(test, 1);
|
||||||
|
|
||||||
bool valid;
|
bool result = test->booleanize();
|
||||||
bool result = test->booleanize(valid);
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (!valid) {
|
|
||||||
|
|
||||||
err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
int to = _code_ptr[ip + 2];
|
int to = _code_ptr[ip + 2];
|
||||||
GD_ERR_BREAK(to < 0 || to > _code_size);
|
GD_ERR_BREAK(to < 0 || to > _code_size);
|
||||||
|
@ -1107,14 +1093,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
|
||||||
GET_VARIANT_PTR(test, 1);
|
GET_VARIANT_PTR(test, 1);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
bool valid;
|
bool result = test->booleanize();
|
||||||
bool result = test->booleanize(valid);
|
|
||||||
|
|
||||||
if (!valid) {
|
|
||||||
|
|
||||||
err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue