Make NodePath copy-on-write, to avoid it changing accidentally by owned copies.

This commit is contained in:
Lukas Tenbrink
2025-11-26 20:20:17 +01:00
parent bc192293b1
commit 60ab73cd1e
2 changed files with 33 additions and 0 deletions
+25
View File
@@ -42,6 +42,7 @@ void NodePath::_update_hash_cache() const {
void NodePath::prepend_period() {
if (data->path.size() && data->path[0].operator String() != ".") {
_copy_on_write();
data->path.insert(0, ".");
data->concatenated_path = StringName();
data->hash_cache_valid = false;
@@ -167,6 +168,29 @@ void NodePath::operator=(const NodePath &p_path) {
}
}
void NodePath::_copy_on_write() {
if (!data) {
return; // No data; nothing to do.
}
if (data->refcount.get() == 1) {
return; // Already the only owner of data.
}
// Make a copy.
Data *new_data = memnew(Data);
new_data->refcount.init();
new_data->path = data->path;
new_data->subpath = data->subpath;
new_data->concatenated_path = data->concatenated_path;
new_data->concatenated_subpath = data->concatenated_subpath;
new_data->absolute = data->absolute;
new_data->hash_cache_valid = data->hash_cache_valid;
new_data->hash_cache = data->hash_cache;
unref();
data = new_data;
}
NodePath::operator String() const {
if (!data) {
return String();
@@ -332,6 +356,7 @@ void NodePath::simplify() {
if (!data) {
return;
}
_copy_on_write();
for (int i = 0; i < data->path.size(); i++) {
if (data->path.size() == 1) {
break;