Allow renaming child nodes in _ready
This commit is contained in:
parent
afc5fa14ad
commit
2c0caa5828
@ -353,6 +353,40 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Replace the key of an entry in-place, without invalidating iterators or changing the entries position during iteration.
|
||||
// p_old_key must exist in the map and p_new_key must not, unless it is equal to p_old_key.
|
||||
bool replace_key(const TKey &p_old_key, const TKey &p_new_key) {
|
||||
if (p_old_key == p_new_key) {
|
||||
return true;
|
||||
}
|
||||
uint32_t pos = 0;
|
||||
ERR_FAIL_COND_V(_lookup_pos(p_new_key, pos), false);
|
||||
ERR_FAIL_COND_V(!_lookup_pos(p_old_key, pos), false);
|
||||
HashMapElement<TKey, TValue> *element = elements[pos];
|
||||
|
||||
// Delete the old entries in hashes and elements.
|
||||
const uint32_t capacity = hash_table_size_primes[capacity_index];
|
||||
const uint64_t capacity_inv = hash_table_size_primes_inv[capacity_index];
|
||||
uint32_t next_pos = fastmod((pos + 1), capacity_inv, capacity);
|
||||
while (hashes[next_pos] != EMPTY_HASH && _get_probe_length(next_pos, hashes[next_pos], capacity, capacity_inv) != 0) {
|
||||
SWAP(hashes[next_pos], hashes[pos]);
|
||||
SWAP(elements[next_pos], elements[pos]);
|
||||
pos = next_pos;
|
||||
next_pos = fastmod((pos + 1), capacity_inv, capacity);
|
||||
}
|
||||
hashes[pos] = EMPTY_HASH;
|
||||
elements[pos] = nullptr;
|
||||
// _insert_with_hash will increment this again.
|
||||
num_elements--;
|
||||
|
||||
// Update the HashMapElement with the new key and reinsert it.
|
||||
const_cast<TKey &>(element->data.key) = p_new_key;
|
||||
uint32_t hash = _hash(p_new_key);
|
||||
_insert_with_hash(hash, element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reserves space for a number of elements, useful to avoid many resizes and rehashes.
|
||||
// If adding a known (possibly large) number of elements at once, must be larger than old capacity.
|
||||
void reserve(uint32_t p_new_capacity) {
|
||||
|
@ -1137,7 +1137,6 @@ void Node::_set_name_nocheck(const StringName &p_name) {
|
||||
|
||||
void Node::set_name(const String &p_name) {
|
||||
ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Changing the name to nodes inside the SceneTree is only allowed from the main thread. Use `set_name.call_deferred(new_name)`.");
|
||||
ERR_FAIL_COND_MSG(data.parent && data.parent->data.blocked > 0, "Parent node is busy setting up children, `set_name(new_name)` failed. Consider using `set_name.call_deferred(new_name)` instead.");
|
||||
String name = p_name.validate_node_name();
|
||||
|
||||
ERR_FAIL_COND(name.is_empty());
|
||||
@ -1149,9 +1148,9 @@ void Node::set_name(const String &p_name) {
|
||||
data.name = name;
|
||||
|
||||
if (data.parent) {
|
||||
data.parent->data.children.erase(old_name);
|
||||
data.parent->_validate_child_name(this, true);
|
||||
data.parent->data.children.insert(data.name, this);
|
||||
bool success = data.parent->data.children.replace_key(old_name, data.name);
|
||||
ERR_FAIL_COND_MSG(!success, "Renaming child in hashtable failed, this is a bug.");
|
||||
}
|
||||
|
||||
if (data.unique_name_in_owner && data.owner) {
|
||||
|
Loading…
Reference in New Issue
Block a user