summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/io/marshalls.cpp20
-rw-r--r--core/io/resource_format_binary.cpp6
-rw-r--r--core/node_path.cpp76
-rw-r--r--core/node_path.h13
-rw-r--r--core/object.cpp123
-rw-r--r--core/object.h5
-rw-r--r--core/variant_call.cpp4
7 files changed, 189 insertions, 58 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index d388a622de..69ae9311fb 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -324,7 +324,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA);
Vector<StringName> names;
Vector<StringName> subnames;
- StringName prop;
uint32_t namecount = strlen &= 0x7FFFFFFF;
uint32_t subnamecount = decode_uint32(buf + 4);
@@ -333,9 +332,10 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
len -= 12;
buf += 12;
+ if (flags & 2) // Obsolete format with property seperate from subpath
+ subnamecount++;
+
uint32_t total = namecount + subnamecount;
- if (flags & 2)
- total++;
if (r_len)
(*r_len) += 12;
@@ -359,10 +359,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (i < namecount)
names.push_back(str);
- else if (i < namecount + subnamecount)
- subnames.push_back(str);
else
- prop = str;
+ subnames.push_back(str);
buf += strlen + pad;
len -= strlen + pad;
@@ -371,7 +369,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4 + strlen + pad;
}
- r_variant = NodePath(names, subnames, flags & 1, prop);
+ r_variant = NodePath(names, subnames, flags & 1);
} else {
//old format, just a string
@@ -919,8 +917,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
uint32_t flags = 0;
if (np.is_absolute())
flags |= 1;
- if (np.get_property() != StringName())
- flags |= 2;
encode_uint32(flags, buf + 8);
@@ -930,8 +926,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 12;
int total = np.get_name_count() + np.get_subname_count();
- if (np.get_property() != StringName())
- total++;
for (int i = 0; i < total; i++) {
@@ -939,10 +933,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
if (i < np.get_name_count())
str = np.get_name(i);
- else if (i < np.get_name_count() + np.get_subname_count())
- str = np.get_subname(i - np.get_subname_count());
else
- str = np.get_property();
+ str = np.get_subname(i - np.get_name_count());
CharString utf8 = str.utf8();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 03c3c5f615..ad6ac568ff 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -267,7 +267,6 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
Vector<StringName> names;
Vector<StringName> subnames;
- StringName property;
bool absolute;
int name_count = f->get_16();
@@ -279,9 +278,8 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
names.push_back(_get_string());
for (uint32_t i = 0; i < subname_count; i++)
subnames.push_back(_get_string());
- property = _get_string();
- NodePath np = NodePath(names, subnames, absolute, property);
+ NodePath np = NodePath(names, subnames, absolute);
r_v = np;
@@ -1454,7 +1452,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
f->store_32(get_string_index(np.get_name(i)));
for (int i = 0; i < np.get_subname_count(); i++)
f->store_32(get_string_index(np.get_subname(i)));
- f->store_32(get_string_index(np.get_property()));
} break;
case Variant::_RID: {
@@ -1685,7 +1682,6 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
get_string_index(np.get_name(i));
for (int i = 0; i < np.get_subname_count(); i++)
get_string_index(np.get_subname(i));
- get_string_index(np.get_property());
} break;
default: {}
diff --git a/core/node_path.cpp b/core/node_path.cpp
index 15f950f605..a01bb420a5 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -48,8 +48,6 @@ uint32_t NodePath::hash() const {
h = h ^ ssn[i].hash();
}
- h = h ^ data->property.hash();
-
return h;
}
@@ -81,13 +79,6 @@ StringName NodePath::get_name(int p_idx) const {
return data->path[p_idx];
}
-StringName NodePath::get_property() const {
-
- if (!data)
- return StringName();
- return data->property;
-}
-
int NodePath::get_subname_count() const {
if (!data)
@@ -128,9 +119,6 @@ bool NodePath::operator==(const NodePath &p_path) const {
if (data->subpath.size() != p_path.data->subpath.size())
return false;
- if (data->property != p_path.data->property)
- return false;
-
for (int i = 0; i < data->path.size(); i++) {
if (data->path[i] != p_path.data->path[i])
@@ -184,8 +172,6 @@ NodePath::operator String() const {
ret += ":" + data->subpath[i].operator String();
}
- if (data->property.operator String() != "")
- ret += ":" + String(data->property);
return ret;
}
@@ -205,6 +191,7 @@ Vector<StringName> NodePath::get_names() const {
return data->path;
return Vector<StringName>();
}
+
Vector<StringName> NodePath::get_subnames() const {
if (data)
@@ -212,6 +199,21 @@ Vector<StringName> NodePath::get_subnames() const {
return Vector<StringName>();
}
+StringName NodePath::get_concatenated_subnames() const {
+ ERR_FAIL_COND_V(!data, StringName());
+
+ if (!data->concatenated_subpath) {
+ int spc = data->subpath.size();
+ String concatenated;
+ const StringName *ssn = data->subpath.ptr();
+ for (int i = 0; i < spc; i++) {
+ concatenated += i == 0 ? ssn[i].operator String() : "." + ssn[i];
+ }
+ data->concatenated_subpath = concatenated;
+ }
+ return data->concatenated_subpath;
+}
+
NodePath NodePath::rel_path_to(const NodePath &p_np) const {
ERR_FAIL_COND_V(!is_absolute(), NodePath());
@@ -250,10 +252,23 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const {
if (relpath.size() == 0)
relpath.push_back(".");
- return NodePath(relpath, p_np.get_subnames(), false, p_np.get_property());
+ return NodePath(relpath, p_np.get_subnames(), false);
+}
+
+NodePath NodePath::get_as_property_path() const {
+
+ if (data->has_slashes || !data->path.size()) {
+ return NodePath(Vector<StringName>(), data->subpath, false);
+ } else {
+ ERR_FAIL_COND_V(data->path.size() != 1, NodePath());
+
+ Vector<StringName> new_path = data->subpath;
+ new_path.insert(0, data->path[0]);
+ return NodePath(Vector<StringName>(), new_path, false);
+ }
}
-NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute, const String &p_property) {
+NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
data = NULL;
@@ -264,14 +279,14 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute, const Stri
data->refcount.init();
data->absolute = p_absolute;
data->path = p_path;
- data->property = p_property;
+ data->has_slashes = true;
}
-NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute, const String &p_property) {
+NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
data = NULL;
- if (p_path.size() == 0)
+ if (p_path.size() == 0 && p_subpath.size() == 0)
return;
data = memnew(Data);
@@ -279,7 +294,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p
data->absolute = p_absolute;
data->path = p_path;
data->subpath = p_subpath;
- data->property = p_property;
+ data->has_slashes = true;
}
void NodePath::simplify() {
@@ -325,6 +340,7 @@ NodePath::NodePath(const String &p_path) {
int absolute = (path[0] == '/') ? 1 : 0;
bool last_is_slash = true;
+ bool has_slashes = false;
int slices = 0;
int subpath_pos = path.find(":");
@@ -337,16 +353,13 @@ NodePath::NodePath(const String &p_path) {
if (path[i] == ':' || path[i] == 0) {
String str = path.substr(from, i - from);
- if (path[i] == ':') {
- if (str == "") {
- ERR_EXPLAIN("Invalid NodePath: " + p_path);
- ERR_FAIL();
- }
- subpath.push_back(str);
- } else {
- //property can be empty
- property = str;
+ if (str == "") {
+ if (path[i] == 0) continue; // Allow end-of-path :
+
+ ERR_EXPLAIN("Invalid NodePath: " + p_path);
+ ERR_FAIL();
}
+ subpath.push_back(str);
from = i + 1;
}
@@ -360,6 +373,7 @@ NodePath::NodePath(const String &p_path) {
if (path[i] == '/') {
last_is_slash = true;
+ has_slashes = true;
} else {
if (last_is_slash)
@@ -369,13 +383,13 @@ NodePath::NodePath(const String &p_path) {
}
}
- if (slices == 0 && !absolute && !property)
+ if (slices == 0 && !absolute && !subpath.size())
return;
data = memnew(Data);
data->refcount.init();
data->absolute = absolute ? true : false;
- data->property = property;
+ data->has_slashes = has_slashes;
data->subpath = subpath;
if (slices == 0)
diff --git a/core/node_path.h b/core/node_path.h
index eb5b9eb6cf..063c4f62db 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -41,10 +41,11 @@ class NodePath {
struct Data {
SafeRefCount refcount;
- StringName property;
Vector<StringName> path;
Vector<StringName> subpath;
+ StringName concatenated_subpath;
bool absolute;
+ bool has_slashes;
};
Data *data;
@@ -53,7 +54,7 @@ class NodePath {
public:
_FORCE_INLINE_ StringName get_sname() const {
- if (data && data->path.size() == 1 && data->subpath.empty() && !data->property) {
+ if (data && data->path.size() == 1 && data->subpath.empty()) {
return data->path[0];
} else {
return operator String();
@@ -67,13 +68,13 @@ public:
StringName get_subname(int p_idx) const;
Vector<StringName> get_names() const;
Vector<StringName> get_subnames() const;
+ StringName get_concatenated_subnames() const;
NodePath rel_path_to(const NodePath &p_np) const;
+ NodePath get_as_property_path() const;
void prepend_period();
- StringName get_property() const;
-
NodePath get_parent() const;
uint32_t hash() const;
@@ -88,8 +89,8 @@ public:
void simplify();
NodePath simplified() const;
- NodePath(const Vector<StringName> &p_path, bool p_absolute, const String &p_property = "");
- NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute, const String &p_property = "");
+ NodePath(const Vector<StringName> &p_path, bool p_absolute);
+ NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute);
NodePath(const NodePath &p_path);
NodePath(const String &p_path);
NodePath();
diff --git a/core/object.cpp b/core/object.cpp
index 823cbe14d4..631676d827 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -517,6 +517,80 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
}
}
+void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid) {
+ if (p_names.empty()) {
+ if (r_valid)
+ *r_valid = false;
+ return;
+ }
+ if (p_names.size() == 1) {
+ set(p_names[0], p_value, r_valid);
+ return;
+ }
+
+ bool valid = false;
+ if (!r_valid) r_valid = &valid;
+
+ List<Variant> value_stack;
+
+ value_stack.push_back(get(p_names[0], r_valid));
+
+ if (!*r_valid) {
+ value_stack.clear();
+ return;
+ }
+
+ 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));
+
+ if (!*r_valid) {
+ value_stack.clear();
+ return;
+ }
+ }
+
+ value_stack.push_back(p_value); // p_names[p_names.size() - 1]
+
+ 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.pop_back();
+
+ if (!*r_valid) {
+ value_stack.clear();
+ return;
+ }
+ }
+
+ set(p_names[0], value_stack.back()->get(), r_valid);
+ value_stack.pop_back();
+
+ ERR_FAIL_COND(!value_stack.empty());
+}
+
+Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) const {
+ if (p_names.empty()) {
+ if (r_valid)
+ *r_valid = false;
+ return Variant();
+ }
+ bool valid = false;
+
+ Variant current_value = get(p_names[0]);
+ for (int i = 1; i < p_names.size(); i++) {
+ current_value = current_value.get_named(p_names[i], &valid);
+
+ if (!valid) {
+ if (r_valid)
+ *r_valid = false;
+ return Variant();
+ }
+ }
+ if (r_valid)
+ *r_valid = true;
+ return current_value;
+}
+
void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const {
if (script_instance && p_reversed) {
@@ -1416,6 +1490,16 @@ Variant Object::_get_bind(const String &p_name) const {
return get(p_name);
}
+void Object::_set_indexed_bind(const NodePath &p_name, const Variant &p_value) {
+
+ set_indexed(p_name.get_as_property_path().get_subnames(), p_value);
+}
+
+Variant Object::_get_indexed_bind(const NodePath &p_name) const {
+
+ return get_indexed(p_name.get_as_property_path().get_subnames());
+}
+
void Object::initialize_class() {
static bool initialized = false;
@@ -1513,6 +1597,8 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_class", "type"), &Object::is_class);
ClassDB::bind_method(D_METHOD("set", "property", "value"), &Object::_set_bind);
ClassDB::bind_method(D_METHOD("get", "property"), &Object::_get_bind);
+ ClassDB::bind_method(D_METHOD("set_indexed", "property", "value"), &Object::_set_indexed_bind);
+ ClassDB::bind_method(D_METHOD("get_indexed", "property"), &Object::_get_indexed_bind);
ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind);
ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind);
ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false));
@@ -1661,6 +1747,43 @@ Variant::Type Object::get_static_property_type(const StringName &p_property, boo
return Variant::NIL;
}
+Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid) const {
+
+ bool valid = false;
+ Variant::Type t = get_static_property_type(p_path[0], &valid);
+ if (!valid) {
+ if (r_valid)
+ *r_valid = false;
+
+ return Variant::NIL;
+ }
+
+ Variant::CallError ce;
+ Variant check = Variant::construct(t, NULL, 0, ce);
+
+ for (int i = 1; i < p_path.size(); i++) {
+ if (check.get_type() == Variant::OBJECT || check.get_type() == Variant::DICTIONARY || check.get_type() == Variant::ARRAY) {
+ // We cannot be sure about the type of properties this types can have
+ if (r_valid)
+ *r_valid = false;
+ return Variant::NIL;
+ }
+
+ check = check.get_named(p_path[i], &valid);
+
+ if (!valid) {
+ if (r_valid)
+ *r_valid = false;
+ return Variant::NIL;
+ }
+ }
+
+ if (r_valid)
+ *r_valid = true;
+
+ return check.get_type();
+}
+
bool Object::is_queued_for_deletion() const {
return _is_queued_for_deletion;
}
diff --git a/core/object.h b/core/object.h
index 7af2c78fc3..3ac699f978 100644
--- a/core/object.h
+++ b/core/object.h
@@ -477,6 +477,8 @@ private:
Array _get_incoming_connections() const;
void _set_bind(const String &p_set, const Variant &p_value);
Variant _get_bind(const String &p_name) const;
+ void _set_indexed_bind(const NodePath &p_name, const Variant &p_value);
+ Variant _get_indexed_bind(const NodePath &p_name) const;
void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
@@ -627,6 +629,8 @@ public:
void set(const StringName &p_name, const Variant &p_value, bool *r_valid = NULL);
Variant get(const StringName &p_name, bool *r_valid = NULL) const;
+ void set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid = NULL);
+ Variant get_indexed(const Vector<StringName> &p_names, bool *r_valid = NULL) const;
void get_property_list(List<PropertyInfo> *p_list, bool p_reversed = false) const;
@@ -687,6 +691,7 @@ public:
bool is_blocking_signals() const;
Variant::Type get_static_property_type(const StringName &p_property, bool *r_valid = NULL) const;
+ Variant::Type get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid = NULL) const;
virtual void get_translatable_strings(List<String> *p_strings) const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 05f0478003..83c92500d0 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -446,7 +446,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(NodePath, get_name);
VCALL_LOCALMEM0R(NodePath, get_subname_count);
VCALL_LOCALMEM1R(NodePath, get_subname);
- VCALL_LOCALMEM0R(NodePath, get_property);
+ VCALL_LOCALMEM0R(NodePath, get_concatenated_subnames);
VCALL_LOCALMEM0R(NodePath, is_empty);
VCALL_LOCALMEM0R(Dictionary, size);
@@ -1590,7 +1590,7 @@ void register_variant_methods() {
ADDFUNC1R(NODE_PATH, STRING, NodePath, get_name, INT, "idx", varray());
ADDFUNC0R(NODE_PATH, INT, NodePath, get_subname_count, varray());
ADDFUNC1R(NODE_PATH, STRING, NodePath, get_subname, INT, "idx", varray());
- ADDFUNC0R(NODE_PATH, STRING, NodePath, get_property, varray());
+ ADDFUNC0R(NODE_PATH, STRING, NodePath, get_concatenated_subnames, varray());
ADDFUNC0R(NODE_PATH, BOOL, NodePath, is_empty, varray());
ADDFUNC0R(DICTIONARY, INT, Dictionary, size, varray());