summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/callable.cpp27
-rw-r--r--core/variant/callable.h3
-rw-r--r--core/variant/callable_bind.cpp52
-rw-r--r--core/variant/callable_bind.h2
-rw-r--r--core/variant/variant.cpp17
-rw-r--r--core/variant/variant.h1
-rw-r--r--core/variant/variant_call.cpp5
-rw-r--r--core/variant/variant_parser.cpp21
-rw-r--r--core/variant/variant_setget.cpp29
9 files changed, 145 insertions, 12 deletions
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index fd85fe78f6..2f2acc55a6 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -117,6 +117,7 @@ Callable Callable::bindv(const Array &p_arguments) {
}
Callable Callable::unbind(int p_argcount) const {
+ ERR_FAIL_COND_V_MSG(p_argcount <= 0, Callable(*this), "Amount of unbind() arguments must be 1 or greater.");
return Callable(memnew(CallableCustomUnbind(*this, p_argcount)));
}
@@ -159,6 +160,27 @@ int Callable::get_bound_arguments_count() const {
}
}
+void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const {
+ if (!is_null() && is_custom()) {
+ custom->get_bound_arguments(r_arguments, r_argcount);
+ } else {
+ r_arguments.clear();
+ r_argcount = 0;
+ }
+}
+
+Array Callable::get_bound_arguments() const {
+ Vector<Variant> arr;
+ int ac;
+ get_bound_arguments_ref(arr, ac);
+ Array ret;
+ ret.resize(arr.size());
+ for (int i = 0; i < arr.size(); i++) {
+ ret[i] = arr[i];
+ }
+ return ret;
+}
+
CallableCustom *Callable::get_custom() const {
ERR_FAIL_COND_V_MSG(!is_custom(), nullptr,
vformat("Can't get custom on non-CallableCustom \"%s\".", operator String()));
@@ -370,6 +392,11 @@ int CallableCustom::get_bound_arguments_count() const {
return 0;
}
+void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
+ r_arguments = Vector<Variant>();
+ r_argcount = 0;
+}
+
CallableCustom::CallableCustom() {
ref_count.init();
}
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 10d291ac24..0abbb64c0b 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -108,6 +108,8 @@ public:
StringName get_method() const;
CallableCustom *get_custom() const;
int get_bound_arguments_count() const;
+ void get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below.
+ Array get_bound_arguments() const;
uint32_t hash() const;
@@ -149,6 +151,7 @@ public:
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
virtual const Callable *get_base_comparator() const;
virtual int get_bound_arguments_count() const;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const;
CallableCustom();
virtual ~CallableCustom() {}
diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp
index 83035dc70d..5be91c6e11 100644
--- a/core/variant/callable_bind.cpp
+++ b/core/variant/callable_bind.cpp
@@ -91,6 +91,43 @@ int CallableCustomBind::get_bound_arguments_count() const {
return callable.get_bound_arguments_count() + binds.size();
}
+void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
+ Vector<Variant> sub_args;
+ int sub_count;
+ callable.get_bound_arguments_ref(sub_args, sub_count);
+
+ if (sub_count == 0) {
+ r_arguments = binds;
+ r_argcount = binds.size();
+ return;
+ }
+
+ int new_count = sub_count + binds.size();
+ r_argcount = new_count;
+
+ if (new_count <= 0) {
+ // Removed more arguments than it adds.
+ r_arguments = Vector<Variant>();
+ return;
+ }
+
+ r_arguments.resize(new_count);
+
+ if (sub_count > 0) {
+ for (int i = 0; i < sub_count; i++) {
+ r_arguments.write[i] = sub_args[i];
+ }
+ for (int i = 0; i < binds.size(); i++) {
+ r_arguments.write[i + sub_count] = binds[i];
+ }
+ r_argcount = new_count;
+ } else {
+ for (int i = 0; i < binds.size() + sub_count; i++) {
+ r_arguments.write[i] = binds[i - sub_count];
+ }
+ }
+}
+
void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount));
for (int i = 0; i < p_argcount; i++) {
@@ -172,6 +209,21 @@ int CallableCustomUnbind::get_bound_arguments_count() const {
return callable.get_bound_arguments_count() - argcount;
}
+void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
+ Vector<Variant> sub_args;
+ int sub_count;
+ callable.get_bound_arguments_ref(sub_args, sub_count);
+
+ r_argcount = sub_args.size() - argcount;
+
+ if (argcount >= sub_args.size()) {
+ r_arguments = Vector<Variant>();
+ } else {
+ sub_args.resize(sub_args.size() - argcount);
+ r_arguments = sub_args;
+ }
+}
+
void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
if (argcount > p_argcount) {
r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h
index a79a521b5b..278ed335d0 100644
--- a/core/variant/callable_bind.h
+++ b/core/variant/callable_bind.h
@@ -52,6 +52,7 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
virtual const Callable *get_base_comparator() const override;
virtual int get_bound_arguments_count() const override;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
Callable get_callable() { return callable; }
Vector<Variant> get_binds() { return binds; }
@@ -77,6 +78,7 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
virtual const Callable *get_base_comparator() const override;
virtual int get_bound_arguments_count() const override;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
Callable get_callable() { return callable; }
int get_unbinds() { return argcount; }
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index bff6656a88..ca42738b05 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -3654,7 +3654,22 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
}
String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
- return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce);
+ Vector<Variant> binds;
+ int args_bound;
+ p_callable.get_bound_arguments_ref(binds, args_bound);
+ if (args_bound <= 0) {
+ return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, MAX(0, p_argcount + args_bound), ce);
+ } else {
+ Vector<const Variant *> argptrs;
+ argptrs.resize(p_argcount + binds.size());
+ for (int i = 0; i < p_argcount; i++) {
+ argptrs.write[i] = p_argptrs[i];
+ }
+ for (int i = 0; i < binds.size(); i++) {
+ argptrs.write[i + p_argcount] = &binds[i];
+ }
+ return get_call_error_text(p_callable.get_object(), p_callable.get_method(), (const Variant **)argptrs.ptr(), argptrs.size(), ce);
+ }
}
void Variant::register_types() {
diff --git a/core/variant/variant.h b/core/variant/variant.h
index fff59c43a6..b9294de77d 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -655,6 +655,7 @@ public:
static bool has_indexing(Variant::Type p_type);
static Variant::Type get_indexed_element_type(Variant::Type p_type);
+ static uint32_t get_indexed_element_usage(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);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 6c06b63dab..9e8c6fccb3 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1923,7 +1923,7 @@ static void _register_variant_builtin_methods() {
/* Plane */
bind_method(Plane, normalized, sarray(), varray());
- bind_method(Plane, center, sarray(), varray());
+ bind_method(Plane, get_center, sarray(), varray());
bind_method(Plane, is_equal_approx, sarray("to_plane"), varray());
bind_method(Plane, is_finite, sarray(), varray());
bind_method(Plane, is_point_over, sarray("point"), varray());
@@ -2017,6 +2017,7 @@ static void _register_variant_builtin_methods() {
bind_method(Callable, get_object_id, sarray(), varray());
bind_method(Callable, get_method, sarray(), varray());
bind_method(Callable, get_bound_arguments_count, sarray(), varray());
+ bind_method(Callable, get_bound_arguments, sarray(), varray());
bind_method(Callable, hash, sarray(), varray());
bind_method(Callable, bindv, sarray("arguments"), varray());
bind_method(Callable, unbind, sarray("argcount"), varray());
@@ -2134,7 +2135,7 @@ static void _register_variant_builtin_methods() {
bind_static_method(Projection, create_depth_correction, sarray("flip_y"), varray());
bind_static_method(Projection, create_light_atlas_rect, sarray("rect"), varray());
bind_static_method(Projection, create_perspective, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov"), varray(false));
- bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", " convergence_dist"), varray());
+ bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", "convergence_dist"), varray());
bind_static_method(Projection, create_for_hmd, sarray("eye", "aspect", "intraocular_dist", "display_width", "display_to_lens", "oversample", "z_near", "z_far"), varray());
bind_static_method(Projection, create_orthogonal, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray());
bind_static_method(Projection, create_orthogonal_aspect, sarray("size", "aspect", "z_near", "z_far", "flip_fov"), varray(false));
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 39a039ffe8..87874deb8d 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -1358,6 +1358,7 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
if (p_simple_tag) {
r_tag.name = "";
r_tag.fields.clear();
+ bool escaping = false;
if (p_stream->is_utf8()) {
CharString cs;
@@ -1368,7 +1369,15 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
return ERR_PARSE_ERROR;
}
if (c == ']') {
- break;
+ if (escaping) {
+ escaping = false;
+ } else {
+ break;
+ }
+ } else if (c == '\\') {
+ escaping = true;
+ } else {
+ escaping = false;
}
cs += c;
}
@@ -1381,7 +1390,15 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
return ERR_PARSE_ERROR;
}
if (c == ']') {
- break;
+ if (escaping) {
+ escaping = false;
+ } else {
+ break;
+ }
+ } else if (c == '\\') {
+ escaping = true;
+ } else {
+ escaping = false;
}
r_tag.name += String::chr(c);
}
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index b8d4495702..30fb5d0e9f 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -151,8 +151,8 @@ void unregister_named_setters_getters() {
bool Variant::has_member(Variant::Type p_type, const StringName &p_member) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
- for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
- if (variant_setters_getters_names[p_type][i] == p_member) {
+ for (const StringName &member : variant_setters_getters_names[p_type]) {
+ if (member == p_member) {
return true;
}
}
@@ -172,8 +172,8 @@ Variant::Type Variant::get_member_type(Variant::Type p_type, const StringName &p
}
void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members) {
- for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
- r_members->push_back(variant_setters_getters_names[p_type][i]);
+ for (const StringName &member : variant_setters_getters_names[p_type]) {
+ r_members->push_back(member);
}
}
@@ -389,6 +389,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
v.write[index] = PtrToArg<m_elem_type>::convert(member); \
} \
static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \
+ static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \
static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \
};
@@ -460,6 +461,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
v.write[index] = PtrToArg<m_elem_type>::convert(member); \
} \
static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \
+ static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \
static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \
};
@@ -515,6 +517,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
v[index] = PtrToArg<m_elem_type>::convert(member); \
} \
static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \
+ static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \
static uint64_t get_indexed_size(const Variant *base) { return m_max; } \
};
@@ -564,6 +567,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
v m_accessor[index] = PtrToArg<m_elem_type>::convert(member); \
} \
static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \
+ static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \
static uint64_t get_indexed_size(const Variant *base) { return m_max; } \
};
@@ -613,6 +617,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
v.m_set(index, PtrToArg<m_elem_type>::convert(member)); \
} \
static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \
+ static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \
static uint64_t get_indexed_size(const Variant *base) { return m_max; } \
};
@@ -683,6 +688,7 @@ struct VariantIndexedSetGet_Array {
v.set(index, PtrToArg<Variant>::convert(member));
}
static Variant::Type get_index_type() { return Variant::NIL; }
+ static uint32_t get_index_usage() { return PROPERTY_USAGE_NIL_IS_VARIANT; }
static uint64_t get_indexed_size(const Variant *base) { return 0; }
};
@@ -768,6 +774,7 @@ struct VariantIndexedSetGet_String {
}
}
static Variant::Type get_index_type() { return Variant::STRING; }
+ static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; }
static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); }
};
@@ -812,6 +819,7 @@ struct VariantIndexedSetGet_String {
v[index] = PtrToArg<Variant>::convert(member); \
} \
static Variant::Type get_index_type() { return Variant::NIL; } \
+ static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; } \
static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \
};
@@ -852,7 +860,8 @@ struct VariantIndexedSetterGetterInfo {
uint64_t (*get_indexed_size)(const Variant *base) = nullptr;
- Variant::Type index_type;
+ Variant::Type index_type = Variant::NIL;
+ uint32_t index_usage = PROPERTY_USAGE_DEFAULT;
bool valid = false;
};
@@ -872,6 +881,7 @@ static void register_indexed_member(Variant::Type p_type) {
sgi.ptr_getter = T::ptr_get;
sgi.index_type = T::get_index_type();
+ sgi.index_usage = T::get_index_usage();
sgi.get_indexed_size = T::get_indexed_size;
sgi.valid = true;
@@ -920,6 +930,11 @@ Variant::Type Variant::get_indexed_element_type(Variant::Type p_type) {
return variant_indexed_setters_getters[p_type].index_type;
}
+uint32_t Variant::get_indexed_element_usage(Variant::Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, PROPERTY_USAGE_DEFAULT);
+ return variant_indexed_setters_getters[p_type].index_usage;
+}
+
Variant::ValidatedIndexedSetter Variant::get_member_validated_indexed_setter(Variant::Type p_type) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
return variant_indexed_setters_getters[p_type].validated_setter;
@@ -1253,7 +1268,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return _data._int > 0;
} break;
case FLOAT: {
- r_iter = 0;
+ r_iter = 0.0;
return _data._float > 0.0;
} break;
case VECTOR2: {
@@ -1457,7 +1472,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
case FLOAT: {
- int64_t idx = r_iter;
+ double idx = r_iter;
idx++;
if (idx >= _data._float) {
return false;