summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHein-Pieter van Braam <hp@tmm.cx>2017-09-18 20:02:47 +0200
committerHein-Pieter van Braam <hp@tmm.cx>2017-09-19 18:55:31 +0200
commit833c3917b247baa46f5a5f6ad6ce478cffc1911d (patch)
tree0f25e4584f1da4b0534c55c9b6f88e0358d8dd98
parent85641c545bedbdb703ad923306786afe5c312110 (diff)
Allow booleanization of all types
We now allow booleanization of all types. This means that empty versions of all types now evaluate to false. So a Vector2(0,0), Dictionary(), etc. This allows you to write GDScript like: if not Dictionary(): print("Empty dict") Booleanization can now also no longer fail. There is no more valid flag, this changes Variant and GDNative API.
-rw-r--r--core/variant.h2
-rw-r--r--core/variant_op.cpp87
-rw-r--r--modules/gdnative/gdnative/variant.cpp5
-rw-r--r--modules/gdnative/include/gdnative/variant.h2
-rw-r--r--modules/gdnative/include/gdnative_api_struct.h2
-rw-r--r--modules/gdscript/gd_function.cpp27
6 files changed, 20 insertions, 105 deletions
diff --git a/core/variant.h b/core/variant.h
index edc86dedd4..5ea540a63f 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -390,7 +390,7 @@ public:
uint32_t hash() const;
bool hash_compare(const Variant &p_variant) const;
- bool booleanize(bool &valid) const;
+ bool booleanize() const;
void static_assign(const Variant &p_variant);
static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list);
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 8349f2fdf6..5d47936679 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -143,56 +143,13 @@
Variant::operator bool() const {
- bool b;
- return booleanize(b);
+ return booleanize();
}
-bool Variant::booleanize(bool &r_valid) const {
-
- r_valid = true;
- switch (type) {
- 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;
+// We consider all unitialized or empty types to be false based on the type's
+// zeroiness.
+bool Variant::booleanize() const {
+ return !is_zero();
}
#define _RETURN(m_what) \
@@ -403,12 +360,6 @@ bool Variant::booleanize(bool &r_valid) const {
_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,
const Variant &p_b, Variant &r_ret, bool &r_valid) {
@@ -1177,12 +1128,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_AND, p_a.type) {
CASE_TYPE_ALL(math, OP_AND) {
- bool l = p_a.booleanize(r_valid);
- if (!r_valid)
- return;
- bool r = p_b.booleanize(r_valid);
- if (!r_valid)
- return;
+ bool l = p_a.booleanize();
+ bool r = p_b.booleanize();
_RETURN(l && r);
}
@@ -1190,12 +1137,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_OR, p_a.type) {
CASE_TYPE_ALL(math, OP_OR) {
- bool l = p_a.booleanize(r_valid);
- if (!r_valid)
- return;
- bool r = p_b.booleanize(r_valid);
- if (!r_valid)
- return;
+ bool l = p_a.booleanize();
+ bool r = p_b.booleanize();
_RETURN(l || r);
}
@@ -1203,12 +1146,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_XOR, p_a.type) {
CASE_TYPE_ALL(math, OP_XOR) {
- bool l = p_a.booleanize(r_valid);
- if (!r_valid)
- return;
- bool r = p_b.booleanize(r_valid);
- if (!r_valid)
- return;
+ bool l = p_a.booleanize();
+ bool r = p_b.booleanize();
_RETURN((l || r) && !(l && r));
}
@@ -1216,9 +1155,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_NOT, p_a.type) {
CASE_TYPE_ALL(math, OP_NOT) {
- bool l = p_a.booleanize(r_valid);
- if (!r_valid)
- return;
+ bool l = p_a.booleanize();
_RETURN(!l);
}
}
diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index 1b2aae607f..9ba4166c1d 100644
--- a/modules/gdnative/gdnative/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -480,10 +480,9 @@ godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const g
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;
- bool &valid = *r_valid;
- return self->booleanize(valid);
+ return self->booleanize();
}
void GDAPI godot_variant_destroy(godot_variant *p_self) {
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index 969506585d..7b804c1eaf 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -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_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);
diff --git a/modules/gdnative/include/gdnative_api_struct.h b/modules/gdnative/include/gdnative_api_struct.h
index cfebeb08cc..c345e27227 100644
--- a/modules/gdnative/include/gdnative_api_struct.h
+++ b/modules/gdnative/include/gdnative_api_struct.h
@@ -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_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_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_string_new, godot_string *r_dest) \
GDAPI_FUNC_VOID(godot_string_new_copy, godot_string *r_dest, const godot_string *p_src) \
diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp
index 438d484a41..df7b16c96e 100644
--- a/modules/gdscript/gd_function.cpp
+++ b/modules/gdscript/gd_function.cpp
@@ -982,15 +982,8 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
GET_VARIANT_PTR(test, 1);
- bool valid;
- bool result = test->booleanize(valid);
-#ifdef DEBUG_ENABLED
- if (!valid) {
+ bool result = test->booleanize();
- err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
- break;
- }
-#endif
if (result) {
int to = _code_ptr[ip + 2];
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);
- bool valid;
- bool result = test->booleanize(valid);
-#ifdef DEBUG_ENABLED
- if (!valid) {
+ bool result = test->booleanize();
- err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
- break;
- }
-#endif
if (!result) {
int to = _code_ptr[ip + 2];
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);
#ifdef DEBUG_ENABLED
- bool valid;
- bool result = test->booleanize(valid);
-
- if (!valid) {
-
- err_text = "cannot evaluate conditional expression of type: " + Variant::get_type_name(test->get_type());
- break;
- }
+ bool result = test->booleanize();
if (!result) {