Refactored variant setters/getters

-Discern between named, indexed and keyed
-Get direct access to functions for typed GDScript and GDNative bindings
-Small changes to some classes in order to work with the new setget binder
This commit is contained in:
reduz 2020-11-06 22:29:22 -03:00
parent 709964849f
commit 05de7ce6ca
16 changed files with 1571 additions and 1996 deletions

View file

@ -193,6 +193,20 @@ struct Color {
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const; operator String() const;
//for binder
_FORCE_INLINE_ void set_r8(int32_t r8) { r = (CLAMP(r8, 0, 255) / 255.0); }
_FORCE_INLINE_ int32_t get_r8() const { return CLAMP(uint32_t(r * 255.0), 0, 255); }
_FORCE_INLINE_ void set_g8(int32_t g8) { g = (CLAMP(g8, 0, 255) / 255.0); }
_FORCE_INLINE_ int32_t get_g8() const { return CLAMP(uint32_t(g * 255.0), 0, 255); }
_FORCE_INLINE_ void set_b8(int32_t b8) { b = (CLAMP(b8, 0, 255) / 255.0); }
_FORCE_INLINE_ int32_t get_b8() const { return CLAMP(uint32_t(b * 255.0), 0, 255); }
_FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0); }
_FORCE_INLINE_ int32_t get_a8() const { return CLAMP(uint32_t(a * 255.0), 0, 255); }
_FORCE_INLINE_ void set_h(float h) { set_hsv(h, get_s(), get_v()); }
_FORCE_INLINE_ void set_s(float s) { set_hsv(get_h(), s, get_v()); }
_FORCE_INLINE_ void set_v(float v) { set_hsv(get_h(), get_s(), v); }
_FORCE_INLINE_ Color() {} _FORCE_INLINE_ Color() {}
/** /**

View file

@ -107,6 +107,14 @@ public:
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const; Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const; Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;
_FORCE_INLINE_ void set_end(const Vector3 &p_end) {
size = p_end - position;
}
_FORCE_INLINE_ Vector3 get_end() const {
return position + size;
}
operator String() const; operator String() const;
_FORCE_INLINE_ AABB() {} _FORCE_INLINE_ AABB() {}

View file

@ -1980,7 +1980,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
} }
bool valid; bool valid;
r_ret = base.get_named(index->name, &valid); r_ret = base.get_named(index->name, valid);
if (!valid) { if (!valid) {
r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type())); r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type()));
return true; return true;

View file

@ -40,8 +40,22 @@
class Quat { class Quat {
public: public:
real_t x = 0, y = 0, z = 0, w = 1; union {
struct {
real_t x;
real_t y;
real_t z;
real_t w;
};
real_t components[4] = { 0, 0, 0, 1.0 };
};
_FORCE_INLINE_ real_t &operator[](int idx) {
return components[idx];
}
_FORCE_INLINE_ const real_t &operator[](int idx) const {
return components[idx];
}
_FORCE_INLINE_ real_t length_squared() const; _FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quat &p_quat) const; bool is_equal_approx(const Quat &p_quat) const;
real_t length() const; real_t length() const;

View file

@ -306,6 +306,15 @@ struct Rect2 {
return false; return false;
} }
} }
_FORCE_INLINE_ void set_end(const Vector2 &p_end) {
size = p_end - position;
}
_FORCE_INLINE_ Vector2 get_end() const {
return position + size;
}
operator String() const { return String(position) + ", " + String(size); } operator String() const { return String(position) + ", " + String(size); }
Rect2() {} Rect2() {}
@ -475,6 +484,14 @@ struct Rect2i {
return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
} }
_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
size = p_end - position;
}
_FORCE_INLINE_ Vector2i get_end() const {
return position + size;
}
operator String() const { return String(position) + ", " + String(size); } operator String() const { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); } operator Rect2() const { return Rect2(position, size); }

View file

@ -421,17 +421,6 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
return; return;
} }
{
bool valid;
setvar(p_name, p_value, &valid);
if (valid) {
if (r_valid) {
*r_valid = true;
}
return;
}
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (script_instance) { if (script_instance) {
bool valid; bool valid;
@ -496,18 +485,6 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
return ret; return ret;
} }
//if nothing else, use getvar
{
bool valid;
ret = getvar(p_name, &valid);
if (valid) {
if (r_valid) {
*r_valid = true;
}
return ret;
}
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (script_instance) { if (script_instance) {
bool valid; bool valid;
@ -555,9 +532,12 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
} }
for (int i = 1; i < p_names.size() - 1; i++) { for (int i = 1; i < p_names.size() - 1; i++) {
value_stack.push_back(value_stack.back()->get().get_named(p_names[i], r_valid)); value_stack.push_back(value_stack.back()->get().get_named(p_names[i], valid));
if (r_valid) {
*r_valid = valid;
}
if (!*r_valid) { if (!valid) {
value_stack.clear(); value_stack.clear();
return; return;
} }
@ -566,10 +546,13 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
value_stack.push_back(p_value); // p_names[p_names.size() - 1] value_stack.push_back(p_value); // p_names[p_names.size() - 1]
for (int i = p_names.size() - 1; i > 0; i--) { for (int i = p_names.size() - 1; i > 0; i--) {
value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), r_valid); value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), valid);
value_stack.pop_back(); value_stack.pop_back();
if (!*r_valid) { if (r_valid) {
*r_valid = valid;
}
if (!valid) {
value_stack.clear(); value_stack.clear();
return; return;
} }
@ -592,7 +575,7 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co
Variant current_value = get(p_names[0], &valid); Variant current_value = get(p_names[0], &valid);
for (int i = 1; i < p_names.size(); i++) { for (int i = 1; i < p_names.size(); i++) {
current_value = current_value.get_named(p_names[i], &valid); current_value = current_value.get_named(p_names[i], valid);
if (!valid) { if (!valid) {
break; break;
@ -698,6 +681,10 @@ Variant Object::getvar(const Variant &p_key, bool *r_valid) const {
if (r_valid) { if (r_valid) {
*r_valid = false; *r_valid = false;
} }
if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) {
return get(p_key, r_valid);
}
return Variant(); return Variant();
} }
@ -705,6 +692,9 @@ void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid)
if (r_valid) { if (r_valid) {
*r_valid = false; *r_valid = false;
} }
if (p_key.get_type() == Variant::STRING_NAME || p_key.get_type() == Variant::STRING) {
return set(p_key, p_value, r_valid);
}
} }
Variant Object::callv(const StringName &p_method, const Array &p_args) { Variant Object::callv(const StringName &p_method, const Array &p_args) {
@ -1711,7 +1701,7 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
return Variant::NIL; return Variant::NIL;
} }
check = check.get_named(p_path[i], &valid); check = check.get_named(p_path[i], valid);
if (!valid) { if (!valid) {
if (r_valid) { if (r_valid) {

View file

@ -39,6 +39,9 @@ Variant PackedDataContainer::getvar(const Variant &p_key, bool *r_valid) const {
if (r_valid) { if (r_valid) {
*r_valid = !err; *r_valid = !err;
} }
if (err) {
return Object::getvar(p_key, r_valid);
}
return ret; return ret;
} }

View file

@ -101,6 +101,8 @@ extern void register_variant_methods();
extern void unregister_variant_methods(); extern void unregister_variant_methods();
extern void register_variant_operators(); extern void register_variant_operators();
extern void unregister_variant_operators(); extern void unregister_variant_operators();
extern void register_variant_setters_getters();
extern void unregister_variant_setters_getters();
void register_core_types() { void register_core_types() {
//consistency check //consistency check
@ -115,6 +117,7 @@ void register_core_types() {
register_global_constants(); register_global_constants();
register_variant_methods(); register_variant_methods();
register_variant_operators(); register_variant_operators();
register_variant_setters_getters();
CoreStringNames::create(); CoreStringNames::create();
@ -322,6 +325,7 @@ void unregister_core_types() {
ClassDB::cleanup_defaults(); ClassDB::cleanup_defaults();
ObjectDB::cleanup(); ObjectDB::cleanup();
unregister_variant_setters_getters();
unregister_variant_operators(); unregister_variant_operators();
unregister_variant_methods(); unregister_variant_methods();
unregister_global_constants(); unregister_global_constants();

View file

@ -477,8 +477,66 @@ public:
static Vector<StringName> get_method_argument_names(Variant::Type p_type, const StringName &p_method); static Vector<StringName> get_method_argument_names(Variant::Type p_type, const StringName &p_method);
static bool is_method_const(Variant::Type p_type, const StringName &p_method); static bool is_method_const(Variant::Type p_type, const StringName &p_method);
void set_named(const StringName &p_index, const Variant &p_value, bool *r_valid = nullptr); void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid);
Variant get_named(const StringName &p_index, bool *r_valid = nullptr) const; Variant get_named(const StringName &p_member, bool &r_valid) const;
typedef void (*ValidatedSetter)(Variant *base, const Variant *value);
typedef void (*ValidatedGetter)(const Variant *base, Variant *value);
static bool has_member(Variant::Type p_type, const StringName &p_member);
static Variant::Type get_member_type(Variant::Type p_type, const StringName &p_member);
static void get_member_list(Type p_type, List<StringName> *r_members);
static ValidatedSetter get_member_validated_setter(Variant::Type p_type, const StringName &p_member);
static ValidatedGetter get_member_validated_getter(Variant::Type p_type, const StringName &p_member);
typedef void (*PTRSetter)(void *base, const void *value);
typedef void (*PTRGetter)(const void *base, void *value);
static PTRSetter get_member_ptr_setter(Variant::Type p_type, const StringName &p_member);
static PTRGetter get_member_ptr_getter(Variant::Type p_type, const StringName &p_member);
static bool has_indexing(Variant::Type p_type);
static Variant::Type get_indexed_element_type(Variant::Type p_type);
typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool &oob);
typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool &oob);
static ValidatedIndexedSetter get_member_validated_indexed_setter(Variant::Type p_type);
static ValidatedIndexedGetter get_member_validated_indexed_getter(Variant::Type p_type);
typedef void (*PTRIndexedSetter)(void *base, int64_t index, const void *value);
typedef void (*PTRIndexedGetter)(const void *base, int64_t index, void *value);
static PTRIndexedSetter get_member_ptr_indexed_setter(Variant::Type p_type);
static PTRIndexedGetter get_member_ptr_indexed_getter(Variant::Type p_type);
void set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob);
Variant get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const;
uint64_t get_indexed_size() const;
static bool is_keyed(Variant::Type p_type);
typedef void (*ValidatedKeyedSetter)(Variant *base, const Variant *key, const Variant *value, bool &valid);
typedef void (*ValidatedKeyedGetter)(const Variant *base, const Variant *key, Variant *value, bool &valid);
typedef bool (*ValidatedKeyedChecker)(const Variant *base, const Variant *key, bool &valid);
static ValidatedKeyedSetter get_member_validated_keyed_setter(Variant::Type p_type);
static ValidatedKeyedGetter get_member_validated_keyed_getter(Variant::Type p_type);
static ValidatedKeyedChecker get_member_validated_keyed_checker(Variant::Type p_type);
typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value);
typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value);
typedef bool (*PTRKeyedChecker)(const void *base, const void *key);
static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type);
static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type);
static PTRKeyedChecker get_member_ptr_keyed_checker(Variant::Type p_type);
void set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid);
Variant get_keyed(const Variant &p_key, bool &r_valid) const;
bool has_key(const Variant &p_key, bool &r_valid) const;
void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr); void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr);
Variant get(const Variant &p_index, bool *r_valid = nullptr) const; Variant get(const Variant &p_index, bool *r_valid = nullptr) const;

View file

@ -1481,7 +1481,6 @@ void register_op(Variant::Operator p_op, Variant::Type p_type_a, Variant::Type p
} }
void register_variant_operators() { void register_variant_operators() {
printf("size of OT %i\n", (int)sizeof(operator_evaluator_table));
zeromem(operator_return_type_table, sizeof(operator_return_type_table)); zeromem(operator_return_type_table, sizeof(operator_return_type_table));
zeromem(operator_evaluator_table, sizeof(operator_evaluator_table)); zeromem(operator_evaluator_table, sizeof(operator_evaluator_table));
zeromem(validated_operator_evaluator_table, sizeof(validated_operator_evaluator_table)); zeromem(validated_operator_evaluator_table, sizeof(validated_operator_evaluator_table));
@ -2122,3 +2121,15 @@ Variant::operator bool() const {
bool Variant::booleanize() const { bool Variant::booleanize() const {
return !is_zero(); return !is_zero();
} }
bool Variant::in(const Variant &p_index, bool *r_valid) const {
bool valid;
Variant ret;
evaluate(OP_IN, p_index, *this, ret, valid);
if (r_valid) {
*r_valid = valid;
return false;
}
ERR_FAIL_COND_V(ret.type != BOOL, false);
return *VariantGetInternalPtr<bool>::get_ptr(&ret);
}

File diff suppressed because it is too large Load diff

View file

@ -3751,7 +3751,8 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
} }
for (int i = 0; i < leftover_path.size() - 1; i++) { for (int i = 0; i < leftover_path.size() - 1; i++) {
property_info_base = property_info_base.get_named(leftover_path[i]); bool valid;
property_info_base = property_info_base.get_named(leftover_path[i], valid);
} }
List<PropertyInfo> pinfo; List<PropertyInfo> pinfo;

View file

@ -2438,7 +2438,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
if (p_subscript->base->is_constant) { if (p_subscript->base->is_constant) {
// Just try to get it. // Just try to get it.
bool valid = false; bool valid = false;
Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, &valid); Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid);
if (!valid) { if (!valid) {
push_error(vformat(R"(Cannot get member "%s" from "%s".)", p_subscript->attribute->name, p_subscript->base->reduced_value), p_subscript->index); push_error(vformat(R"(Cannot get member "%s" from "%s".)", p_subscript->attribute->name, p_subscript->base->reduced_value), p_subscript->index);
} else { } else {

View file

@ -620,7 +620,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
const StringName *index = &_global_names_ptr[indexname]; const StringName *index = &_global_names_ptr[indexname];
bool valid; bool valid;
dst->set_named(*index, *value, &valid); dst->set_named(*index, *value, valid);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (!valid) { if (!valid) {
@ -647,10 +647,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool valid; bool valid;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
//allow better error message in cases where src and dst are the same stack position //allow better error message in cases where src and dst are the same stack position
Variant ret = src->get_named(*index, &valid); Variant ret = src->get_named(*index, valid);
#else #else
*dst = src->get_named(*index, &valid); *dst = src->get_named(*index, valid);
#endif #endif
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (!valid) { if (!valid) {

View file

@ -1341,7 +1341,7 @@ public:
} }
bool valid; bool valid;
r_ret = base.get_named(index->name, &valid); r_ret = base.get_named(index->name, valid);
if (!valid) { if (!valid) {
r_error_str = "Invalid index '" + String(index->name) + "' for base of type " + Variant::get_type_name(base.get_type()) + "."; r_error_str = "Invalid index '" + String(index->name) + "' for base of type " + Variant::get_type_name(base.get_type()) + ".";
return true; return true;

View file

@ -1449,11 +1449,11 @@ public:
_FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) { _FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) {
if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) { if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) {
source.set_named(index, p_argument, &valid); source.set_named(index, p_argument, valid);
} else { } else {
Variant value; Variant value;
if (index != StringName()) { if (index != StringName()) {
value = source.get_named(index, &valid); value = source.get_named(index, valid);
} else { } else {
value = source; value = source;
} }
@ -1497,7 +1497,7 @@ public:
} }
if (index != StringName()) { if (index != StringName()) {
source.set_named(index, value, &valid); source.set_named(index, value, valid);
} else { } else {
source = value; source = value;
} }
@ -1562,12 +1562,12 @@ public:
bool valid; bool valid;
if (needs_get) { if (needs_get) {
Variant value = v.get_named(property, &valid); Variant value = v.get_named(property, valid);
_process_get(value, *p_inputs[1], valid); _process_get(value, *p_inputs[1], valid);
v.set_named(property, value, &valid); v.set_named(property, value, valid);
} else { } else {
v.set_named(property, *p_inputs[1], &valid); v.set_named(property, *p_inputs[1], valid);
} }
if (!valid) { if (!valid) {
@ -2111,7 +2111,7 @@ public:
*p_outputs[0] = object->get(property, &valid); *p_outputs[0] = object->get(property, &valid);
if (index != StringName()) { if (index != StringName()) {
*p_outputs[0] = p_outputs[0]->get_named(index); *p_outputs[0] = p_outputs[0]->get_named(index, valid);
} }
if (!valid) { if (!valid) {
@ -2140,7 +2140,7 @@ public:
*p_outputs[0] = another->get(property, &valid); *p_outputs[0] = another->get(property, &valid);
if (index != StringName()) { if (index != StringName()) {
*p_outputs[0] = p_outputs[0]->get_named(index); *p_outputs[0] = p_outputs[0]->get_named(index, valid);
} }
if (!valid) { if (!valid) {
@ -2156,7 +2156,7 @@ public:
*p_outputs[0] = v.get(property, &valid); *p_outputs[0] = v.get(property, &valid);
if (index != StringName()) { if (index != StringName()) {
*p_outputs[0] = p_outputs[0]->get_named(index); *p_outputs[0] = p_outputs[0]->get_named(index, valid);
} }
if (!valid) { if (!valid) {