1/**************************************************************************/
2/* node.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "node.h"
32
33#include "core/config/project_settings.h"
34#include "core/core_string_names.h"
35#include "core/io/resource_loader.h"
36#include "core/object/message_queue.h"
37#include "core/object/script_language.h"
38#include "core/string/print_string.h"
39#include "instance_placeholder.h"
40#include "scene/animation/tween.h"
41#include "scene/debugger/scene_debugger.h"
42#include "scene/main/multiplayer_api.h"
43#include "scene/main/window.h"
44#include "scene/resources/packed_scene.h"
45#include "scene/scene_string_names.h"
46#include "viewport.h"
47
48#include <stdint.h>
49
50int Node::orphan_node_count = 0;
51
52thread_local Node *Node::current_process_thread_group = nullptr;
53
54void Node::_notification(int p_notification) {
55 switch (p_notification) {
56 case NOTIFICATION_PROCESS: {
57 GDVIRTUAL_CALL(_process, get_process_delta_time());
58 } break;
59
60 case NOTIFICATION_PHYSICS_PROCESS: {
61 GDVIRTUAL_CALL(_physics_process, get_physics_process_delta_time());
62 } break;
63
64 case NOTIFICATION_ENTER_TREE: {
65 ERR_FAIL_NULL(get_viewport());
66 ERR_FAIL_NULL(get_tree());
67
68 // Update process mode.
69 if (data.process_mode == PROCESS_MODE_INHERIT) {
70 if (data.parent) {
71 data.process_owner = data.parent->data.process_owner;
72 } else {
73 ERR_PRINT("The root node can't be set to Inherit process mode, reverting to Pausable instead.");
74 data.process_mode = PROCESS_MODE_PAUSABLE;
75 data.process_owner = this;
76 }
77 } else {
78 data.process_owner = this;
79 }
80
81 { // Update threaded process mode.
82 if (data.process_thread_group == PROCESS_THREAD_GROUP_INHERIT) {
83 if (data.parent) {
84 data.process_thread_group_owner = data.parent->data.process_thread_group_owner;
85 }
86
87 if (data.process_thread_group_owner) {
88 data.process_group = data.process_thread_group_owner->data.process_group;
89 } else {
90 data.process_group = &data.tree->default_process_group;
91 }
92 } else {
93 data.process_thread_group_owner = this;
94 _add_process_group();
95 }
96
97 if (_is_any_processing()) {
98 _add_to_process_thread_group();
99 }
100 }
101
102 if (data.input) {
103 add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
104 }
105 if (data.shortcut_input) {
106 add_to_group("_vp_shortcut_input" + itos(get_viewport()->get_instance_id()));
107 }
108 if (data.unhandled_input) {
109 add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
110 }
111 if (data.unhandled_key_input) {
112 add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
113 }
114
115 get_tree()->nodes_in_tree_count++;
116 orphan_node_count--;
117 } break;
118
119 case NOTIFICATION_EXIT_TREE: {
120 ERR_FAIL_NULL(get_viewport());
121 ERR_FAIL_NULL(get_tree());
122
123 get_tree()->nodes_in_tree_count--;
124 orphan_node_count++;
125
126 if (data.input) {
127 remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id()));
128 }
129 if (data.shortcut_input) {
130 remove_from_group("_vp_shortcut_input" + itos(get_viewport()->get_instance_id()));
131 }
132 if (data.unhandled_input) {
133 remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
134 }
135 if (data.unhandled_key_input) {
136 remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
137 }
138
139 // Remove from processing first
140 if (_is_any_processing()) {
141 _remove_from_process_thread_group();
142 }
143 // Remove the process group
144 if (data.process_thread_group_owner == this) {
145 _remove_process_group();
146 }
147 data.process_thread_group_owner = nullptr;
148 data.process_owner = nullptr;
149
150 if (data.path_cache) {
151 memdelete(data.path_cache);
152 data.path_cache = nullptr;
153 }
154 } break;
155
156 case NOTIFICATION_PATH_RENAMED: {
157 if (data.path_cache) {
158 memdelete(data.path_cache);
159 data.path_cache = nullptr;
160 }
161 } break;
162
163 case NOTIFICATION_READY: {
164 if (GDVIRTUAL_IS_OVERRIDDEN(_input)) {
165 set_process_input(true);
166 }
167
168 if (GDVIRTUAL_IS_OVERRIDDEN(_shortcut_input)) {
169 set_process_shortcut_input(true);
170 }
171
172 if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_input)) {
173 set_process_unhandled_input(true);
174 }
175
176 if (GDVIRTUAL_IS_OVERRIDDEN(_unhandled_key_input)) {
177 set_process_unhandled_key_input(true);
178 }
179
180 if (GDVIRTUAL_IS_OVERRIDDEN(_process)) {
181 set_process(true);
182 }
183 if (GDVIRTUAL_IS_OVERRIDDEN(_physics_process)) {
184 set_physics_process(true);
185 }
186
187 GDVIRTUAL_CALL(_ready);
188 } break;
189
190 case NOTIFICATION_POSTINITIALIZE: {
191 data.in_constructor = false;
192 } break;
193
194 case NOTIFICATION_PREDELETE: {
195 if (data.inside_tree && !Thread::is_main_thread()) {
196 cancel_free();
197 ERR_PRINT("Attempted to free a node that is currently added to the SceneTree from a thread. This is not permitted, use queue_free() instead. Node has not been freed.");
198 return;
199 }
200
201 if (data.owner) {
202 _clean_up_owner();
203 }
204
205 if (data.parent) {
206 data.parent->remove_child(this);
207 }
208
209 // kill children as cleanly as possible
210 while (data.children.size()) {
211 Node *child = data.children.last()->value; // begin from the end because its faster and more consistent with creation
212 memdelete(child);
213 }
214 } break;
215 }
216}
217
218void Node::_propagate_ready() {
219 data.ready_notified = true;
220 data.blocked++;
221 for (KeyValue<StringName, Node *> &K : data.children) {
222 K.value->_propagate_ready();
223 }
224
225 data.blocked--;
226
227 notification(NOTIFICATION_POST_ENTER_TREE);
228
229 if (data.ready_first) {
230 data.ready_first = false;
231 notification(NOTIFICATION_READY);
232 emit_signal(SceneStringNames::get_singleton()->ready);
233 }
234}
235
236void Node::_propagate_enter_tree() {
237 // this needs to happen to all children before any enter_tree
238
239 if (data.parent) {
240 data.tree = data.parent->data.tree;
241 data.depth = data.parent->data.depth + 1;
242 } else {
243 data.depth = 1;
244 }
245
246 data.viewport = Object::cast_to<Viewport>(this);
247 if (!data.viewport && data.parent) {
248 data.viewport = data.parent->data.viewport;
249 }
250
251 data.inside_tree = true;
252
253 for (KeyValue<StringName, GroupData> &E : data.grouped) {
254 E.value.group = data.tree->add_to_group(E.key, this);
255 }
256
257 notification(NOTIFICATION_ENTER_TREE);
258
259 GDVIRTUAL_CALL(_enter_tree);
260
261 emit_signal(SceneStringNames::get_singleton()->tree_entered);
262
263 data.tree->node_added(this);
264
265 if (data.parent) {
266 Variant c = this;
267 const Variant *cptr = &c;
268 data.parent->emit_signalp(SNAME("child_entered_tree"), &cptr, 1);
269 }
270
271 data.blocked++;
272 //block while adding children
273
274 for (KeyValue<StringName, Node *> &K : data.children) {
275 if (!K.value->is_inside_tree()) { // could have been added in enter_tree
276 K.value->_propagate_enter_tree();
277 }
278 }
279
280 data.blocked--;
281
282#ifdef DEBUG_ENABLED
283 SceneDebugger::add_to_cache(data.scene_file_path, this);
284#endif
285 // enter groups
286}
287
288void Node::_propagate_after_exit_tree() {
289 // Clear owner if it was not part of the pruned branch
290 if (data.owner) {
291 bool found = false;
292 Node *parent = data.parent;
293
294 while (parent) {
295 if (parent == data.owner) {
296 found = true;
297 break;
298 }
299
300 parent = parent->data.parent;
301 }
302
303 if (!found) {
304 _clean_up_owner();
305 }
306 }
307
308 data.blocked++;
309
310 for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) {
311 I->value->_propagate_after_exit_tree();
312 }
313
314 data.blocked--;
315
316 emit_signal(SceneStringNames::get_singleton()->tree_exited);
317}
318
319void Node::_propagate_exit_tree() {
320 //block while removing children
321
322#ifdef DEBUG_ENABLED
323 if (!data.scene_file_path.is_empty()) {
324 // Only remove if file path is set (optimization).
325 SceneDebugger::remove_from_cache(data.scene_file_path, this);
326 }
327#endif
328 data.blocked++;
329
330 for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) {
331 I->value->_propagate_exit_tree();
332 }
333
334 data.blocked--;
335
336 GDVIRTUAL_CALL(_exit_tree);
337
338 emit_signal(SceneStringNames::get_singleton()->tree_exiting);
339
340 notification(NOTIFICATION_EXIT_TREE, true);
341 if (data.tree) {
342 data.tree->node_removed(this);
343 }
344
345 if (data.parent) {
346 Variant c = this;
347 const Variant *cptr = &c;
348 data.parent->emit_signalp(SNAME("child_exiting_tree"), &cptr, 1);
349 }
350
351 // exit groups
352 for (KeyValue<StringName, GroupData> &E : data.grouped) {
353 data.tree->remove_from_group(E.key, this);
354 E.value.group = nullptr;
355 }
356
357 data.viewport = nullptr;
358
359 if (data.tree) {
360 data.tree->tree_changed();
361 }
362
363 data.inside_tree = false;
364 data.ready_notified = false;
365 data.tree = nullptr;
366 data.depth = -1;
367}
368
369void Node::move_child(Node *p_child, int p_index) {
370 ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Moving child node positions inside the SceneTree is only allowed from the main thread. Use call_deferred(\"move_child\",child,index).");
371 ERR_FAIL_NULL(p_child);
372 ERR_FAIL_COND_MSG(p_child->data.parent != this, "Child is not a child of this node.");
373
374 _update_children_cache();
375 // We need to check whether node is internal and move it only in the relevant node range.
376 if (p_child->data.internal_mode == INTERNAL_MODE_FRONT) {
377 if (p_index < 0) {
378 p_index += data.internal_children_front_count_cache;
379 }
380 ERR_FAIL_INDEX_MSG(p_index, data.internal_children_front_count_cache, vformat("Invalid new child index: %d. Child is internal.", p_index));
381 _move_child(p_child, p_index);
382 } else if (p_child->data.internal_mode == INTERNAL_MODE_BACK) {
383 if (p_index < 0) {
384 p_index += data.internal_children_back_count_cache;
385 }
386 ERR_FAIL_INDEX_MSG(p_index, data.internal_children_back_count_cache, vformat("Invalid new child index: %d. Child is internal.", p_index));
387 _move_child(p_child, (int)data.children_cache.size() - data.internal_children_back_count_cache + p_index);
388 } else {
389 if (p_index < 0) {
390 p_index += get_child_count(false);
391 }
392 ERR_FAIL_INDEX_MSG(p_index, (int)data.children_cache.size() + 1 - data.internal_children_front_count_cache - data.internal_children_back_count_cache, vformat("Invalid new child index: %d.", p_index));
393 _move_child(p_child, p_index + data.internal_children_front_count_cache);
394 }
395}
396
397void Node::_move_child(Node *p_child, int p_index, bool p_ignore_end) {
398 ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, `move_child()` failed. Consider using `move_child.call_deferred(child, index)` instead (or `popup.call_deferred()` if this is from a popup).");
399
400 // Specifying one place beyond the end
401 // means the same as moving to the last index
402 if (!p_ignore_end) { // p_ignore_end is a little hack to make back internal children work properly.
403 if (p_child->data.internal_mode == INTERNAL_MODE_FRONT) {
404 if (p_index == data.internal_children_front_count_cache) {
405 p_index--;
406 }
407 } else if (p_child->data.internal_mode == INTERNAL_MODE_BACK) {
408 if (p_index == (int)data.children_cache.size()) {
409 p_index--;
410 }
411 } else {
412 if (p_index == (int)data.children_cache.size() - data.internal_children_back_count_cache) {
413 p_index--;
414 }
415 }
416 }
417
418 int child_index = p_child->get_index();
419
420 if (child_index == p_index) {
421 return; //do nothing
422 }
423
424 int motion_from = MIN(p_index, child_index);
425 int motion_to = MAX(p_index, child_index);
426
427 data.children_cache.remove_at(child_index);
428 data.children_cache.insert(p_index, p_child);
429
430 if (data.tree) {
431 data.tree->tree_changed();
432 }
433
434 data.blocked++;
435 //new pos first
436 for (int i = motion_from; i <= motion_to; i++) {
437 if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_DISABLED) {
438 data.children_cache[i]->data.index = i - data.internal_children_front_count_cache;
439 } else if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_BACK) {
440 data.children_cache[i]->data.index = i - data.internal_children_front_count_cache - data.external_children_count_cache;
441 } else {
442 data.children_cache[i]->data.index = i;
443 }
444 }
445 // notification second
446 move_child_notify(p_child);
447 notification(NOTIFICATION_CHILD_ORDER_CHANGED);
448 emit_signal(SNAME("child_order_changed"));
449 p_child->_propagate_groups_dirty();
450
451 data.blocked--;
452}
453
454void Node::_propagate_groups_dirty() {
455 for (const KeyValue<StringName, GroupData> &E : data.grouped) {
456 if (E.value.group) {
457 E.value.group->changed = true;
458 }
459 }
460
461 for (KeyValue<StringName, Node *> &K : data.children) {
462 K.value->_propagate_groups_dirty();
463 }
464}
465
466void Node::add_child_notify(Node *p_child) {
467 // to be used when not wanted
468}
469
470void Node::remove_child_notify(Node *p_child) {
471 // to be used when not wanted
472}
473
474void Node::move_child_notify(Node *p_child) {
475 // to be used when not wanted
476}
477
478void Node::owner_changed_notify() {
479}
480
481void Node::set_physics_process(bool p_process) {
482 ERR_THREAD_GUARD
483 if (data.physics_process == p_process) {
484 return;
485 }
486
487 if (!is_inside_tree()) {
488 data.physics_process = p_process;
489 return;
490 }
491
492 if (_is_any_processing()) {
493 _remove_from_process_thread_group();
494 }
495
496 data.physics_process = p_process;
497
498 if (_is_any_processing()) {
499 _add_to_process_thread_group();
500 }
501}
502
503bool Node::is_physics_processing() const {
504 return data.physics_process;
505}
506
507void Node::set_physics_process_internal(bool p_process_internal) {
508 ERR_THREAD_GUARD
509 if (data.physics_process_internal == p_process_internal) {
510 return;
511 }
512
513 if (!is_inside_tree()) {
514 data.physics_process_internal = p_process_internal;
515 return;
516 }
517
518 if (_is_any_processing()) {
519 _remove_from_process_thread_group();
520 }
521
522 data.physics_process_internal = p_process_internal;
523
524 if (_is_any_processing()) {
525 _add_to_process_thread_group();
526 }
527}
528
529bool Node::is_physics_processing_internal() const {
530 return data.physics_process_internal;
531}
532
533void Node::set_process_mode(ProcessMode p_mode) {
534 ERR_THREAD_GUARD
535 if (data.process_mode == p_mode) {
536 return;
537 }
538
539 if (!is_inside_tree()) {
540 data.process_mode = p_mode;
541 return;
542 }
543
544 bool prev_can_process = can_process();
545 bool prev_enabled = _is_enabled();
546
547 if (p_mode == PROCESS_MODE_INHERIT) {
548 if (data.parent) {
549 data.process_owner = data.parent->data.process_owner;
550 } else {
551 ERR_FAIL_MSG("The root node can't be set to Inherit process mode.");
552 }
553 } else {
554 data.process_owner = this;
555 }
556
557 data.process_mode = p_mode;
558
559 bool next_can_process = can_process();
560 bool next_enabled = _is_enabled();
561
562 int pause_notification = 0;
563
564 if (prev_can_process && !next_can_process) {
565 pause_notification = NOTIFICATION_PAUSED;
566 } else if (!prev_can_process && next_can_process) {
567 pause_notification = NOTIFICATION_UNPAUSED;
568 }
569
570 int enabled_notification = 0;
571
572 if (prev_enabled && !next_enabled) {
573 enabled_notification = NOTIFICATION_DISABLED;
574 } else if (!prev_enabled && next_enabled) {
575 enabled_notification = NOTIFICATION_ENABLED;
576 }
577
578 _propagate_process_owner(data.process_owner, pause_notification, enabled_notification);
579
580#ifdef TOOLS_ENABLED
581 // This is required for the editor to update the visibility of disabled nodes
582 // It's very expensive during runtime to change, so editor-only
583 if (Engine::get_singleton()->is_editor_hint()) {
584 get_tree()->emit_signal(SNAME("tree_process_mode_changed"));
585 }
586#endif
587}
588
589void Node::_propagate_pause_notification(bool p_enable) {
590 bool prev_can_process = _can_process(!p_enable);
591 bool next_can_process = _can_process(p_enable);
592
593 if (prev_can_process && !next_can_process) {
594 notification(NOTIFICATION_PAUSED);
595 } else if (!prev_can_process && next_can_process) {
596 notification(NOTIFICATION_UNPAUSED);
597 }
598
599 data.blocked++;
600 for (KeyValue<StringName, Node *> &K : data.children) {
601 K.value->_propagate_pause_notification(p_enable);
602 }
603 data.blocked--;
604}
605
606Node::ProcessMode Node::get_process_mode() const {
607 return data.process_mode;
608}
609
610void Node::_propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification) {
611 data.process_owner = p_owner;
612
613 if (p_pause_notification != 0) {
614 notification(p_pause_notification);
615 }
616
617 if (p_enabled_notification != 0) {
618 notification(p_enabled_notification);
619 }
620
621 data.blocked++;
622 for (KeyValue<StringName, Node *> &K : data.children) {
623 Node *c = K.value;
624 if (c->data.process_mode == PROCESS_MODE_INHERIT) {
625 c->_propagate_process_owner(p_owner, p_pause_notification, p_enabled_notification);
626 }
627 }
628 data.blocked--;
629}
630
631void Node::set_multiplayer_authority(int p_peer_id, bool p_recursive) {
632 ERR_THREAD_GUARD
633 data.multiplayer_authority = p_peer_id;
634
635 if (p_recursive) {
636 for (KeyValue<StringName, Node *> &K : data.children) {
637 K.value->set_multiplayer_authority(p_peer_id, true);
638 }
639 }
640}
641
642int Node::get_multiplayer_authority() const {
643 return data.multiplayer_authority;
644}
645
646bool Node::is_multiplayer_authority() const {
647 ERR_FAIL_COND_V(!is_inside_tree(), false);
648
649 Ref<MultiplayerAPI> api = get_multiplayer();
650 return api.is_valid() && (api->get_unique_id() == data.multiplayer_authority);
651}
652
653/***** RPC CONFIG ********/
654
655void Node::rpc_config(const StringName &p_method, const Variant &p_config) {
656 ERR_THREAD_GUARD
657 if (data.rpc_config.get_type() != Variant::DICTIONARY) {
658 data.rpc_config = Dictionary();
659 }
660 Dictionary node_config = data.rpc_config;
661 if (p_config.get_type() == Variant::NIL) {
662 node_config.erase(p_method);
663 } else {
664 ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY);
665 node_config[p_method] = p_config;
666 }
667}
668
669const Variant Node::get_node_rpc_config() const {
670 return data.rpc_config;
671}
672
673/***** RPC FUNCTIONS ********/
674
675Error Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
676 if (p_argcount < 1) {
677 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
678 r_error.argument = 1;
679 return ERR_INVALID_PARAMETER;
680 }
681
682 Variant::Type type = p_args[0]->get_type();
683 if (type != Variant::STRING_NAME && type != Variant::STRING) {
684 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
685 r_error.argument = 0;
686 r_error.expected = Variant::STRING_NAME;
687 return ERR_INVALID_PARAMETER;
688 }
689
690 StringName method = (*p_args[0]).operator StringName();
691
692 Error err = rpcp(0, method, &p_args[1], p_argcount - 1);
693 r_error.error = Callable::CallError::CALL_OK;
694 return err;
695}
696
697Error Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
698 if (p_argcount < 2) {
699 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
700 r_error.argument = 2;
701 return ERR_INVALID_PARAMETER;
702 }
703
704 if (p_args[0]->get_type() != Variant::INT) {
705 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
706 r_error.argument = 0;
707 r_error.expected = Variant::INT;
708 return ERR_INVALID_PARAMETER;
709 }
710
711 Variant::Type type = p_args[1]->get_type();
712 if (type != Variant::STRING_NAME && type != Variant::STRING) {
713 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
714 r_error.argument = 1;
715 r_error.expected = Variant::STRING_NAME;
716 return ERR_INVALID_PARAMETER;
717 }
718
719 int peer_id = *p_args[0];
720 StringName method = (*p_args[1]).operator StringName();
721
722 Error err = rpcp(peer_id, method, &p_args[2], p_argcount - 2);
723 r_error.error = Callable::CallError::CALL_OK;
724 return err;
725}
726
727Error Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {
728 ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED);
729
730 Ref<MultiplayerAPI> api = get_multiplayer();
731 if (api.is_null()) {
732 return ERR_UNCONFIGURED;
733 }
734 return api->rpcp(this, p_peer_id, p_method, p_arg, p_argcount);
735}
736
737Ref<MultiplayerAPI> Node::get_multiplayer() const {
738 if (!is_inside_tree()) {
739 return Ref<MultiplayerAPI>();
740 }
741 return get_tree()->get_multiplayer(get_path());
742}
743
744//////////// end of rpc
745
746bool Node::can_process_notification(int p_what) const {
747 switch (p_what) {
748 case NOTIFICATION_PHYSICS_PROCESS:
749 return data.physics_process;
750 case NOTIFICATION_PROCESS:
751 return data.process;
752 case NOTIFICATION_INTERNAL_PROCESS:
753 return data.process_internal;
754 case NOTIFICATION_INTERNAL_PHYSICS_PROCESS:
755 return data.physics_process_internal;
756 }
757
758 return true;
759}
760
761bool Node::can_process() const {
762 ERR_FAIL_COND_V(!is_inside_tree(), false);
763 return _can_process(get_tree()->is_paused());
764}
765
766bool Node::_can_process(bool p_paused) const {
767 ProcessMode process_mode;
768
769 if (data.process_mode == PROCESS_MODE_INHERIT) {
770 if (!data.process_owner) {
771 process_mode = PROCESS_MODE_PAUSABLE;
772 } else {
773 process_mode = data.process_owner->data.process_mode;
774 }
775 } else {
776 process_mode = data.process_mode;
777 }
778
779 // The owner can't be set to inherit, must be a bug.
780 ERR_FAIL_COND_V(process_mode == PROCESS_MODE_INHERIT, false);
781
782 if (process_mode == PROCESS_MODE_DISABLED) {
783 return false;
784 } else if (process_mode == PROCESS_MODE_ALWAYS) {
785 return true;
786 }
787
788 if (p_paused) {
789 return process_mode == PROCESS_MODE_WHEN_PAUSED;
790 } else {
791 return process_mode == PROCESS_MODE_PAUSABLE;
792 }
793}
794
795bool Node::_is_enabled() const {
796 ProcessMode process_mode;
797
798 if (data.process_mode == PROCESS_MODE_INHERIT) {
799 if (!data.process_owner) {
800 process_mode = PROCESS_MODE_PAUSABLE;
801 } else {
802 process_mode = data.process_owner->data.process_mode;
803 }
804 } else {
805 process_mode = data.process_mode;
806 }
807
808 return (process_mode != PROCESS_MODE_DISABLED);
809}
810
811bool Node::is_enabled() const {
812 ERR_FAIL_COND_V(!is_inside_tree(), false);
813 return _is_enabled();
814}
815
816double Node::get_physics_process_delta_time() const {
817 if (data.tree) {
818 return data.tree->get_physics_process_time();
819 } else {
820 return 0;
821 }
822}
823
824double Node::get_process_delta_time() const {
825 if (data.tree) {
826 return data.tree->get_process_time();
827 } else {
828 return 0;
829 }
830}
831
832void Node::set_process(bool p_process) {
833 ERR_THREAD_GUARD
834 if (data.process == p_process) {
835 return;
836 }
837
838 if (!is_inside_tree()) {
839 data.process = p_process;
840 return;
841 }
842
843 if (_is_any_processing()) {
844 _remove_from_process_thread_group();
845 }
846
847 data.process = p_process;
848
849 if (_is_any_processing()) {
850 _add_to_process_thread_group();
851 }
852}
853
854bool Node::is_processing() const {
855 return data.process;
856}
857
858void Node::set_process_internal(bool p_process_internal) {
859 ERR_THREAD_GUARD
860 if (data.process_internal == p_process_internal) {
861 return;
862 }
863
864 if (!is_inside_tree()) {
865 data.process_internal = p_process_internal;
866 return;
867 }
868
869 if (_is_any_processing()) {
870 _remove_from_process_thread_group();
871 }
872
873 data.process_internal = p_process_internal;
874
875 if (_is_any_processing()) {
876 _add_to_process_thread_group();
877 }
878}
879
880void Node::_add_process_group() {
881 get_tree()->_add_process_group(this);
882}
883
884void Node::_remove_process_group() {
885 get_tree()->_remove_process_group(this);
886}
887
888void Node::_remove_from_process_thread_group() {
889 get_tree()->_remove_node_from_process_group(this, data.process_thread_group_owner);
890}
891
892void Node::_add_to_process_thread_group() {
893 get_tree()->_add_node_to_process_group(this, data.process_thread_group_owner);
894}
895
896void Node::_remove_tree_from_process_thread_group() {
897 if (!is_inside_tree()) {
898 return; // May not be initialized yet.
899 }
900
901 for (KeyValue<StringName, Node *> &K : data.children) {
902 if (K.value->data.process_thread_group != PROCESS_THREAD_GROUP_INHERIT) {
903 continue;
904 }
905
906 K.value->_remove_tree_from_process_thread_group();
907 }
908
909 if (_is_any_processing()) {
910 _remove_from_process_thread_group();
911 }
912}
913
914void Node::_add_tree_to_process_thread_group(Node *p_owner) {
915 if (_is_any_processing()) {
916 _add_to_process_thread_group();
917 }
918
919 data.process_thread_group_owner = p_owner;
920 if (p_owner != nullptr) {
921 data.process_group = p_owner->data.process_group;
922 } else {
923 data.process_group = &data.tree->default_process_group;
924 }
925
926 for (KeyValue<StringName, Node *> &K : data.children) {
927 if (K.value->data.process_thread_group != PROCESS_THREAD_GROUP_INHERIT) {
928 continue;
929 }
930
931 K.value->_add_to_process_thread_group();
932 }
933}
934bool Node::is_processing_internal() const {
935 return data.process_internal;
936}
937
938void Node::set_process_thread_group_order(int p_order) {
939 ERR_THREAD_GUARD
940 if (data.process_thread_group_order == p_order) {
941 return;
942 }
943
944 data.process_thread_group_order = p_order;
945
946 // Not yet in the tree (or not a group owner, in whose case this is pointless but harmless); trivial update.
947 if (!is_inside_tree() || data.process_thread_group_owner != this) {
948 return;
949 }
950
951 get_tree()->process_groups_dirty = true;
952}
953
954int Node::get_process_thread_group_order() const {
955 return data.process_thread_group_order;
956}
957
958void Node::set_process_priority(int p_priority) {
959 ERR_THREAD_GUARD
960 if (data.process_priority == p_priority) {
961 return;
962 }
963 if (!is_inside_tree()) {
964 // Not yet in the tree; trivial update.
965 data.process_priority = p_priority;
966 return;
967 }
968
969 if (_is_any_processing()) {
970 _remove_from_process_thread_group();
971 data.process_priority = p_priority;
972 _add_to_process_thread_group();
973 }
974}
975
976int Node::get_process_priority() const {
977 return data.process_priority;
978}
979
980void Node::set_physics_process_priority(int p_priority) {
981 ERR_THREAD_GUARD
982 if (data.physics_process_priority == p_priority) {
983 return;
984 }
985 if (!is_inside_tree()) {
986 // Not yet in the tree; trivial update.
987 data.physics_process_priority = p_priority;
988 return;
989 }
990
991 if (_is_any_processing()) {
992 _remove_from_process_thread_group();
993 data.physics_process_priority = p_priority;
994 _add_to_process_thread_group();
995 }
996}
997
998int Node::get_physics_process_priority() const {
999 return data.physics_process_priority;
1000}
1001
1002void Node::set_process_thread_group(ProcessThreadGroup p_mode) {
1003 ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Changing the process thread group can only be done from the main thread. Use call_deferred(\"set_process_thread_group\",mode).");
1004 if (data.process_thread_group == p_mode) {
1005 return;
1006 }
1007
1008 if (!is_inside_tree()) {
1009 // Not yet in the tree; trivial update.
1010 data.process_thread_group = p_mode;
1011 return;
1012 }
1013
1014 _remove_tree_from_process_thread_group();
1015 if (data.process_thread_group != PROCESS_THREAD_GROUP_INHERIT) {
1016 _remove_process_group();
1017 }
1018
1019 data.process_thread_group = p_mode;
1020
1021 if (p_mode == PROCESS_THREAD_GROUP_INHERIT) {
1022 if (data.parent) {
1023 data.process_thread_group_owner = data.parent->data.process_thread_group_owner;
1024 } else {
1025 data.process_thread_group_owner = nullptr;
1026 }
1027 } else {
1028 data.process_thread_group_owner = this;
1029 _add_process_group();
1030 }
1031
1032 _add_tree_to_process_thread_group(data.process_thread_group_owner);
1033
1034 notify_property_list_changed();
1035}
1036
1037Node::ProcessThreadGroup Node::get_process_thread_group() const {
1038 return data.process_thread_group;
1039}
1040
1041void Node::set_process_thread_messages(BitField<ProcessThreadMessages> p_flags) {
1042 ERR_THREAD_GUARD
1043 if (data.process_thread_messages == p_flags) {
1044 return;
1045 }
1046
1047 data.process_thread_messages = p_flags;
1048}
1049
1050BitField<Node::ProcessThreadMessages> Node::get_process_thread_messages() const {
1051 return data.process_thread_messages;
1052}
1053
1054void Node::set_process_input(bool p_enable) {
1055 ERR_THREAD_GUARD
1056 if (p_enable == data.input) {
1057 return;
1058 }
1059
1060 data.input = p_enable;
1061 if (!is_inside_tree()) {
1062 return;
1063 }
1064
1065 if (p_enable) {
1066 add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
1067 } else {
1068 remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id()));
1069 }
1070}
1071
1072bool Node::is_processing_input() const {
1073 return data.input;
1074}
1075
1076void Node::set_process_shortcut_input(bool p_enable) {
1077 ERR_THREAD_GUARD
1078 if (p_enable == data.shortcut_input) {
1079 return;
1080 }
1081 data.shortcut_input = p_enable;
1082 if (!is_inside_tree()) {
1083 return;
1084 }
1085
1086 if (p_enable) {
1087 add_to_group("_vp_shortcut_input" + itos(get_viewport()->get_instance_id()));
1088 } else {
1089 remove_from_group("_vp_shortcut_input" + itos(get_viewport()->get_instance_id()));
1090 }
1091}
1092
1093bool Node::is_processing_shortcut_input() const {
1094 return data.shortcut_input;
1095}
1096
1097void Node::set_process_unhandled_input(bool p_enable) {
1098 ERR_THREAD_GUARD
1099 if (p_enable == data.unhandled_input) {
1100 return;
1101 }
1102 data.unhandled_input = p_enable;
1103 if (!is_inside_tree()) {
1104 return;
1105 }
1106
1107 if (p_enable) {
1108 add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
1109 } else {
1110 remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
1111 }
1112}
1113
1114bool Node::is_processing_unhandled_input() const {
1115 return data.unhandled_input;
1116}
1117
1118void Node::set_process_unhandled_key_input(bool p_enable) {
1119 ERR_THREAD_GUARD
1120 if (p_enable == data.unhandled_key_input) {
1121 return;
1122 }
1123 data.unhandled_key_input = p_enable;
1124 if (!is_inside_tree()) {
1125 return;
1126 }
1127
1128 if (p_enable) {
1129 add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
1130 } else {
1131 remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
1132 }
1133}
1134
1135bool Node::is_processing_unhandled_key_input() const {
1136 return data.unhandled_key_input;
1137}
1138
1139StringName Node::get_name() const {
1140 return data.name;
1141}
1142
1143void Node::_set_name_nocheck(const StringName &p_name) {
1144 data.name = p_name;
1145}
1146
1147void Node::set_name(const String &p_name) {
1148 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)`.");
1149 String name = p_name.validate_node_name();
1150
1151 ERR_FAIL_COND(name.is_empty());
1152
1153 if (data.unique_name_in_owner && data.owner) {
1154 _release_unique_name_in_owner();
1155 }
1156 String old_name = data.name;
1157 data.name = name;
1158
1159 if (data.parent) {
1160 data.parent->_validate_child_name(this, true);
1161 bool success = data.parent->data.children.replace_key(old_name, data.name);
1162 ERR_FAIL_COND_MSG(!success, "Renaming child in hashtable failed, this is a bug.");
1163 }
1164
1165 if (data.unique_name_in_owner && data.owner) {
1166 _acquire_unique_name_in_owner();
1167 }
1168
1169 propagate_notification(NOTIFICATION_PATH_RENAMED);
1170
1171 if (is_inside_tree()) {
1172 emit_signal(SNAME("renamed"));
1173 get_tree()->node_renamed(this);
1174 get_tree()->tree_changed();
1175 }
1176}
1177
1178// Returns a clear description of this node depending on what is available. Useful for error messages.
1179String Node::get_description() const {
1180 String description;
1181 if (is_inside_tree()) {
1182 description = get_path();
1183 } else {
1184 description = get_name();
1185 if (description.is_empty()) {
1186 description = get_class();
1187 }
1188 }
1189 return description;
1190}
1191
1192static SafeRefCount node_hrcr_count;
1193
1194void Node::init_node_hrcr() {
1195 node_hrcr_count.init(1);
1196}
1197
1198#ifdef TOOLS_ENABLED
1199String Node::validate_child_name(Node *p_child) {
1200 StringName name = p_child->data.name;
1201 _generate_serial_child_name(p_child, name);
1202 return name;
1203}
1204#endif
1205
1206String Node::adjust_name_casing(const String &p_name) {
1207 switch (GLOBAL_GET("editor/naming/node_name_casing").operator int()) {
1208 case NAME_CASING_PASCAL_CASE:
1209 return p_name.to_pascal_case();
1210 case NAME_CASING_CAMEL_CASE:
1211 return p_name.to_camel_case();
1212 case NAME_CASING_SNAKE_CASE:
1213 return p_name.to_snake_case();
1214 }
1215 return p_name;
1216}
1217
1218void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
1219 /* Make sure the name is unique */
1220
1221 if (p_force_human_readable) {
1222 //this approach to autoset node names is human readable but very slow
1223
1224 StringName name = p_child->data.name;
1225 _generate_serial_child_name(p_child, name);
1226 p_child->data.name = name;
1227
1228 } else {
1229 //this approach to autoset node names is fast but not as readable
1230 //it's the default and reserves the '@' character for unique names.
1231
1232 bool unique = true;
1233
1234 if (p_child->data.name == StringName()) {
1235 //new unique name must be assigned
1236 unique = false;
1237 } else {
1238 const Node *const *existing = data.children.getptr(p_child->data.name);
1239 unique = !existing || *existing == p_child;
1240 }
1241
1242 if (!unique) {
1243 ERR_FAIL_COND(!node_hrcr_count.ref());
1244 // Optimized version of the code below:
1245 // String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get());
1246 uint32_t c = node_hrcr_count.get();
1247 String cn = p_child->get_class_name().operator String();
1248 const char32_t *cn_ptr = cn.ptr();
1249 uint32_t cn_length = cn.length();
1250 uint32_t c_chars = String::num_characters(c);
1251 uint32_t len = 2 + cn_length + c_chars;
1252 char32_t *str = (char32_t *)alloca(sizeof(char32_t) * (len + 1));
1253 uint32_t idx = 0;
1254 str[idx++] = '@';
1255 for (uint32_t i = 0; i < cn_length; i++) {
1256 str[idx++] = cn_ptr[i];
1257 }
1258 str[idx++] = '@';
1259 idx += c_chars;
1260 ERR_FAIL_COND(idx != len);
1261 str[idx] = 0;
1262 while (c) {
1263 str[--idx] = '0' + (c % 10);
1264 c /= 10;
1265 }
1266 p_child->data.name = String(str);
1267 }
1268 }
1269}
1270
1271// Return s + 1 as if it were an integer
1272String increase_numeric_string(const String &s) {
1273 String res = s;
1274 bool carry = res.length() > 0;
1275
1276 for (int i = res.length() - 1; i >= 0; i--) {
1277 if (!carry) {
1278 break;
1279 }
1280 char32_t n = s[i];
1281 if (n == '9') { // keep carry as true: 9 + 1
1282 res[i] = '0';
1283 } else {
1284 res[i] = s[i] + 1;
1285 carry = false;
1286 }
1287 }
1288
1289 if (carry) {
1290 res = "1" + res;
1291 }
1292
1293 return res;
1294}
1295
1296void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const {
1297 if (name == StringName()) {
1298 // No name and a new name is needed, create one.
1299
1300 name = p_child->get_class();
1301 }
1302
1303 const Node *const *existing = data.children.getptr(name);
1304 if (!existing || *existing == p_child) { // Unused, or is current node.
1305 return;
1306 }
1307
1308 // Extract trailing number
1309 String name_string = name;
1310 String nums;
1311 for (int i = name_string.length() - 1; i >= 0; i--) {
1312 char32_t n = name_string[i];
1313 if (is_digit(n)) {
1314 nums = String::chr(name_string[i]) + nums;
1315 } else {
1316 break;
1317 }
1318 }
1319
1320 String nnsep = _get_name_num_separator();
1321 int name_last_index = name_string.length() - nnsep.length() - nums.length();
1322
1323 // Assign the base name + separator to name if we have numbers preceded by a separator
1324 if (nums.length() > 0 && name_string.substr(name_last_index, nnsep.length()) == nnsep) {
1325 name_string = name_string.substr(0, name_last_index + nnsep.length());
1326 } else {
1327 nums = "";
1328 }
1329
1330 for (;;) {
1331 StringName attempt = name_string + nums;
1332
1333 existing = data.children.getptr(attempt);
1334 bool exists = existing != nullptr && *existing != p_child;
1335
1336 if (!exists) {
1337 name = attempt;
1338 return;
1339 } else {
1340 if (nums.length() == 0) {
1341 // Name was undecorated so skip to 2 for a more natural result
1342 nums = "2";
1343 name_string += nnsep; // Add separator because nums.length() > 0 was false
1344 } else {
1345 nums = increase_numeric_string(nums);
1346 }
1347 }
1348 }
1349}
1350
1351Node::InternalMode Node::get_internal_mode() const {
1352 return data.internal_mode;
1353}
1354
1355void Node::_add_child_nocheck(Node *p_child, const StringName &p_name, InternalMode p_internal_mode) {
1356 //add a child node quickly, without name validation
1357
1358 p_child->data.name = p_name;
1359 data.children.insert(p_name, p_child);
1360
1361 p_child->data.internal_mode = p_internal_mode;
1362 switch (p_internal_mode) {
1363 case INTERNAL_MODE_FRONT: {
1364 p_child->data.index = data.internal_children_front_count_cache++;
1365 } break;
1366 case INTERNAL_MODE_BACK: {
1367 p_child->data.index = data.internal_children_back_count_cache++;
1368 } break;
1369 case INTERNAL_MODE_DISABLED: {
1370 p_child->data.index = data.external_children_count_cache++;
1371 } break;
1372 }
1373
1374 p_child->data.parent = this;
1375
1376 if (!data.children_cache_dirty && p_internal_mode == INTERNAL_MODE_DISABLED && data.internal_children_back_count_cache == 0) {
1377 // Special case, also add to the cached children array since its cheap.
1378 data.children_cache.push_back(p_child);
1379 } else {
1380 data.children_cache_dirty = true;
1381 }
1382
1383 p_child->notification(NOTIFICATION_PARENTED);
1384
1385 if (data.tree) {
1386 p_child->_set_tree(data.tree);
1387 }
1388
1389 /* Notify */
1390 //recognize children created in this node constructor
1391 p_child->data.parent_owned = data.in_constructor;
1392 add_child_notify(p_child);
1393 notification(NOTIFICATION_CHILD_ORDER_CHANGED);
1394 emit_signal(SNAME("child_order_changed"));
1395}
1396
1397void Node::add_child(Node *p_child, bool p_force_readable_name, InternalMode p_internal) {
1398 ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Adding children to a node inside the SceneTree is only allowed from the main thread. Use call_deferred(\"add_child\",node).");
1399
1400 ERR_THREAD_GUARD
1401 ERR_FAIL_NULL(p_child);
1402 ERR_FAIL_COND_MSG(p_child == this, vformat("Can't add child '%s' to itself.", p_child->get_name())); // adding to itself!
1403 ERR_FAIL_COND_MSG(p_child->data.parent, vformat("Can't add child '%s' to '%s', already has a parent '%s'.", p_child->get_name(), get_name(), p_child->data.parent->get_name())); //Fail if node has a parent
1404#ifdef DEBUG_ENABLED
1405 ERR_FAIL_COND_MSG(p_child->is_ancestor_of(this), vformat("Can't add child '%s' to '%s' as it would result in a cyclic dependency since '%s' is already a parent of '%s'.", p_child->get_name(), get_name(), p_child->get_name(), get_name()));
1406#endif
1407 ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, `add_child()` failed. Consider using `add_child.call_deferred(child)` instead.");
1408
1409 _validate_child_name(p_child, p_force_readable_name);
1410 _add_child_nocheck(p_child, p_child->data.name, p_internal);
1411}
1412
1413void Node::add_sibling(Node *p_sibling, bool p_force_readable_name) {
1414 ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Adding a sibling to a node inside the SceneTree is only allowed from the main thread. Use call_deferred(\"add_sibling\",node).");
1415 ERR_FAIL_NULL(p_sibling);
1416 ERR_FAIL_COND_MSG(p_sibling == this, vformat("Can't add sibling '%s' to itself.", p_sibling->get_name())); // adding to itself!
1417 ERR_FAIL_NULL(data.parent);
1418 ERR_FAIL_COND_MSG(data.parent->data.blocked > 0, "Parent node is busy setting up children, `add_sibling()` failed. Consider using `add_sibling.call_deferred(sibling)` instead.");
1419
1420 data.parent->add_child(p_sibling, p_force_readable_name, data.internal_mode);
1421 data.parent->_update_children_cache();
1422 data.parent->_move_child(p_sibling, get_index() + 1);
1423}
1424
1425void Node::remove_child(Node *p_child) {
1426 ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Removing children from a node inside the SceneTree is only allowed from the main thread. Use call_deferred(\"remove_child\",node).");
1427 ERR_FAIL_NULL(p_child);
1428 ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy adding/removing children, `remove_child()` can't be called at this time. Consider using `remove_child.call_deferred(child)` instead.");
1429 ERR_FAIL_COND(p_child->data.parent != this);
1430
1431 /**
1432 * Do not change the data.internal_children*cache counters here.
1433 * Because if nodes are re-added, the indices can remain
1434 * greater-than-everything indices and children added remain
1435 * properly ordered.
1436 *
1437 * All children indices and counters will be updated next time the
1438 * cache is re-generated.
1439 */
1440
1441 data.blocked++;
1442 p_child->_set_tree(nullptr);
1443 //}
1444
1445 remove_child_notify(p_child);
1446 p_child->notification(NOTIFICATION_UNPARENTED);
1447
1448 data.blocked--;
1449
1450 data.children_cache_dirty = true;
1451 bool success = data.children.erase(p_child->data.name);
1452 ERR_FAIL_COND_MSG(!success, "Children name does not match parent name in hashtable, this is a bug.");
1453
1454 p_child->data.parent = nullptr;
1455 p_child->data.index = -1;
1456
1457 notification(NOTIFICATION_CHILD_ORDER_CHANGED);
1458 emit_signal(SNAME("child_order_changed"));
1459
1460 if (data.inside_tree) {
1461 p_child->_propagate_after_exit_tree();
1462 }
1463}
1464
1465void Node::_update_children_cache_impl() const {
1466 // Assign children
1467 data.children_cache.resize(data.children.size());
1468 int idx = 0;
1469 for (const KeyValue<StringName, Node *> &K : data.children) {
1470 data.children_cache[idx] = K.value;
1471 idx++;
1472 }
1473 // Sort them
1474 data.children_cache.sort_custom<ComparatorByIndex>();
1475 // Update indices
1476 data.external_children_count_cache = 0;
1477 data.internal_children_back_count_cache = 0;
1478 data.internal_children_front_count_cache = 0;
1479
1480 for (uint32_t i = 0; i < data.children_cache.size(); i++) {
1481 switch (data.children_cache[i]->data.internal_mode) {
1482 case INTERNAL_MODE_DISABLED: {
1483 data.children_cache[i]->data.index = data.external_children_count_cache++;
1484 } break;
1485 case INTERNAL_MODE_FRONT: {
1486 data.children_cache[i]->data.index = data.internal_children_front_count_cache++;
1487 } break;
1488 case INTERNAL_MODE_BACK: {
1489 data.children_cache[i]->data.index = data.internal_children_back_count_cache++;
1490 } break;
1491 }
1492 }
1493 data.children_cache_dirty = false;
1494}
1495
1496int Node::get_child_count(bool p_include_internal) const {
1497 ERR_THREAD_GUARD_V(0);
1498 _update_children_cache();
1499
1500 if (p_include_internal) {
1501 return data.children_cache.size();
1502 } else {
1503 return data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache;
1504 }
1505}
1506
1507Node *Node::get_child(int p_index, bool p_include_internal) const {
1508 ERR_THREAD_GUARD_V(nullptr);
1509 _update_children_cache();
1510
1511 if (p_include_internal) {
1512 if (p_index < 0) {
1513 p_index += data.children_cache.size();
1514 }
1515 ERR_FAIL_INDEX_V(p_index, (int)data.children_cache.size(), nullptr);
1516 return data.children_cache[p_index];
1517 } else {
1518 if (p_index < 0) {
1519 p_index += (int)data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache;
1520 }
1521 ERR_FAIL_INDEX_V(p_index, (int)data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache, nullptr);
1522 p_index += data.internal_children_front_count_cache;
1523 return data.children_cache[p_index];
1524 }
1525}
1526
1527TypedArray<Node> Node::get_children(bool p_include_internal) const {
1528 ERR_THREAD_GUARD_V(TypedArray<Node>());
1529 TypedArray<Node> arr;
1530 int cc = get_child_count(p_include_internal);
1531 arr.resize(cc);
1532 for (int i = 0; i < cc; i++) {
1533 arr[i] = get_child(i, p_include_internal);
1534 }
1535
1536 return arr;
1537}
1538
1539Node *Node::_get_child_by_name(const StringName &p_name) const {
1540 const Node *const *node = data.children.getptr(p_name);
1541 if (node) {
1542 return const_cast<Node *>(*node);
1543 } else {
1544 return nullptr;
1545 }
1546}
1547
1548Node *Node::get_node_or_null(const NodePath &p_path) const {
1549 ERR_THREAD_GUARD_V(nullptr);
1550 if (p_path.is_empty()) {
1551 return nullptr;
1552 }
1553
1554 ERR_FAIL_COND_V_MSG(!data.inside_tree && p_path.is_absolute(), nullptr, "Can't use get_node() with absolute paths from outside the active scene tree.");
1555
1556 Node *current = nullptr;
1557 Node *root = nullptr;
1558
1559 if (!p_path.is_absolute()) {
1560 current = const_cast<Node *>(this); //start from this
1561 } else {
1562 root = const_cast<Node *>(this);
1563 while (root->data.parent) {
1564 root = root->data.parent; //start from root
1565 }
1566 }
1567
1568 for (int i = 0; i < p_path.get_name_count(); i++) {
1569 StringName name = p_path.get_name(i);
1570 Node *next = nullptr;
1571
1572 if (name == SceneStringNames::get_singleton()->dot) { // .
1573
1574 next = current;
1575
1576 } else if (name == SceneStringNames::get_singleton()->doubledot) { // ..
1577
1578 if (current == nullptr || !current->data.parent) {
1579 return nullptr;
1580 }
1581
1582 next = current->data.parent;
1583 } else if (current == nullptr) {
1584 if (name == root->get_name()) {
1585 next = root;
1586 }
1587
1588 } else if (name.is_node_unique_name()) {
1589 if (current->data.owned_unique_nodes.size()) {
1590 // Has unique nodes in ownership
1591 Node **unique = current->data.owned_unique_nodes.getptr(name);
1592 if (!unique) {
1593 return nullptr;
1594 }
1595 next = *unique;
1596 } else if (current->data.owner) {
1597 Node **unique = current->data.owner->data.owned_unique_nodes.getptr(name);
1598 if (!unique) {
1599 return nullptr;
1600 }
1601 next = *unique;
1602 } else {
1603 return nullptr;
1604 }
1605
1606 } else {
1607 next = nullptr;
1608 const Node *const *node = current->data.children.getptr(name);
1609 if (node) {
1610 next = const_cast<Node *>(*node);
1611 } else {
1612 return nullptr;
1613 }
1614 }
1615 current = next;
1616 }
1617
1618 return current;
1619}
1620
1621Node *Node::get_node(const NodePath &p_path) const {
1622 Node *node = get_node_or_null(p_path);
1623
1624 if (unlikely(!node)) {
1625 const String desc = get_description();
1626 if (p_path.is_absolute()) {
1627 ERR_FAIL_V_MSG(nullptr,
1628 vformat(R"(Node not found: "%s" (absolute path attempted from "%s").)", p_path, desc));
1629 } else {
1630 ERR_FAIL_V_MSG(nullptr,
1631 vformat(R"(Node not found: "%s" (relative to "%s").)", p_path, desc));
1632 }
1633 }
1634
1635 return node;
1636}
1637
1638bool Node::has_node(const NodePath &p_path) const {
1639 return get_node_or_null(p_path) != nullptr;
1640}
1641
1642// Finds the first child node (in tree order) whose name matches the given pattern.
1643// Can be recursive or not, and limited to owned nodes.
1644Node *Node::find_child(const String &p_pattern, bool p_recursive, bool p_owned) const {
1645 ERR_THREAD_GUARD_V(nullptr);
1646 ERR_FAIL_COND_V(p_pattern.is_empty(), nullptr);
1647 _update_children_cache();
1648 Node *const *cptr = data.children_cache.ptr();
1649 int ccount = data.children_cache.size();
1650 for (int i = 0; i < ccount; i++) {
1651 if (p_owned && !cptr[i]->data.owner) {
1652 continue;
1653 }
1654 if (cptr[i]->data.name.operator String().match(p_pattern)) {
1655 return cptr[i];
1656 }
1657
1658 if (!p_recursive) {
1659 continue;
1660 }
1661
1662 Node *ret = cptr[i]->find_child(p_pattern, true, p_owned);
1663 if (ret) {
1664 return ret;
1665 }
1666 }
1667 return nullptr;
1668}
1669
1670// Finds child nodes based on their name using pattern matching, or class name,
1671// or both (either pattern or type can be left empty).
1672// Can be recursive or not, and limited to owned nodes.
1673TypedArray<Node> Node::find_children(const String &p_pattern, const String &p_type, bool p_recursive, bool p_owned) const {
1674 ERR_THREAD_GUARD_V(TypedArray<Node>());
1675 TypedArray<Node> ret;
1676 ERR_FAIL_COND_V(p_pattern.is_empty() && p_type.is_empty(), ret);
1677 _update_children_cache();
1678 Node *const *cptr = data.children_cache.ptr();
1679 int ccount = data.children_cache.size();
1680 for (int i = 0; i < ccount; i++) {
1681 if (p_owned && !cptr[i]->data.owner) {
1682 continue;
1683 }
1684
1685 if (p_pattern.is_empty() || cptr[i]->data.name.operator String().match(p_pattern)) {
1686 if (p_type.is_empty() || cptr[i]->is_class(p_type)) {
1687 ret.append(cptr[i]);
1688 } else if (cptr[i]->get_script_instance()) {
1689 Ref<Script> scr = cptr[i]->get_script_instance()->get_script();
1690 while (scr.is_valid()) {
1691 if ((ScriptServer::is_global_class(p_type) && ScriptServer::get_global_class_path(p_type) == scr->get_path()) || p_type == scr->get_path()) {
1692 ret.append(cptr[i]);
1693 break;
1694 }
1695
1696 scr = scr->get_base_script();
1697 }
1698 }
1699 }
1700
1701 if (p_recursive) {
1702 ret.append_array(cptr[i]->find_children(p_pattern, p_type, true, p_owned));
1703 }
1704 }
1705
1706 return ret;
1707}
1708
1709void Node::reparent(Node *p_parent, bool p_keep_global_transform) {
1710 ERR_THREAD_GUARD
1711 ERR_FAIL_NULL(p_parent);
1712 ERR_FAIL_NULL_MSG(data.parent, "Node needs a parent to be reparented.");
1713
1714 if (p_parent == data.parent) {
1715 return;
1716 }
1717
1718 data.parent->remove_child(this);
1719 p_parent->add_child(this);
1720}
1721
1722Node *Node::get_parent() const {
1723 return data.parent;
1724}
1725
1726Node *Node::find_parent(const String &p_pattern) const {
1727 ERR_THREAD_GUARD_V(nullptr);
1728 Node *p = data.parent;
1729 while (p) {
1730 if (p->data.name.operator String().match(p_pattern)) {
1731 return p;
1732 }
1733 p = p->data.parent;
1734 }
1735
1736 return nullptr;
1737}
1738
1739Window *Node::get_window() const {
1740 ERR_THREAD_GUARD_V(nullptr);
1741 Viewport *vp = get_viewport();
1742 if (vp) {
1743 return vp->get_base_window();
1744 }
1745 return nullptr;
1746}
1747
1748Window *Node::get_last_exclusive_window() const {
1749 Window *w = get_window();
1750 while (w && w->get_exclusive_child()) {
1751 w = w->get_exclusive_child();
1752 }
1753
1754 return w;
1755}
1756
1757bool Node::is_ancestor_of(const Node *p_node) const {
1758 ERR_FAIL_NULL_V(p_node, false);
1759 Node *p = p_node->data.parent;
1760 while (p) {
1761 if (p == this) {
1762 return true;
1763 }
1764 p = p->data.parent;
1765 }
1766
1767 return false;
1768}
1769
1770bool Node::is_greater_than(const Node *p_node) const {
1771 ERR_FAIL_NULL_V(p_node, false);
1772 ERR_FAIL_COND_V(!data.inside_tree, false);
1773 ERR_FAIL_COND_V(!p_node->data.inside_tree, false);
1774
1775 ERR_FAIL_COND_V(data.depth < 0, false);
1776 ERR_FAIL_COND_V(p_node->data.depth < 0, false);
1777
1778 _update_children_cache();
1779
1780 int *this_stack = (int *)alloca(sizeof(int) * data.depth);
1781 int *that_stack = (int *)alloca(sizeof(int) * p_node->data.depth);
1782
1783 const Node *n = this;
1784
1785 int idx = data.depth - 1;
1786 while (n) {
1787 ERR_FAIL_INDEX_V(idx, data.depth, false);
1788 this_stack[idx--] = n->get_index();
1789 n = n->data.parent;
1790 }
1791
1792 ERR_FAIL_COND_V(idx != -1, false);
1793 n = p_node;
1794 idx = p_node->data.depth - 1;
1795 while (n) {
1796 ERR_FAIL_INDEX_V(idx, p_node->data.depth, false);
1797 that_stack[idx--] = n->get_index();
1798
1799 n = n->data.parent;
1800 }
1801 ERR_FAIL_COND_V(idx != -1, false);
1802 idx = 0;
1803
1804 bool res;
1805 while (true) {
1806 // using -2 since out-of-tree or nonroot nodes have -1
1807 int this_idx = (idx >= data.depth) ? -2 : this_stack[idx];
1808 int that_idx = (idx >= p_node->data.depth) ? -2 : that_stack[idx];
1809
1810 if (this_idx > that_idx) {
1811 res = true;
1812 break;
1813 } else if (this_idx < that_idx) {
1814 res = false;
1815 break;
1816 } else if (this_idx == -2) {
1817 res = false; // equal
1818 break;
1819 }
1820 idx++;
1821 }
1822
1823 return res;
1824}
1825
1826void Node::get_owned_by(Node *p_by, List<Node *> *p_owned) {
1827 if (data.owner == p_by) {
1828 p_owned->push_back(this);
1829 }
1830
1831 for (KeyValue<StringName, Node *> &K : data.children) {
1832 K.value->get_owned_by(p_by, p_owned);
1833 }
1834}
1835
1836void Node::_set_owner_nocheck(Node *p_owner) {
1837 if (data.owner == p_owner) {
1838 return;
1839 }
1840
1841 ERR_FAIL_COND(data.owner);
1842 data.owner = p_owner;
1843 data.owner->data.owned.push_back(this);
1844 data.OW = data.owner->data.owned.back();
1845
1846 owner_changed_notify();
1847}
1848
1849void Node::_release_unique_name_in_owner() {
1850 ERR_FAIL_NULL(data.owner); // Sanity check.
1851 StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.operator String());
1852 Node **which = data.owner->data.owned_unique_nodes.getptr(key);
1853 if (which == nullptr || *which != this) {
1854 return; // Ignore.
1855 }
1856 data.owner->data.owned_unique_nodes.erase(key);
1857}
1858
1859void Node::_acquire_unique_name_in_owner() {
1860 ERR_FAIL_NULL(data.owner); // Sanity check.
1861 StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.operator String());
1862 Node **which = data.owner->data.owned_unique_nodes.getptr(key);
1863 if (which != nullptr && *which != this) {
1864 String which_path = is_inside_tree() ? (*which)->get_path() : data.owner->get_path_to(*which);
1865 WARN_PRINT(vformat(RTR("Setting node name '%s' to be unique within scene for '%s', but it's already claimed by '%s'.\n'%s' is no longer set as having a unique name."),
1866 get_name(), is_inside_tree() ? get_path() : data.owner->get_path_to(this), which_path, which_path));
1867 data.unique_name_in_owner = false;
1868 return;
1869 }
1870 data.owner->data.owned_unique_nodes[key] = this;
1871}
1872
1873void Node::set_unique_name_in_owner(bool p_enabled) {
1874 ERR_MAIN_THREAD_GUARD
1875 if (data.unique_name_in_owner == p_enabled) {
1876 return;
1877 }
1878
1879 if (data.unique_name_in_owner && data.owner != nullptr) {
1880 _release_unique_name_in_owner();
1881 }
1882 data.unique_name_in_owner = p_enabled;
1883
1884 if (data.unique_name_in_owner && data.owner != nullptr) {
1885 _acquire_unique_name_in_owner();
1886 }
1887
1888 update_configuration_warnings();
1889}
1890
1891bool Node::is_unique_name_in_owner() const {
1892 return data.unique_name_in_owner;
1893}
1894
1895void Node::set_owner(Node *p_owner) {
1896 ERR_MAIN_THREAD_GUARD
1897 if (data.owner) {
1898 _clean_up_owner();
1899 }
1900
1901 ERR_FAIL_COND(p_owner == this);
1902
1903 if (!p_owner) {
1904 return;
1905 }
1906
1907 Node *check = this->get_parent();
1908 bool owner_valid = false;
1909
1910 while (check) {
1911 if (check == p_owner) {
1912 owner_valid = true;
1913 break;
1914 }
1915
1916 check = check->data.parent;
1917 }
1918
1919 ERR_FAIL_COND_MSG(!owner_valid, "Invalid owner. Owner must be an ancestor in the tree.");
1920
1921 _set_owner_nocheck(p_owner);
1922
1923 if (data.unique_name_in_owner) {
1924 _acquire_unique_name_in_owner();
1925 }
1926}
1927
1928Node *Node::get_owner() const {
1929 return data.owner;
1930}
1931
1932void Node::_clean_up_owner() {
1933 ERR_FAIL_NULL(data.owner); // Sanity check.
1934
1935 if (data.unique_name_in_owner) {
1936 _release_unique_name_in_owner();
1937 }
1938 data.owner->data.owned.erase(data.OW);
1939 data.owner = nullptr;
1940 data.OW = nullptr;
1941}
1942
1943Node *Node::find_common_parent_with(const Node *p_node) const {
1944 if (this == p_node) {
1945 return const_cast<Node *>(p_node);
1946 }
1947
1948 HashSet<const Node *> visited;
1949
1950 const Node *n = this;
1951
1952 while (n) {
1953 visited.insert(n);
1954 n = n->data.parent;
1955 }
1956
1957 const Node *common_parent = p_node;
1958
1959 while (common_parent) {
1960 if (visited.has(common_parent)) {
1961 break;
1962 }
1963 common_parent = common_parent->data.parent;
1964 }
1965
1966 if (!common_parent) {
1967 return nullptr;
1968 }
1969
1970 return const_cast<Node *>(common_parent);
1971}
1972
1973NodePath Node::get_path_to(const Node *p_node, bool p_use_unique_path) const {
1974 ERR_FAIL_NULL_V(p_node, NodePath());
1975
1976 if (this == p_node) {
1977 return NodePath(".");
1978 }
1979
1980 HashSet<const Node *> visited;
1981
1982 const Node *n = this;
1983
1984 while (n) {
1985 visited.insert(n);
1986 n = n->data.parent;
1987 }
1988
1989 const Node *common_parent = p_node;
1990
1991 while (common_parent) {
1992 if (visited.has(common_parent)) {
1993 break;
1994 }
1995 common_parent = common_parent->data.parent;
1996 }
1997
1998 ERR_FAIL_NULL_V(common_parent, NodePath()); //nodes not in the same tree
1999
2000 visited.clear();
2001
2002 Vector<StringName> path;
2003 StringName up = String("..");
2004
2005 if (p_use_unique_path) {
2006 n = p_node;
2007
2008 bool is_detected = false;
2009 while (n != common_parent) {
2010 if (n->is_unique_name_in_owner() && n->get_owner() == get_owner()) {
2011 path.push_back(UNIQUE_NODE_PREFIX + String(n->get_name()));
2012 is_detected = true;
2013 break;
2014 }
2015 path.push_back(n->get_name());
2016 n = n->data.parent;
2017 }
2018
2019 if (!is_detected) {
2020 n = this;
2021
2022 String detected_name;
2023 int up_count = 0;
2024 while (n != common_parent) {
2025 if (n->is_unique_name_in_owner() && n->get_owner() == get_owner()) {
2026 detected_name = n->get_name();
2027 up_count = 0;
2028 }
2029 up_count++;
2030 n = n->data.parent;
2031 }
2032
2033 for (int i = 0; i < up_count; i++) {
2034 path.push_back(up);
2035 }
2036
2037 if (!detected_name.is_empty()) {
2038 path.push_back(UNIQUE_NODE_PREFIX + detected_name);
2039 }
2040 }
2041 } else {
2042 n = p_node;
2043
2044 while (n != common_parent) {
2045 path.push_back(n->get_name());
2046 n = n->data.parent;
2047 }
2048
2049 n = this;
2050
2051 while (n != common_parent) {
2052 path.push_back(up);
2053 n = n->data.parent;
2054 }
2055 }
2056
2057 path.reverse();
2058
2059 return NodePath(path, false);
2060}
2061
2062NodePath Node::get_path() const {
2063 ERR_FAIL_COND_V_MSG(!is_inside_tree(), NodePath(), "Cannot get path of node as it is not in a scene tree.");
2064
2065 if (data.path_cache) {
2066 return *data.path_cache;
2067 }
2068
2069 const Node *n = this;
2070
2071 Vector<StringName> path;
2072
2073 while (n) {
2074 path.push_back(n->get_name());
2075 n = n->data.parent;
2076 }
2077
2078 path.reverse();
2079
2080 data.path_cache = memnew(NodePath(path, true));
2081
2082 return *data.path_cache;
2083}
2084
2085bool Node::is_in_group(const StringName &p_identifier) const {
2086 ERR_THREAD_GUARD_V(false);
2087 return data.grouped.has(p_identifier);
2088}
2089
2090void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
2091 ERR_THREAD_GUARD
2092 ERR_FAIL_COND(!p_identifier.operator String().length());
2093
2094 if (data.grouped.has(p_identifier)) {
2095 return;
2096 }
2097
2098 GroupData gd;
2099
2100 if (data.tree) {
2101 gd.group = data.tree->add_to_group(p_identifier, this);
2102 } else {
2103 gd.group = nullptr;
2104 }
2105
2106 gd.persistent = p_persistent;
2107
2108 data.grouped[p_identifier] = gd;
2109}
2110
2111void Node::remove_from_group(const StringName &p_identifier) {
2112 ERR_THREAD_GUARD
2113 HashMap<StringName, GroupData>::Iterator E = data.grouped.find(p_identifier);
2114
2115 if (!E) {
2116 return;
2117 }
2118
2119 if (data.tree) {
2120 data.tree->remove_from_group(E->key, this);
2121 }
2122
2123 data.grouped.remove(E);
2124}
2125
2126TypedArray<StringName> Node::_get_groups() const {
2127 TypedArray<StringName> groups;
2128 List<GroupInfo> gi;
2129 get_groups(&gi);
2130 for (const GroupInfo &E : gi) {
2131 groups.push_back(E.name);
2132 }
2133
2134 return groups;
2135}
2136
2137void Node::get_groups(List<GroupInfo> *p_groups) const {
2138 ERR_THREAD_GUARD
2139 for (const KeyValue<StringName, GroupData> &E : data.grouped) {
2140 GroupInfo gi;
2141 gi.name = E.key;
2142 gi.persistent = E.value.persistent;
2143 p_groups->push_back(gi);
2144 }
2145}
2146
2147int Node::get_persistent_group_count() const {
2148 ERR_THREAD_GUARD_V(0);
2149 int count = 0;
2150
2151 for (const KeyValue<StringName, GroupData> &E : data.grouped) {
2152 if (E.value.persistent) {
2153 count += 1;
2154 }
2155 }
2156
2157 return count;
2158}
2159
2160void Node::_print_tree_pretty(const String &prefix, const bool last) {
2161 String new_prefix = last ? String::utf8(" â”–â•´") : String::utf8(" â” â•´");
2162 print_line(prefix + new_prefix + String(get_name()));
2163 _update_children_cache();
2164 for (uint32_t i = 0; i < data.children_cache.size(); i++) {
2165 new_prefix = last ? String::utf8(" ") : String::utf8(" ┃ ");
2166 data.children_cache[i]->_print_tree_pretty(prefix + new_prefix, i == data.children_cache.size() - 1);
2167 }
2168}
2169
2170void Node::print_tree_pretty() {
2171 _print_tree_pretty("", true);
2172}
2173
2174void Node::print_tree() {
2175 _print_tree(this);
2176}
2177
2178void Node::_print_tree(const Node *p_node) {
2179 print_line(String(p_node->get_path_to(this)));
2180 _update_children_cache();
2181 for (uint32_t i = 0; i < data.children_cache.size(); i++) {
2182 data.children_cache[i]->_print_tree(p_node);
2183 }
2184}
2185
2186void Node::_propagate_reverse_notification(int p_notification) {
2187 data.blocked++;
2188
2189 for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) {
2190 I->value->_propagate_reverse_notification(p_notification);
2191 }
2192
2193 notification(p_notification, true);
2194 data.blocked--;
2195}
2196
2197void Node::_propagate_deferred_notification(int p_notification, bool p_reverse) {
2198 ERR_FAIL_COND(!is_inside_tree());
2199
2200 data.blocked++;
2201
2202 if (!p_reverse) {
2203 MessageQueue::get_singleton()->push_notification(this, p_notification);
2204 }
2205
2206 for (KeyValue<StringName, Node *> &K : data.children) {
2207 K.value->_propagate_deferred_notification(p_notification, p_reverse);
2208 }
2209
2210 if (p_reverse) {
2211 MessageQueue::get_singleton()->push_notification(this, p_notification);
2212 }
2213
2214 data.blocked--;
2215}
2216
2217void Node::propagate_notification(int p_notification) {
2218 ERR_THREAD_GUARD
2219 data.blocked++;
2220 notification(p_notification);
2221
2222 for (KeyValue<StringName, Node *> &K : data.children) {
2223 K.value->propagate_notification(p_notification);
2224 }
2225 data.blocked--;
2226}
2227
2228void Node::propagate_call(const StringName &p_method, const Array &p_args, const bool p_parent_first) {
2229 ERR_THREAD_GUARD
2230 data.blocked++;
2231
2232 if (p_parent_first && has_method(p_method)) {
2233 callv(p_method, p_args);
2234 }
2235
2236 for (KeyValue<StringName, Node *> &K : data.children) {
2237 K.value->propagate_call(p_method, p_args, p_parent_first);
2238 }
2239
2240 if (!p_parent_first && has_method(p_method)) {
2241 callv(p_method, p_args);
2242 }
2243
2244 data.blocked--;
2245}
2246
2247void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) {
2248 if (get_owner() == p_owner) {
2249 set_owner(p_by_owner);
2250 }
2251
2252 data.blocked++;
2253 for (KeyValue<StringName, Node *> &K : data.children) {
2254 K.value->_propagate_replace_owner(p_owner, p_by_owner);
2255 }
2256 data.blocked--;
2257}
2258
2259Ref<Tween> Node::create_tween() {
2260 ERR_THREAD_GUARD_V(Ref<Tween>());
2261 ERR_FAIL_NULL_V_MSG(data.tree, nullptr, "Can't create Tween when not inside scene tree.");
2262 Ref<Tween> tween = get_tree()->create_tween();
2263 tween->bind_node(this);
2264 return tween;
2265}
2266
2267void Node::set_scene_file_path(const String &p_scene_file_path) {
2268 ERR_THREAD_GUARD
2269 data.scene_file_path = p_scene_file_path;
2270}
2271
2272String Node::get_scene_file_path() const {
2273 return data.scene_file_path;
2274}
2275
2276void Node::set_editor_description(const String &p_editor_description) {
2277 ERR_THREAD_GUARD
2278 if (data.editor_description == p_editor_description) {
2279 return;
2280 }
2281
2282 data.editor_description = p_editor_description;
2283
2284 if (Engine::get_singleton()->is_editor_hint() && is_inside_tree()) {
2285 // Update tree so the tooltip in the Scene tree dock is also updated in the editor.
2286 get_tree()->tree_changed();
2287 }
2288}
2289
2290String Node::get_editor_description() const {
2291 return data.editor_description;
2292}
2293
2294void Node::set_editable_instance(Node *p_node, bool p_editable) {
2295 ERR_THREAD_GUARD
2296 ERR_FAIL_NULL(p_node);
2297 ERR_FAIL_COND(!is_ancestor_of(p_node));
2298 if (!p_editable) {
2299 p_node->data.editable_instance = false;
2300 // Avoid this flag being needlessly saved;
2301 // also give more visual feedback if editable children are re-enabled
2302 set_display_folded(false);
2303 } else {
2304 p_node->data.editable_instance = true;
2305 }
2306}
2307
2308bool Node::is_editable_instance(const Node *p_node) const {
2309 if (!p_node) {
2310 return false; // Easier, null is never editable. :)
2311 }
2312 ERR_FAIL_COND_V(!is_ancestor_of(p_node), false);
2313 return p_node->data.editable_instance;
2314}
2315
2316Node *Node::get_deepest_editable_node(Node *p_start_node) const {
2317 ERR_THREAD_GUARD_V(nullptr);
2318 ERR_FAIL_NULL_V(p_start_node, nullptr);
2319 ERR_FAIL_COND_V(!is_ancestor_of(p_start_node), p_start_node);
2320
2321 Node const *iterated_item = p_start_node;
2322 Node *node = p_start_node;
2323
2324 while (iterated_item->get_owner() && iterated_item->get_owner() != this) {
2325 if (!is_editable_instance(iterated_item->get_owner())) {
2326 node = iterated_item->get_owner();
2327 }
2328
2329 iterated_item = iterated_item->get_owner();
2330 }
2331
2332 return node;
2333}
2334
2335#ifdef TOOLS_ENABLED
2336void Node::set_property_pinned(const String &p_property, bool p_pinned) {
2337 ERR_THREAD_GUARD
2338 bool current_pinned = false;
2339 Array pinned = get_meta("_edit_pinned_properties_", Array());
2340 StringName psa = get_property_store_alias(p_property);
2341 current_pinned = pinned.has(psa);
2342
2343 if (current_pinned != p_pinned) {
2344 if (p_pinned) {
2345 pinned.append(psa);
2346 } else {
2347 pinned.erase(psa);
2348 }
2349 }
2350
2351 if (pinned.is_empty()) {
2352 remove_meta("_edit_pinned_properties_");
2353 } else {
2354 set_meta("_edit_pinned_properties_", pinned);
2355 }
2356}
2357
2358bool Node::is_property_pinned(const StringName &p_property) const {
2359 Array pinned = get_meta("_edit_pinned_properties_", Array());
2360 StringName psa = get_property_store_alias(p_property);
2361 return pinned.has(psa);
2362}
2363
2364StringName Node::get_property_store_alias(const StringName &p_property) const {
2365 return p_property;
2366}
2367
2368bool Node::is_part_of_edited_scene() const {
2369 return Engine::get_singleton()->is_editor_hint() && is_inside_tree() && get_tree()->get_edited_scene_root() &&
2370 (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this));
2371}
2372#endif
2373
2374void Node::get_storable_properties(HashSet<StringName> &r_storable_properties) const {
2375 ERR_THREAD_GUARD
2376 List<PropertyInfo> pi;
2377 get_property_list(&pi);
2378 for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
2379 if ((E->get().usage & PROPERTY_USAGE_STORAGE)) {
2380 r_storable_properties.insert(E->get().name);
2381 }
2382 }
2383}
2384
2385String Node::to_string() {
2386 ERR_THREAD_GUARD_V(String());
2387 if (get_script_instance()) {
2388 bool valid;
2389 String ret = get_script_instance()->to_string(&valid);
2390 if (valid) {
2391 return ret;
2392 }
2393 }
2394
2395 return (get_name() ? String(get_name()) + ":" : "") + Object::to_string();
2396}
2397
2398void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
2399 ERR_THREAD_GUARD
2400 data.instance_state = p_state;
2401}
2402
2403Ref<SceneState> Node::get_scene_instance_state() const {
2404 return data.instance_state;
2405}
2406
2407void Node::set_scene_inherited_state(const Ref<SceneState> &p_state) {
2408 ERR_THREAD_GUARD
2409 data.inherited_state = p_state;
2410}
2411
2412Ref<SceneState> Node::get_scene_inherited_state() const {
2413 return data.inherited_state;
2414}
2415
2416void Node::set_scene_instance_load_placeholder(bool p_enable) {
2417 data.use_placeholder = p_enable;
2418}
2419
2420bool Node::get_scene_instance_load_placeholder() const {
2421 return data.use_placeholder;
2422}
2423
2424Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) const {
2425 ERR_THREAD_GUARD_V(nullptr);
2426 Node *node = nullptr;
2427
2428 bool instantiated = false;
2429
2430 if (Object::cast_to<InstancePlaceholder>(this)) {
2431 const InstancePlaceholder *ip = Object::cast_to<const InstancePlaceholder>(this);
2432 InstancePlaceholder *nip = memnew(InstancePlaceholder);
2433 nip->set_instance_path(ip->get_instance_path());
2434 node = nip;
2435
2436 } else if ((p_flags & DUPLICATE_USE_INSTANTIATION) && !get_scene_file_path().is_empty()) {
2437 Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path());
2438 ERR_FAIL_COND_V(res.is_null(), nullptr);
2439 PackedScene::GenEditState edit_state = PackedScene::GEN_EDIT_STATE_DISABLED;
2440#ifdef TOOLS_ENABLED
2441 if (p_flags & DUPLICATE_FROM_EDITOR) {
2442 edit_state = PackedScene::GEN_EDIT_STATE_INSTANCE;
2443 }
2444#endif
2445 node = res->instantiate(edit_state);
2446 ERR_FAIL_NULL_V(node, nullptr);
2447 node->set_scene_instance_load_placeholder(get_scene_instance_load_placeholder());
2448
2449 instantiated = true;
2450
2451 } else {
2452 Object *obj = ClassDB::instantiate(get_class());
2453 ERR_FAIL_NULL_V(obj, nullptr);
2454 node = Object::cast_to<Node>(obj);
2455 if (!node) {
2456 memdelete(obj);
2457 }
2458 ERR_FAIL_NULL_V(node, nullptr);
2459 }
2460
2461 if (!get_scene_file_path().is_empty()) { //an instance
2462 node->set_scene_file_path(get_scene_file_path());
2463 node->data.editable_instance = data.editable_instance;
2464 }
2465
2466 StringName script_property_name = CoreStringNames::get_singleton()->_script;
2467
2468 List<const Node *> hidden_roots;
2469 List<const Node *> node_tree;
2470 node_tree.push_front(this);
2471
2472 if (instantiated) {
2473 // Since nodes in the instantiated hierarchy won't be duplicated explicitly, we need to make an inventory
2474 // of all the nodes in the tree of the instantiated scene in order to transfer the values of the properties
2475
2476 Vector<const Node *> instance_roots;
2477 instance_roots.push_back(this);
2478
2479 for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
2480 for (int i = 0; i < N->get()->get_child_count(); ++i) {
2481 Node *descendant = N->get()->get_child(i);
2482 // Skip nodes not really belonging to the instantiated hierarchy; they'll be processed normally later
2483 // but remember non-instantiated nodes that are hidden below instantiated ones
2484 if (!instance_roots.has(descendant->get_owner())) {
2485 if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) {
2486 hidden_roots.push_back(descendant);
2487 }
2488 continue;
2489 }
2490
2491 node_tree.push_back(descendant);
2492
2493 if (!descendant->get_scene_file_path().is_empty() && instance_roots.has(descendant->get_owner())) {
2494 instance_roots.push_back(descendant);
2495 }
2496 }
2497 }
2498 }
2499
2500 for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
2501 Node *current_node = node->get_node(get_path_to(N->get()));
2502 ERR_CONTINUE(!current_node);
2503
2504 if (p_flags & DUPLICATE_SCRIPTS) {
2505 bool is_valid = false;
2506 Variant scr = N->get()->get(script_property_name, &is_valid);
2507 if (is_valid) {
2508 current_node->set(script_property_name, scr);
2509 }
2510 }
2511
2512 List<PropertyInfo> plist;
2513 N->get()->get_property_list(&plist);
2514
2515 for (const PropertyInfo &E : plist) {
2516 if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
2517 continue;
2518 }
2519 String name = E.name;
2520 if (name == script_property_name) {
2521 continue;
2522 }
2523
2524 Variant value = N->get()->get(name).duplicate(true);
2525
2526 if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
2527 Resource *res = Object::cast_to<Resource>(value);
2528 if (res) { // Duplicate only if it's a resource
2529 current_node->set(name, res->duplicate());
2530 }
2531
2532 } else {
2533 current_node->set(name, value);
2534 }
2535 }
2536 }
2537
2538 if (get_name() != String()) {
2539 node->set_name(get_name());
2540 }
2541
2542#ifdef TOOLS_ENABLED
2543 if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) {
2544 r_duplimap->insert(this, node);
2545 }
2546#endif
2547
2548 if (p_flags & DUPLICATE_GROUPS) {
2549 List<GroupInfo> gi;
2550 get_groups(&gi);
2551 for (const GroupInfo &E : gi) {
2552#ifdef TOOLS_ENABLED
2553 if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) {
2554 continue;
2555 }
2556#endif
2557
2558 node->add_to_group(E.name, E.persistent);
2559 }
2560 }
2561
2562 for (int i = 0; i < get_child_count(); i++) {
2563 if (get_child(i)->data.parent_owned) {
2564 continue;
2565 }
2566 if (instantiated && get_child(i)->data.owner == this) {
2567 continue; //part of instance
2568 }
2569
2570 Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
2571 if (!dup) {
2572 memdelete(node);
2573 return nullptr;
2574 }
2575
2576 node->add_child(dup);
2577 if (i < node->get_child_count() - 1) {
2578 node->move_child(dup, i);
2579 }
2580 }
2581
2582 for (const Node *&E : hidden_roots) {
2583 Node *parent = node->get_node(get_path_to(E->data.parent));
2584 if (!parent) {
2585 memdelete(node);
2586 return nullptr;
2587 }
2588
2589 Node *dup = E->_duplicate(p_flags, r_duplimap);
2590 if (!dup) {
2591 memdelete(node);
2592 return nullptr;
2593 }
2594
2595 parent->add_child(dup);
2596 int pos = E->get_index();
2597
2598 if (pos < parent->get_child_count() - 1) {
2599 parent->move_child(dup, pos);
2600 }
2601 }
2602
2603 return node;
2604}
2605
2606Node *Node::duplicate(int p_flags) const {
2607 ERR_THREAD_GUARD_V(nullptr);
2608 Node *dupe = _duplicate(p_flags);
2609
2610 if (dupe && (p_flags & DUPLICATE_SIGNALS)) {
2611 _duplicate_signals(this, dupe);
2612 }
2613
2614 return dupe;
2615}
2616
2617#ifdef TOOLS_ENABLED
2618Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) const {
2619 return duplicate_from_editor(r_duplimap, HashMap<Ref<Resource>, Ref<Resource>>());
2620}
2621
2622Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
2623 Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap);
2624
2625 // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
2626 if (!p_resource_remap.is_empty()) {
2627 remap_node_resources(dupe, p_resource_remap);
2628 }
2629
2630 // Duplication of signals must happen after all the node descendants have been copied,
2631 // because re-targeting of connections from some descendant to another is not possible
2632 // if the emitter node comes later in tree order than the receiver
2633 _duplicate_signals(this, dupe);
2634
2635 return dupe;
2636}
2637
2638void Node::remap_node_resources(Node *p_node, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
2639 List<PropertyInfo> props;
2640 p_node->get_property_list(&props);
2641
2642 for (const PropertyInfo &E : props) {
2643 if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
2644 continue;
2645 }
2646
2647 Variant v = p_node->get(E.name);
2648 if (v.is_ref_counted()) {
2649 Ref<Resource> res = v;
2650 if (res.is_valid()) {
2651 if (p_resource_remap.has(res)) {
2652 p_node->set(E.name, p_resource_remap[res]);
2653 remap_nested_resources(res, p_resource_remap);
2654 }
2655 }
2656 }
2657 }
2658
2659 for (int i = 0; i < p_node->get_child_count(); i++) {
2660 remap_node_resources(p_node->get_child(i), p_resource_remap);
2661 }
2662}
2663
2664void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
2665 List<PropertyInfo> props;
2666 p_resource->get_property_list(&props);
2667
2668 for (const PropertyInfo &E : props) {
2669 if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
2670 continue;
2671 }
2672
2673 Variant v = p_resource->get(E.name);
2674 if (v.is_ref_counted()) {
2675 Ref<Resource> res = v;
2676 if (res.is_valid()) {
2677 if (p_resource_remap.has(res)) {
2678 p_resource->set(E.name, p_resource_remap[res]);
2679 remap_nested_resources(res, p_resource_remap);
2680 }
2681 }
2682 }
2683 }
2684}
2685#endif
2686
2687// Duplication of signals must happen after all the node descendants have been copied,
2688// because re-targeting of connections from some descendant to another is not possible
2689// if the emitter node comes later in tree order than the receiver
2690void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
2691 if ((this != p_original) && !(p_original->is_ancestor_of(this))) {
2692 return;
2693 }
2694
2695 List<const Node *> process_list;
2696 process_list.push_back(this);
2697 while (!process_list.is_empty()) {
2698 const Node *n = process_list.front()->get();
2699 process_list.pop_front();
2700
2701 List<Connection> conns;
2702 n->get_all_signal_connections(&conns);
2703
2704 for (const Connection &E : conns) {
2705 if (E.flags & CONNECT_PERSIST) {
2706 //user connected
2707 NodePath p = p_original->get_path_to(n);
2708 Node *copy = p_copy->get_node(p);
2709
2710 Node *target = Object::cast_to<Node>(E.callable.get_object());
2711 if (!target) {
2712 continue;
2713 }
2714 NodePath ptarget = p_original->get_path_to(target);
2715
2716 Node *copytarget = target;
2717
2718 // Attempt to find a path to the duplicate target, if it seems it's not part
2719 // of the duplicated and not yet parented hierarchy then at least try to connect
2720 // to the same target as the original
2721
2722 if (p_copy->has_node(ptarget)) {
2723 copytarget = p_copy->get_node(ptarget);
2724 }
2725
2726 if (copy && copytarget && E.callable.get_method() != StringName()) {
2727 Callable copy_callable = Callable(copytarget, E.callable.get_method());
2728 if (!copy->is_connected(E.signal.get_name(), copy_callable)) {
2729 int arg_count = E.callable.get_bound_arguments_count();
2730 if (arg_count > 0) {
2731 copy_callable = copy_callable.bindv(E.callable.get_bound_arguments());
2732 } else if (arg_count < 0) {
2733 copy_callable = copy_callable.unbind(-arg_count);
2734 }
2735 copy->connect(E.signal.get_name(), copy_callable, E.flags);
2736 }
2737 }
2738 }
2739 }
2740
2741 for (int i = 0; i < n->get_child_count(); i++) {
2742 process_list.push_back(n->get_child(i));
2743 }
2744 }
2745}
2746
2747static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) {
2748 if (p_node->get_owner() == p_by) {
2749 p_owned->push_back(p_node);
2750 }
2751
2752 for (int i = 0; i < p_node->get_child_count(); i++) {
2753 find_owned_by(p_by, p_node->get_child(i), p_owned);
2754 }
2755}
2756
2757void Node::replace_by(Node *p_node, bool p_keep_groups) {
2758 ERR_THREAD_GUARD
2759 ERR_FAIL_NULL(p_node);
2760 ERR_FAIL_COND(p_node->data.parent);
2761
2762 List<Node *> owned = data.owned;
2763 List<Node *> owned_by_owner;
2764 Node *owner = (data.owner == this) ? p_node : data.owner;
2765
2766 if (p_keep_groups) {
2767 List<GroupInfo> groups;
2768 get_groups(&groups);
2769
2770 for (const GroupInfo &E : groups) {
2771 p_node->add_to_group(E.name, E.persistent);
2772 }
2773 }
2774
2775 _replace_connections_target(p_node);
2776
2777 if (data.owner) {
2778 for (int i = 0; i < get_child_count(); i++) {
2779 find_owned_by(data.owner, get_child(i), &owned_by_owner);
2780 }
2781
2782 _clean_up_owner();
2783 }
2784
2785 Node *parent = data.parent;
2786 int index_in_parent = get_index();
2787
2788 if (data.parent) {
2789 parent->remove_child(this);
2790 parent->add_child(p_node);
2791 parent->move_child(p_node, index_in_parent);
2792 }
2793
2794 emit_signal(SNAME("replacing_by"), p_node);
2795
2796 while (get_child_count()) {
2797 Node *child = get_child(0);
2798 remove_child(child);
2799 if (!child->is_owned_by_parent()) {
2800 // add the custom children to the p_node
2801 p_node->add_child(child);
2802 }
2803 }
2804
2805 p_node->set_owner(owner);
2806 for (int i = 0; i < owned.size(); i++) {
2807 owned[i]->set_owner(p_node);
2808 }
2809
2810 for (int i = 0; i < owned_by_owner.size(); i++) {
2811 owned_by_owner[i]->set_owner(owner);
2812 }
2813
2814 p_node->set_scene_file_path(get_scene_file_path());
2815}
2816
2817void Node::_replace_connections_target(Node *p_new_target) {
2818 List<Connection> cl;
2819 get_signals_connected_to_this(&cl);
2820
2821 for (const Connection &c : cl) {
2822 if (c.flags & CONNECT_PERSIST) {
2823 c.signal.get_object()->disconnect(c.signal.get_name(), Callable(this, c.callable.get_method()));
2824 bool valid = p_new_target->has_method(c.callable.get_method()) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.callable.get_method());
2825 ERR_CONTINUE_MSG(!valid, vformat("Attempt to connect signal '%s.%s' to nonexistent method '%s.%s'.", c.signal.get_object()->get_class(), c.signal.get_name(), c.callable.get_object()->get_class(), c.callable.get_method()));
2826 c.signal.get_object()->connect(c.signal.get_name(), Callable(p_new_target, c.callable.get_method()), c.flags);
2827 }
2828 }
2829}
2830
2831bool Node::has_node_and_resource(const NodePath &p_path) const {
2832 ERR_THREAD_GUARD_V(false);
2833 if (!has_node(p_path)) {
2834 return false;
2835 }
2836 Ref<Resource> res;
2837 Vector<StringName> leftover_path;
2838 Node *node = get_node_and_resource(p_path, res, leftover_path, false);
2839
2840 return node;
2841}
2842
2843Array Node::_get_node_and_resource(const NodePath &p_path) {
2844 Ref<Resource> res;
2845 Vector<StringName> leftover_path;
2846 Node *node = get_node_and_resource(p_path, res, leftover_path, false);
2847 Array result;
2848
2849 if (node) {
2850 result.push_back(node);
2851 } else {
2852 result.push_back(Variant());
2853 }
2854
2855 if (res.is_valid()) {
2856 result.push_back(res);
2857 } else {
2858 result.push_back(Variant());
2859 }
2860
2861 result.push_back(NodePath(Vector<StringName>(), leftover_path, false));
2862
2863 return result;
2864}
2865
2866Node *Node::get_node_and_resource(const NodePath &p_path, Ref<Resource> &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property) const {
2867 ERR_THREAD_GUARD_V(nullptr);
2868 Node *node = get_node(p_path);
2869 r_res = Ref<Resource>();
2870 r_leftover_subpath = Vector<StringName>();
2871 if (!node) {
2872 return nullptr;
2873 }
2874
2875 if (p_path.get_subname_count()) {
2876 int j = 0;
2877 // If not p_last_is_property, we shouldn't consider the last one as part of the resource
2878 for (; j < p_path.get_subname_count() - (int)p_last_is_property; j++) {
2879 bool is_valid = false;
2880 Variant new_res_v = j == 0 ? node->get(p_path.get_subname(j), &is_valid) : r_res->get(p_path.get_subname(j), &is_valid);
2881
2882 if (!is_valid) { // Found nothing on that path
2883 return nullptr;
2884 }
2885
2886 Ref<Resource> new_res = new_res_v;
2887
2888 if (new_res.is_null()) { // No longer a resource, assume property
2889 break;
2890 }
2891
2892 r_res = new_res;
2893 }
2894 for (; j < p_path.get_subname_count(); j++) {
2895 // Put the rest of the subpath in the leftover path
2896 r_leftover_subpath.push_back(p_path.get_subname(j));
2897 }
2898 }
2899
2900 return node;
2901}
2902
2903void Node::_set_tree(SceneTree *p_tree) {
2904 SceneTree *tree_changed_a = nullptr;
2905 SceneTree *tree_changed_b = nullptr;
2906
2907 //ERR_FAIL_COND(p_scene && data.parent && !data.parent->data.scene); //nobug if both are null
2908
2909 if (data.tree) {
2910 _propagate_exit_tree();
2911
2912 tree_changed_a = data.tree;
2913 }
2914
2915 data.tree = p_tree;
2916
2917 if (data.tree) {
2918 _propagate_enter_tree();
2919 if (!data.parent || data.parent->data.ready_notified) { // No parent (root) or parent ready
2920 _propagate_ready(); //reverse_notification(NOTIFICATION_READY);
2921 }
2922
2923 tree_changed_b = data.tree;
2924 }
2925
2926 if (tree_changed_a) {
2927 tree_changed_a->tree_changed();
2928 }
2929 if (tree_changed_b) {
2930 tree_changed_b->tree_changed();
2931 }
2932}
2933
2934#ifdef DEBUG_ENABLED
2935static HashMap<ObjectID, List<String>> _print_orphan_nodes_map;
2936
2937static void _print_orphan_nodes_routine(Object *p_obj) {
2938 Node *n = Object::cast_to<Node>(p_obj);
2939 if (!n) {
2940 return;
2941 }
2942
2943 if (n->is_inside_tree()) {
2944 return;
2945 }
2946
2947 Node *p = n;
2948 while (p->get_parent()) {
2949 p = p->get_parent();
2950 }
2951
2952 String path;
2953 if (p == n) {
2954 path = n->get_name();
2955 } else {
2956 path = String(p->get_name()) + "/" + p->get_path_to(n);
2957 }
2958
2959 List<String> info_strings;
2960 info_strings.push_back(path);
2961 info_strings.push_back(n->get_class());
2962
2963 _print_orphan_nodes_map[p_obj->get_instance_id()] = info_strings;
2964}
2965#endif // DEBUG_ENABLED
2966
2967void Node::print_orphan_nodes() {
2968#ifdef DEBUG_ENABLED
2969 // Make sure it's empty.
2970 _print_orphan_nodes_map.clear();
2971
2972 // Collect and print information about orphan nodes.
2973 ObjectDB::debug_objects(_print_orphan_nodes_routine);
2974
2975 for (const KeyValue<ObjectID, List<String>> &E : _print_orphan_nodes_map) {
2976 print_line(itos(E.key) + " - Stray Node: " + E.value[0] + " (Type: " + E.value[1] + ")");
2977 }
2978
2979 // Flush it after use.
2980 _print_orphan_nodes_map.clear();
2981#endif
2982}
2983
2984void Node::queue_free() {
2985 // There are users which instantiate multiple scene trees for their games.
2986 // Use the node's own tree to handle its deletion when relevant.
2987 if (is_inside_tree()) {
2988 get_tree()->queue_delete(this);
2989 } else {
2990 SceneTree *tree = SceneTree::get_singleton();
2991 ERR_FAIL_NULL_MSG(tree, "Can't queue free a node when no SceneTree is available.");
2992 tree->queue_delete(this);
2993 }
2994}
2995
2996void Node::set_import_path(const NodePath &p_import_path) {
2997#ifdef TOOLS_ENABLED
2998 data.import_path = p_import_path;
2999#endif
3000}
3001
3002NodePath Node::get_import_path() const {
3003#ifdef TOOLS_ENABLED
3004 return data.import_path;
3005#else
3006 return NodePath();
3007#endif
3008}
3009
3010static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) {
3011 if (p_node != p_base && !p_node->get_owner()) {
3012 return;
3013 }
3014 String n = p_base->get_path_to(p_node);
3015 r_options->push_back(n.quote());
3016 for (int i = 0; i < p_node->get_child_count(); i++) {
3017 _add_nodes_to_options(p_base, p_node->get_child(i), r_options);
3018 }
3019}
3020
3021void Node::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
3022 String pf = p_function;
3023 if ((pf == "has_node" || pf == "get_node") && p_idx == 0) {
3024 _add_nodes_to_options(this, this, r_options);
3025 }
3026 Object::get_argument_options(p_function, p_idx, r_options);
3027}
3028
3029void Node::clear_internal_tree_resource_paths() {
3030 clear_internal_resource_paths();
3031 for (KeyValue<StringName, Node *> &K : data.children) {
3032 K.value->clear_internal_tree_resource_paths();
3033 }
3034}
3035
3036PackedStringArray Node::get_configuration_warnings() const {
3037 ERR_THREAD_GUARD_V(PackedStringArray());
3038 PackedStringArray ret;
3039
3040 Vector<String> warnings;
3041 if (GDVIRTUAL_CALL(_get_configuration_warnings, warnings)) {
3042 ret.append_array(warnings);
3043 }
3044
3045 return ret;
3046}
3047
3048String Node::get_configuration_warnings_as_string() const {
3049 PackedStringArray warnings = get_configuration_warnings();
3050 String all_warnings;
3051 for (int i = 0; i < warnings.size(); i++) {
3052 if (i > 0) {
3053 all_warnings += "\n\n";
3054 }
3055 // Format as a bullet point list to make multiple warnings easier to distinguish
3056 // from each other.
3057 all_warnings += String::utf8("• ") + warnings[i];
3058 }
3059 return all_warnings;
3060}
3061
3062void Node::update_configuration_warnings() {
3063 ERR_THREAD_GUARD
3064#ifdef TOOLS_ENABLED
3065 if (!is_inside_tree()) {
3066 return;
3067 }
3068 if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) {
3069 get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this);
3070 }
3071#endif
3072}
3073
3074bool Node::is_owned_by_parent() const {
3075 return data.parent_owned;
3076}
3077
3078void Node::set_display_folded(bool p_folded) {
3079 ERR_THREAD_GUARD
3080 data.display_folded = p_folded;
3081}
3082
3083bool Node::is_displayed_folded() const {
3084 return data.display_folded;
3085}
3086
3087bool Node::is_ready() const {
3088 return !data.ready_first;
3089}
3090
3091void Node::request_ready() {
3092 ERR_THREAD_GUARD
3093 data.ready_first = true;
3094}
3095
3096void Node::_call_input(const Ref<InputEvent> &p_event) {
3097 if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
3098 GDVIRTUAL_CALL(_input, p_event);
3099 }
3100 if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
3101 return;
3102 }
3103 input(p_event);
3104}
3105
3106void Node::_call_shortcut_input(const Ref<InputEvent> &p_event) {
3107 if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
3108 GDVIRTUAL_CALL(_shortcut_input, p_event);
3109 }
3110 if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
3111 return;
3112 }
3113 shortcut_input(p_event);
3114}
3115
3116void Node::_call_unhandled_input(const Ref<InputEvent> &p_event) {
3117 if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
3118 GDVIRTUAL_CALL(_unhandled_input, p_event);
3119 }
3120 if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
3121 return;
3122 }
3123 unhandled_input(p_event);
3124}
3125
3126void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) {
3127 if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
3128 GDVIRTUAL_CALL(_unhandled_key_input, p_event);
3129 }
3130 if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
3131 return;
3132 }
3133 unhandled_key_input(p_event);
3134}
3135
3136void Node::_validate_property(PropertyInfo &p_property) const {
3137 if ((p_property.name == "process_thread_group_order" || p_property.name == "process_thread_messages") && data.process_thread_group == PROCESS_THREAD_GROUP_INHERIT) {
3138 p_property.usage = 0;
3139 }
3140}
3141
3142void Node::input(const Ref<InputEvent> &p_event) {
3143}
3144
3145void Node::shortcut_input(const Ref<InputEvent> &p_key_event) {
3146}
3147
3148void Node::unhandled_input(const Ref<InputEvent> &p_event) {
3149}
3150
3151void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) {
3152}
3153
3154Variant Node::_call_deferred_thread_group_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
3155 if (p_argcount < 1) {
3156 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
3157 r_error.argument = 0;
3158 return Variant();
3159 }
3160
3161 if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
3162 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
3163 r_error.argument = 0;
3164 r_error.expected = Variant::STRING_NAME;
3165 return Variant();
3166 }
3167
3168 r_error.error = Callable::CallError::CALL_OK;
3169
3170 StringName method = *p_args[0];
3171
3172 call_deferred_thread_groupp(method, &p_args[1], p_argcount - 1, true);
3173
3174 return Variant();
3175}
3176
3177Variant Node::_call_thread_safe_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
3178 if (p_argcount < 1) {
3179 r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
3180 r_error.argument = 0;
3181 return Variant();
3182 }
3183
3184 if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
3185 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
3186 r_error.argument = 0;
3187 r_error.expected = Variant::STRING_NAME;
3188 return Variant();
3189 }
3190
3191 r_error.error = Callable::CallError::CALL_OK;
3192
3193 StringName method = *p_args[0];
3194
3195 call_thread_safep(method, &p_args[1], p_argcount - 1, true);
3196
3197 return Variant();
3198}
3199
3200void Node::call_deferred_thread_groupp(const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) {
3201 ERR_FAIL_COND(!is_inside_tree());
3202 SceneTree::ProcessGroup *pg = (SceneTree::ProcessGroup *)data.process_group;
3203 pg->call_queue.push_callp(this, p_method, p_args, p_argcount, p_show_error);
3204}
3205void Node::set_deferred_thread_group(const StringName &p_property, const Variant &p_value) {
3206 ERR_FAIL_COND(!is_inside_tree());
3207 SceneTree::ProcessGroup *pg = (SceneTree::ProcessGroup *)data.process_group;
3208 pg->call_queue.push_set(this, p_property, p_value);
3209}
3210void Node::notify_deferred_thread_group(int p_notification) {
3211 ERR_FAIL_COND(!is_inside_tree());
3212 SceneTree::ProcessGroup *pg = (SceneTree::ProcessGroup *)data.process_group;
3213 pg->call_queue.push_notification(this, p_notification);
3214}
3215
3216void Node::call_thread_safep(const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) {
3217 if (is_accessible_from_caller_thread()) {
3218 Callable::CallError ce;
3219 callp(p_method, p_args, p_argcount, ce);
3220 if (p_show_error && ce.error != Callable::CallError::CALL_OK) {
3221 ERR_FAIL_MSG("Error calling method from 'call_threadp': " + Variant::get_call_error_text(this, p_method, p_args, p_argcount, ce) + ".");
3222 }
3223 } else {
3224 call_deferred_thread_groupp(p_method, p_args, p_argcount, p_show_error);
3225 }
3226}
3227void Node::set_thread_safe(const StringName &p_property, const Variant &p_value) {
3228 if (is_accessible_from_caller_thread()) {
3229 set(p_property, p_value);
3230 } else {
3231 set_deferred_thread_group(p_property, p_value);
3232 }
3233}
3234void Node::notify_thread_safe(int p_notification) {
3235 if (is_accessible_from_caller_thread()) {
3236 notification(p_notification);
3237 } else {
3238 notify_deferred_thread_group(p_notification);
3239 }
3240}
3241
3242void Node::_bind_methods() {
3243 GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/node_name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"), 0);
3244 GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/node_name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"), NAME_CASING_PASCAL_CASE);
3245
3246 ClassDB::bind_static_method("Node", D_METHOD("print_orphan_nodes"), &Node::print_orphan_nodes);
3247 ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "force_readable_name"), &Node::add_sibling, DEFVAL(false));
3248
3249 ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name);
3250 ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name);
3251 ClassDB::bind_method(D_METHOD("add_child", "node", "force_readable_name", "internal"), &Node::add_child, DEFVAL(false), DEFVAL(0));
3252 ClassDB::bind_method(D_METHOD("remove_child", "node"), &Node::remove_child);
3253 ClassDB::bind_method(D_METHOD("reparent", "new_parent", "keep_global_transform"), &Node::reparent, DEFVAL(true));
3254 ClassDB::bind_method(D_METHOD("get_child_count", "include_internal"), &Node::get_child_count, DEFVAL(false)); // Note that the default value bound for include_internal is false, while the method is declared with true. This is because internal nodes are irrelevant for GDSCript.
3255 ClassDB::bind_method(D_METHOD("get_children", "include_internal"), &Node::get_children, DEFVAL(false));
3256 ClassDB::bind_method(D_METHOD("get_child", "idx", "include_internal"), &Node::get_child, DEFVAL(false));
3257 ClassDB::bind_method(D_METHOD("has_node", "path"), &Node::has_node);
3258 ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node);
3259 ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null);
3260 ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent);
3261 ClassDB::bind_method(D_METHOD("find_child", "pattern", "recursive", "owned"), &Node::find_child, DEFVAL(true), DEFVAL(true));
3262 ClassDB::bind_method(D_METHOD("find_children", "pattern", "type", "recursive", "owned"), &Node::find_children, DEFVAL(""), DEFVAL(true), DEFVAL(true));
3263 ClassDB::bind_method(D_METHOD("find_parent", "pattern"), &Node::find_parent);
3264 ClassDB::bind_method(D_METHOD("has_node_and_resource", "path"), &Node::has_node_and_resource);
3265 ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
3266
3267 ClassDB::bind_method(D_METHOD("is_inside_tree"), &Node::is_inside_tree);
3268 ClassDB::bind_method(D_METHOD("is_ancestor_of", "node"), &Node::is_ancestor_of);
3269 ClassDB::bind_method(D_METHOD("is_greater_than", "node"), &Node::is_greater_than);
3270 ClassDB::bind_method(D_METHOD("get_path"), &Node::get_path);
3271 ClassDB::bind_method(D_METHOD("get_path_to", "node", "use_unique_path"), &Node::get_path_to, DEFVAL(false));
3272 ClassDB::bind_method(D_METHOD("add_to_group", "group", "persistent"), &Node::add_to_group, DEFVAL(false));
3273 ClassDB::bind_method(D_METHOD("remove_from_group", "group"), &Node::remove_from_group);
3274 ClassDB::bind_method(D_METHOD("is_in_group", "group"), &Node::is_in_group);
3275 ClassDB::bind_method(D_METHOD("move_child", "child_node", "to_index"), &Node::move_child);
3276 ClassDB::bind_method(D_METHOD("get_groups"), &Node::_get_groups);
3277 ClassDB::bind_method(D_METHOD("set_owner", "owner"), &Node::set_owner);
3278 ClassDB::bind_method(D_METHOD("get_owner"), &Node::get_owner);
3279 ClassDB::bind_method(D_METHOD("get_index", "include_internal"), &Node::get_index, DEFVAL(false));
3280 ClassDB::bind_method(D_METHOD("print_tree"), &Node::print_tree);
3281 ClassDB::bind_method(D_METHOD("print_tree_pretty"), &Node::print_tree_pretty);
3282 ClassDB::bind_method(D_METHOD("set_scene_file_path", "scene_file_path"), &Node::set_scene_file_path);
3283 ClassDB::bind_method(D_METHOD("get_scene_file_path"), &Node::get_scene_file_path);
3284 ClassDB::bind_method(D_METHOD("propagate_notification", "what"), &Node::propagate_notification);
3285 ClassDB::bind_method(D_METHOD("propagate_call", "method", "args", "parent_first"), &Node::propagate_call, DEFVAL(Array()), DEFVAL(false));
3286 ClassDB::bind_method(D_METHOD("set_physics_process", "enable"), &Node::set_physics_process);
3287 ClassDB::bind_method(D_METHOD("get_physics_process_delta_time"), &Node::get_physics_process_delta_time);
3288 ClassDB::bind_method(D_METHOD("is_physics_processing"), &Node::is_physics_processing);
3289 ClassDB::bind_method(D_METHOD("get_process_delta_time"), &Node::get_process_delta_time);
3290 ClassDB::bind_method(D_METHOD("set_process", "enable"), &Node::set_process);
3291 ClassDB::bind_method(D_METHOD("set_process_priority", "priority"), &Node::set_process_priority);
3292 ClassDB::bind_method(D_METHOD("get_process_priority"), &Node::get_process_priority);
3293 ClassDB::bind_method(D_METHOD("set_physics_process_priority", "priority"), &Node::set_physics_process_priority);
3294 ClassDB::bind_method(D_METHOD("get_physics_process_priority"), &Node::get_physics_process_priority);
3295 ClassDB::bind_method(D_METHOD("is_processing"), &Node::is_processing);
3296 ClassDB::bind_method(D_METHOD("set_process_input", "enable"), &Node::set_process_input);
3297 ClassDB::bind_method(D_METHOD("is_processing_input"), &Node::is_processing_input);
3298 ClassDB::bind_method(D_METHOD("set_process_shortcut_input", "enable"), &Node::set_process_shortcut_input);
3299 ClassDB::bind_method(D_METHOD("is_processing_shortcut_input"), &Node::is_processing_shortcut_input);
3300 ClassDB::bind_method(D_METHOD("set_process_unhandled_input", "enable"), &Node::set_process_unhandled_input);
3301 ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input);
3302 ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input);
3303 ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input);
3304 ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode);
3305 ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode);
3306 ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process);
3307
3308 ClassDB::bind_method(D_METHOD("set_process_thread_group", "mode"), &Node::set_process_thread_group);
3309 ClassDB::bind_method(D_METHOD("get_process_thread_group"), &Node::get_process_thread_group);
3310
3311 ClassDB::bind_method(D_METHOD("set_process_thread_messages", "flags"), &Node::set_process_thread_messages);
3312 ClassDB::bind_method(D_METHOD("get_process_thread_messages"), &Node::get_process_thread_messages);
3313
3314 ClassDB::bind_method(D_METHOD("set_process_thread_group_order", "order"), &Node::set_process_thread_group_order);
3315 ClassDB::bind_method(D_METHOD("get_process_thread_group_order"), &Node::get_process_thread_group_order);
3316
3317 ClassDB::bind_method(D_METHOD("set_display_folded", "fold"), &Node::set_display_folded);
3318 ClassDB::bind_method(D_METHOD("is_displayed_folded"), &Node::is_displayed_folded);
3319
3320 ClassDB::bind_method(D_METHOD("set_process_internal", "enable"), &Node::set_process_internal);
3321 ClassDB::bind_method(D_METHOD("is_processing_internal"), &Node::is_processing_internal);
3322
3323 ClassDB::bind_method(D_METHOD("set_physics_process_internal", "enable"), &Node::set_physics_process_internal);
3324 ClassDB::bind_method(D_METHOD("is_physics_processing_internal"), &Node::is_physics_processing_internal);
3325
3326 ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
3327 ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
3328 ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree);
3329 ClassDB::bind_method(D_METHOD("create_tween"), &Node::create_tween);
3330
3331 ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANTIATION | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS));
3332 ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false));
3333
3334 ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder);
3335 ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder);
3336 ClassDB::bind_method(D_METHOD("set_editable_instance", "node", "is_editable"), &Node::set_editable_instance);
3337 ClassDB::bind_method(D_METHOD("is_editable_instance", "node"), &Node::is_editable_instance);
3338
3339 ClassDB::bind_method(D_METHOD("get_viewport"), &Node::get_viewport);
3340
3341 ClassDB::bind_method(D_METHOD("queue_free"), &Node::queue_free);
3342
3343 ClassDB::bind_method(D_METHOD("request_ready"), &Node::request_ready);
3344 ClassDB::bind_method(D_METHOD("is_node_ready"), &Node::is_ready);
3345
3346 ClassDB::bind_method(D_METHOD("set_multiplayer_authority", "id", "recursive"), &Node::set_multiplayer_authority, DEFVAL(true));
3347 ClassDB::bind_method(D_METHOD("get_multiplayer_authority"), &Node::get_multiplayer_authority);
3348
3349 ClassDB::bind_method(D_METHOD("is_multiplayer_authority"), &Node::is_multiplayer_authority);
3350
3351 ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
3352 ClassDB::bind_method(D_METHOD("rpc_config", "method", "config"), &Node::rpc_config);
3353
3354 ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
3355 ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
3356
3357 ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path);
3358 ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
3359
3360 ClassDB::bind_method(D_METHOD("set_unique_name_in_owner", "enable"), &Node::set_unique_name_in_owner);
3361 ClassDB::bind_method(D_METHOD("is_unique_name_in_owner"), &Node::is_unique_name_in_owner);
3362
3363#ifdef TOOLS_ENABLED
3364 ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned);
3365#endif
3366
3367 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
3368
3369 {
3370 MethodInfo mi;
3371
3372 mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
3373
3374 mi.name = "rpc";
3375 ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc", &Node::_rpc_bind, mi);
3376
3377 mi.arguments.push_front(PropertyInfo(Variant::INT, "peer_id"));
3378
3379 mi.name = "rpc_id";
3380 ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc_id", &Node::_rpc_id_bind, mi);
3381 }
3382
3383 ClassDB::bind_method(D_METHOD("update_configuration_warnings"), &Node::update_configuration_warnings);
3384
3385 {
3386 MethodInfo mi;
3387 mi.name = "call_deferred_thread_group";
3388 mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
3389
3390 ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_deferred_thread_group", &Node::_call_deferred_thread_group_bind, mi, varray(), false);
3391 }
3392 ClassDB::bind_method(D_METHOD("set_deferred_thread_group", "property", "value"), &Node::set_deferred_thread_group);
3393 ClassDB::bind_method(D_METHOD("notify_deferred_thread_group", "what"), &Node::notify_deferred_thread_group);
3394
3395 {
3396 MethodInfo mi;
3397 mi.name = "call_thread_safe";
3398 mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
3399
3400 ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_thread_safe", &Node::_call_thread_safe_bind, mi, varray(), false);
3401 }
3402 ClassDB::bind_method(D_METHOD("set_thread_safe", "property", "value"), &Node::set_thread_safe);
3403 ClassDB::bind_method(D_METHOD("notify_thread_safe", "what"), &Node::notify_thread_safe);
3404
3405 BIND_CONSTANT(NOTIFICATION_ENTER_TREE);
3406 BIND_CONSTANT(NOTIFICATION_EXIT_TREE);
3407 BIND_CONSTANT(NOTIFICATION_MOVED_IN_PARENT);
3408 BIND_CONSTANT(NOTIFICATION_READY);
3409 BIND_CONSTANT(NOTIFICATION_PAUSED);
3410 BIND_CONSTANT(NOTIFICATION_UNPAUSED);
3411 BIND_CONSTANT(NOTIFICATION_PHYSICS_PROCESS);
3412 BIND_CONSTANT(NOTIFICATION_PROCESS);
3413 BIND_CONSTANT(NOTIFICATION_PARENTED);
3414 BIND_CONSTANT(NOTIFICATION_UNPARENTED);
3415 BIND_CONSTANT(NOTIFICATION_SCENE_INSTANTIATED);
3416 BIND_CONSTANT(NOTIFICATION_DRAG_BEGIN);
3417 BIND_CONSTANT(NOTIFICATION_DRAG_END);
3418 BIND_CONSTANT(NOTIFICATION_PATH_RENAMED);
3419 BIND_CONSTANT(NOTIFICATION_CHILD_ORDER_CHANGED);
3420 BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS);
3421 BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
3422 BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE);
3423 BIND_CONSTANT(NOTIFICATION_DISABLED);
3424 BIND_CONSTANT(NOTIFICATION_ENABLED);
3425 BIND_CONSTANT(NOTIFICATION_NODE_RECACHE_REQUESTED);
3426
3427 BIND_CONSTANT(NOTIFICATION_EDITOR_PRE_SAVE);
3428 BIND_CONSTANT(NOTIFICATION_EDITOR_POST_SAVE);
3429
3430 BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
3431 BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
3432 BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_IN);
3433 BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_OUT);
3434 BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST);
3435 BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
3436 BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED);
3437 BIND_CONSTANT(NOTIFICATION_WM_DPI_CHANGE);
3438 BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
3439 BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
3440 BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
3441 BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
3442 BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
3443 BIND_CONSTANT(NOTIFICATION_CRASH);
3444 BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
3445 BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED);
3446 BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED);
3447 BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN);
3448 BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
3449 BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
3450
3451 BIND_ENUM_CONSTANT(PROCESS_MODE_INHERIT);
3452 BIND_ENUM_CONSTANT(PROCESS_MODE_PAUSABLE);
3453 BIND_ENUM_CONSTANT(PROCESS_MODE_WHEN_PAUSED);
3454 BIND_ENUM_CONSTANT(PROCESS_MODE_ALWAYS);
3455 BIND_ENUM_CONSTANT(PROCESS_MODE_DISABLED);
3456
3457 BIND_ENUM_CONSTANT(PROCESS_THREAD_GROUP_INHERIT);
3458 BIND_ENUM_CONSTANT(PROCESS_THREAD_GROUP_MAIN_THREAD);
3459 BIND_ENUM_CONSTANT(PROCESS_THREAD_GROUP_SUB_THREAD);
3460
3461 BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES);
3462 BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_PHYSICS);
3463 BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_ALL);
3464
3465 BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
3466 BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
3467 BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS);
3468 BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANTIATION);
3469
3470 BIND_ENUM_CONSTANT(INTERNAL_MODE_DISABLED);
3471 BIND_ENUM_CONSTANT(INTERNAL_MODE_FRONT);
3472 BIND_ENUM_CONSTANT(INTERNAL_MODE_BACK);
3473
3474 ADD_SIGNAL(MethodInfo("ready"));
3475 ADD_SIGNAL(MethodInfo("renamed"));
3476 ADD_SIGNAL(MethodInfo("tree_entered"));
3477 ADD_SIGNAL(MethodInfo("tree_exiting"));
3478 ADD_SIGNAL(MethodInfo("tree_exited"));
3479 ADD_SIGNAL(MethodInfo("child_entered_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
3480 ADD_SIGNAL(MethodInfo("child_exiting_tree", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
3481
3482 ADD_SIGNAL(MethodInfo("child_order_changed"));
3483 ADD_SIGNAL(MethodInfo("replacing_by", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
3484
3485 ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name");
3486 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "unique_name_in_owner", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_unique_name_in_owner", "is_unique_name_in_owner");
3487 ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path");
3488 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_owner", "get_owner");
3489 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "", "get_multiplayer");
3490
3491 ADD_GROUP("Process", "process_");
3492 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode");
3493 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority");
3494 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_physics_priority"), "set_physics_process_priority", "get_physics_process_priority");
3495 ADD_SUBGROUP("Thread Group", "process_thread");
3496 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_group", PROPERTY_HINT_ENUM, "Inherit,Main Thread,Sub Thread"), "set_process_thread_group", "get_process_thread_group");
3497 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_group_order"), "set_process_thread_group_order", "get_process_thread_group_order");
3498 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_messages", PROPERTY_HINT_FLAGS, "Process,Physics Process"), "set_process_thread_messages", "get_process_thread_messages");
3499
3500 ADD_GROUP("Editor Description", "editor_");
3501 ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT), "set_editor_description", "get_editor_description");
3502
3503 GDVIRTUAL_BIND(_process, "delta");
3504 GDVIRTUAL_BIND(_physics_process, "delta");
3505 GDVIRTUAL_BIND(_enter_tree);
3506 GDVIRTUAL_BIND(_exit_tree);
3507 GDVIRTUAL_BIND(_ready);
3508 GDVIRTUAL_BIND(_get_configuration_warnings);
3509 GDVIRTUAL_BIND(_input, "event");
3510 GDVIRTUAL_BIND(_shortcut_input, "event");
3511 GDVIRTUAL_BIND(_unhandled_input, "event");
3512 GDVIRTUAL_BIND(_unhandled_key_input, "event");
3513}
3514
3515String Node::_get_name_num_separator() {
3516 switch (GLOBAL_GET("editor/naming/node_name_num_separator").operator int()) {
3517 case 0:
3518 return "";
3519 case 1:
3520 return " ";
3521 case 2:
3522 return "_";
3523 case 3:
3524 return "-";
3525 }
3526 return " ";
3527}
3528
3529Node::Node() {
3530 orphan_node_count++;
3531}
3532
3533Node::~Node() {
3534 data.grouped.clear();
3535 data.owned.clear();
3536 data.children.clear();
3537 data.children_cache.clear();
3538
3539 ERR_FAIL_COND(data.parent);
3540 ERR_FAIL_COND(data.children_cache.size());
3541
3542 orphan_node_count--;
3543}
3544
3545////////////////////////////////
3546// Multithreaded locked version of Object functions.
3547
3548#ifdef DEBUG_ENABLED
3549
3550void Node::set_script(const Variant &p_script) {
3551 ERR_THREAD_GUARD;
3552 Object::set_script(p_script);
3553}
3554
3555Variant Node::get_script() const {
3556 ERR_THREAD_GUARD_V(Variant());
3557 return Object::get_script();
3558}
3559
3560bool Node::has_meta(const StringName &p_name) const {
3561 ERR_THREAD_GUARD_V(false);
3562 return Object::has_meta(p_name);
3563}
3564
3565void Node::set_meta(const StringName &p_name, const Variant &p_value) {
3566 ERR_THREAD_GUARD;
3567 Object::set_meta(p_name, p_value);
3568}
3569
3570void Node::remove_meta(const StringName &p_name) {
3571 ERR_THREAD_GUARD;
3572 Object::remove_meta(p_name);
3573}
3574
3575Variant Node::get_meta(const StringName &p_name, const Variant &p_default) const {
3576 ERR_THREAD_GUARD_V(Variant());
3577 return Object::get_meta(p_name, p_default);
3578}
3579
3580void Node::get_meta_list(List<StringName> *p_list) const {
3581 ERR_THREAD_GUARD;
3582 Object::get_meta_list(p_list);
3583}
3584
3585Error Node::emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount) {
3586 ERR_THREAD_GUARD_V(ERR_INVALID_PARAMETER);
3587 return Object::emit_signalp(p_name, p_args, p_argcount);
3588}
3589
3590bool Node::has_signal(const StringName &p_name) const {
3591 ERR_THREAD_GUARD_V(false);
3592 return Object::has_signal(p_name);
3593}
3594
3595void Node::get_signal_list(List<MethodInfo> *p_signals) const {
3596 ERR_THREAD_GUARD;
3597 Object::get_signal_list(p_signals);
3598}
3599
3600void Node::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
3601 ERR_THREAD_GUARD;
3602 Object::get_signal_connection_list(p_signal, p_connections);
3603}
3604
3605void Node::get_all_signal_connections(List<Connection> *p_connections) const {
3606 ERR_THREAD_GUARD;
3607 Object::get_all_signal_connections(p_connections);
3608}
3609
3610int Node::get_persistent_signal_connection_count() const {
3611 ERR_THREAD_GUARD_V(0);
3612 return Object::get_persistent_signal_connection_count();
3613}
3614
3615void Node::get_signals_connected_to_this(List<Connection> *p_connections) const {
3616 ERR_THREAD_GUARD;
3617 Object::get_signals_connected_to_this(p_connections);
3618}
3619
3620Error Node::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) {
3621 ERR_THREAD_GUARD_V(ERR_INVALID_PARAMETER);
3622 return Object::connect(p_signal, p_callable, p_flags);
3623}
3624
3625void Node::disconnect(const StringName &p_signal, const Callable &p_callable) {
3626 ERR_THREAD_GUARD;
3627 Object::disconnect(p_signal, p_callable);
3628}
3629
3630bool Node::is_connected(const StringName &p_signal, const Callable &p_callable) const {
3631 ERR_THREAD_GUARD_V(false);
3632 return Object::is_connected(p_signal, p_callable);
3633}
3634
3635#endif
3636