feat: updated engine
This commit is contained in:
parent
cbe99774ff
commit
f4cf6b3999
6607 changed files with 910135 additions and 430025 deletions
|
|
@ -38,18 +38,26 @@ STATIC_ASSERT_INCOMPLETE_TYPE(class, Shader);
|
|||
STATIC_ASSERT_INCOMPLETE_TYPE(class, OS);
|
||||
STATIC_ASSERT_INCOMPLETE_TYPE(class, Engine);
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/resource.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/object/message_queue.h"
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/string/print_string.h"
|
||||
#include "instance_placeholder.h"
|
||||
#include "scene/animation/tween.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/main/instance_placeholder.h"
|
||||
#include "scene/main/multiplayer_api.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/main/window.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "viewport.h"
|
||||
#include "servers/display/accessibility_server.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
SafeNumeric<uint64_t> Node::total_node_count{ 0 };
|
||||
|
|
@ -61,7 +69,7 @@ void Node::_notification(int p_notification) {
|
|||
switch (p_notification) {
|
||||
case NOTIFICATION_ACCESSIBILITY_INVALIDATE: {
|
||||
if (data.accessibility_element.is_valid()) {
|
||||
DisplayServer::get_singleton()->accessibility_free_element(data.accessibility_element);
|
||||
AccessibilityServer::get_singleton()->free_element(data.accessibility_element);
|
||||
data.accessibility_element = RID();
|
||||
}
|
||||
} break;
|
||||
|
|
@ -70,7 +78,7 @@ void Node::_notification(int p_notification) {
|
|||
RID ae = get_accessibility_element();
|
||||
ERR_FAIL_COND(ae.is_null());
|
||||
|
||||
DisplayServer::get_singleton()->accessibility_update_set_name(ae, get_name());
|
||||
AccessibilityServer::get_singleton()->update_set_name(ae, get_name());
|
||||
|
||||
// Node children.
|
||||
if (!accessibility_override_tree_hierarchy()) {
|
||||
|
|
@ -83,7 +91,7 @@ void Node::_notification(int p_notification) {
|
|||
if (child_node->is_part_of_edited_scene()) {
|
||||
continue;
|
||||
}
|
||||
DisplayServer::get_singleton()->accessibility_update_add_child(ae, child_node->get_accessibility_element());
|
||||
AccessibilityServer::get_singleton()->update_add_child(ae, child_node->get_accessibility_element());
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
|
@ -178,9 +186,7 @@ void Node::_notification(int p_notification) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
if (data.auto_translate_mode != AUTO_TRANSLATE_MODE_DISABLED) {
|
||||
notification(NOTIFICATION_TRANSLATION_CHANGED);
|
||||
}
|
||||
notification(NOTIFICATION_TRANSLATION_CHANGED);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
|
|
@ -189,7 +195,7 @@ void Node::_notification(int p_notification) {
|
|||
|
||||
if (data.tree->is_accessibility_supported() && !is_part_of_edited_scene()) {
|
||||
if (data.accessibility_element.is_valid()) {
|
||||
DisplayServer::get_singleton()->accessibility_free_element(data.accessibility_element);
|
||||
AccessibilityServer::get_singleton()->free_element(data.accessibility_element);
|
||||
data.accessibility_element = RID();
|
||||
}
|
||||
data.tree->_accessibility_notify_change(this, true);
|
||||
|
|
@ -899,8 +905,7 @@ bool Node::can_process_notification(int p_what) const {
|
|||
}
|
||||
|
||||
bool Node::can_process() const {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
return !data.tree->is_suspended() && _can_process(data.tree->is_paused());
|
||||
return is_inside_tree() && !data.tree->is_suspended() && _can_process(data.tree->is_paused());
|
||||
}
|
||||
|
||||
bool Node::_can_process(bool p_paused) const {
|
||||
|
|
@ -964,6 +969,10 @@ void Node::set_physics_interpolation_mode(PhysicsInterpolationMode p_mode) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Node::is_physics_interpolated_and_enabled() const {
|
||||
return SceneTree::is_fti_enabled() && is_physics_interpolated();
|
||||
}
|
||||
|
||||
void Node::reset_physics_interpolation() {
|
||||
if (SceneTree::is_fti_enabled() && is_inside_tree()) {
|
||||
propagate_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
|
||||
|
|
@ -1096,10 +1105,6 @@ void Node::_remove_tree_from_process_thread_group() {
|
|||
}
|
||||
|
||||
void Node::_add_tree_to_process_thread_group(Node *p_owner) {
|
||||
if (_is_any_processing()) {
|
||||
_add_to_process_thread_group();
|
||||
}
|
||||
|
||||
data.process_thread_group_owner = p_owner;
|
||||
if (p_owner != nullptr) {
|
||||
data.process_group = p_owner->data.process_group;
|
||||
|
|
@ -1107,12 +1112,16 @@ void Node::_add_tree_to_process_thread_group(Node *p_owner) {
|
|||
data.process_group = &data.tree->default_process_group;
|
||||
}
|
||||
|
||||
if (_is_any_processing()) {
|
||||
_add_to_process_thread_group();
|
||||
}
|
||||
|
||||
for (KeyValue<StringName, Node *> &K : data.children) {
|
||||
if (K.value->data.process_thread_group != PROCESS_THREAD_GROUP_INHERIT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
K.value->_add_to_process_thread_group();
|
||||
K.value->_add_tree_to_process_thread_group(p_owner);
|
||||
}
|
||||
}
|
||||
bool Node::is_processing_internal() const {
|
||||
|
|
@ -1466,7 +1475,7 @@ void Node::set_name(const StringName &p_name) {
|
|||
}
|
||||
|
||||
// Returns a clear description of this node depending on what is available. Useful for error messages.
|
||||
String Node::get_description() const {
|
||||
String Node::get_description(bool p_show_not_in_tree) const {
|
||||
String description;
|
||||
if (is_inside_tree()) {
|
||||
description = String(get_path());
|
||||
|
|
@ -1475,6 +1484,9 @@ String Node::get_description() const {
|
|||
if (description.is_empty()) {
|
||||
description = get_class();
|
||||
}
|
||||
if (p_show_not_in_tree) {
|
||||
description += " (not inside tree)";
|
||||
}
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
|
@ -1541,7 +1553,7 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
|
|||
// Optimized version of the code below:
|
||||
// String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get());
|
||||
uint32_t c = node_hrcr_count.get();
|
||||
String cn = p_child->get_class_name().operator String();
|
||||
String cn = p_child->get_class_name().string();
|
||||
const char32_t *cn_ptr = cn.ptr();
|
||||
uint32_t cn_length = cn.length();
|
||||
uint32_t c_chars = String::num_characters(c);
|
||||
|
|
@ -1756,7 +1768,25 @@ void Node::remove_child(RequiredParam<Node> rp_child) {
|
|||
|
||||
data.blocked--;
|
||||
|
||||
data.children_cache_dirty = true;
|
||||
if (!data.children_cache_dirty && !data.children_cache.is_empty() && data.children_cache[data.children_cache.size() - 1] == p_child) {
|
||||
// Removing the last child keeps the cache and the counters valid, so pop it
|
||||
// instead of dirtying the cache. This keeps interleaving removals with reads
|
||||
// (like get_child()) linear, as long as children are removed back to front.
|
||||
data.children_cache.resize(data.children_cache.size() - 1);
|
||||
switch (p_child->data.internal_mode) {
|
||||
case INTERNAL_MODE_DISABLED: {
|
||||
data.external_children_count_cache--;
|
||||
} break;
|
||||
case INTERNAL_MODE_FRONT: {
|
||||
data.internal_children_front_count_cache--;
|
||||
} break;
|
||||
case INTERNAL_MODE_BACK: {
|
||||
data.internal_children_back_count_cache--;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
data.children_cache_dirty = true;
|
||||
}
|
||||
bool success = data.children.erase(p_child->data.name);
|
||||
ERR_FAIL_COND_MSG(!success, "Children name does not match parent name in hashtable, this is a bug.");
|
||||
|
||||
|
|
@ -1984,7 +2014,7 @@ Node *Node::find_child(const String &p_pattern, bool p_recursive, bool p_owned)
|
|||
if (p_owned && !cptr[i]->data.owner) {
|
||||
continue;
|
||||
}
|
||||
if (cptr[i]->data.name.operator String().match(p_pattern)) {
|
||||
if (cptr[i]->data.name.string().match(p_pattern)) {
|
||||
return cptr[i];
|
||||
}
|
||||
|
||||
|
|
@ -2015,7 +2045,7 @@ TypedArray<Node> Node::find_children(const String &p_pattern, const String &p_ty
|
|||
continue;
|
||||
}
|
||||
|
||||
if (p_pattern.is_empty() || cptr[i]->data.name.operator String().match(p_pattern)) {
|
||||
if (p_pattern.is_empty() || cptr[i]->data.name.string().match(p_pattern)) {
|
||||
if (p_type.is_empty() || cptr[i]->is_class(p_type)) {
|
||||
ret.append(cptr[i]);
|
||||
} else if (cptr[i]->get_script_instance()) {
|
||||
|
|
@ -2093,7 +2123,7 @@ Node *Node::find_parent(const String &p_pattern) const {
|
|||
ERR_THREAD_GUARD_V(nullptr);
|
||||
Node *p = data.parent;
|
||||
while (p) {
|
||||
if (p->data.name.operator String().match(p_pattern)) {
|
||||
if (p->data.name.string().match(p_pattern)) {
|
||||
return p;
|
||||
}
|
||||
p = p->data.parent;
|
||||
|
|
@ -2138,12 +2168,23 @@ Window *Node::get_last_exclusive_window() const {
|
|||
|
||||
bool Node::is_ancestor_of(RequiredParam<const Node> rp_node) const {
|
||||
EXTRACT_PARAM_OR_FAIL_V(p_node, rp_node, false);
|
||||
Node *p = p_node->data.parent;
|
||||
while (p) {
|
||||
if (p == this) {
|
||||
|
||||
const Node *n = p_node;
|
||||
|
||||
if (is_inside_tree() && p_node->data.tree == data.tree) {
|
||||
const int depth = data.depth;
|
||||
while (n->data.depth > depth) {
|
||||
n = n->data.parent;
|
||||
}
|
||||
return n == this;
|
||||
}
|
||||
|
||||
n = p_node->data.parent;
|
||||
while (n) {
|
||||
if (n == this) {
|
||||
return true;
|
||||
}
|
||||
p = p->data.parent;
|
||||
n = n->data.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -2211,7 +2252,7 @@ void Node::_set_owner_nocheck(Node *p_owner) {
|
|||
|
||||
void Node::_release_unique_name_in_owner() {
|
||||
ERR_FAIL_NULL(data.owner); // Safety check.
|
||||
StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.operator String());
|
||||
StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.string());
|
||||
Node **which = data.owner->data.owned_unique_nodes.getptr(key);
|
||||
if (which == nullptr || *which != this) {
|
||||
return; // Ignore.
|
||||
|
|
@ -2221,7 +2262,7 @@ void Node::_release_unique_name_in_owner() {
|
|||
|
||||
void Node::_acquire_unique_name_in_owner() {
|
||||
ERR_FAIL_NULL(data.owner); // Safety check.
|
||||
StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.operator String());
|
||||
StringName key = StringName(UNIQUE_NODE_PREFIX + data.name.string());
|
||||
Node **which = data.owner->data.owned_unique_nodes.getptr(key);
|
||||
if (which != nullptr && *which != this) {
|
||||
String which_path = String(is_inside_tree() ? (*which)->get_path() : data.owner->get_path_to(*which));
|
||||
|
|
@ -2351,7 +2392,7 @@ NodePath Node::get_path_to(RequiredParam<const Node> rp_node, bool p_use_unique_
|
|||
common_parent = common_parent->data.parent;
|
||||
}
|
||||
|
||||
ERR_FAIL_NULL_V(common_parent, NodePath()); //nodes not in the same tree
|
||||
ERR_FAIL_NULL_V_MSG(common_parent, NodePath(), vformat("No path can be resolved between the nodes %s and %s as they share no common ancestor.", get_description(true), p_node->get_description(true)));
|
||||
|
||||
visited.clear();
|
||||
|
||||
|
|
@ -2562,37 +2603,6 @@ String Node::get_tree_string() {
|
|||
return _get_tree_string(this);
|
||||
}
|
||||
|
||||
void Node::_propagate_reverse_notification(int p_notification) {
|
||||
data.blocked++;
|
||||
|
||||
for (HashMap<StringName, Node *>::Iterator I = data.children.last(); I; --I) {
|
||||
I->value->_propagate_reverse_notification(p_notification);
|
||||
}
|
||||
|
||||
notification(p_notification, true);
|
||||
data.blocked--;
|
||||
}
|
||||
|
||||
void Node::_propagate_deferred_notification(int p_notification, bool p_reverse) {
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
data.blocked++;
|
||||
|
||||
if (!p_reverse) {
|
||||
MessageQueue::get_singleton()->push_notification(this, p_notification);
|
||||
}
|
||||
|
||||
for (KeyValue<StringName, Node *> &K : data.children) {
|
||||
K.value->_propagate_deferred_notification(p_notification, p_reverse);
|
||||
}
|
||||
|
||||
if (p_reverse) {
|
||||
MessageQueue::get_singleton()->push_notification(this, p_notification);
|
||||
}
|
||||
|
||||
data.blocked--;
|
||||
}
|
||||
|
||||
void Node::propagate_notification(int p_notification) {
|
||||
ERR_THREAD_GUARD
|
||||
data.blocked++;
|
||||
|
|
@ -2751,6 +2761,7 @@ StringName Node::get_property_store_alias(const StringName &p_property) const {
|
|||
|
||||
bool Node::is_part_of_edited_scene() const {
|
||||
return Engine::get_singleton()->is_editor_hint() && is_inside_tree() && data.tree->get_edited_scene_root() &&
|
||||
data.tree->get_edited_scene_root()->get_parent() && // Defend against edge cases when creating new scenes and they are not fully added to the tree yet.
|
||||
data.tree->get_edited_scene_root()->get_parent()->is_ancestor_of(this);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -3224,7 +3235,7 @@ void Node::replace_by(RequiredParam<Node> rp_node, bool p_keep_groups) {
|
|||
EXTRACT_PARAM_OR_FAIL(p_node, rp_node);
|
||||
ERR_FAIL_COND(p_node->data.parent);
|
||||
|
||||
List<Node *> owned = data.owned;
|
||||
List<Node *> owned(data.owned);
|
||||
List<Node *> owned_by_owner;
|
||||
Node *owner = (data.owner == this) ? p_node : data.owner;
|
||||
|
||||
|
|
@ -3258,16 +3269,14 @@ void Node::replace_by(RequiredParam<Node> rp_node, bool p_keep_groups) {
|
|||
|
||||
emit_signal(SNAME("replacing_by"), p_node);
|
||||
|
||||
while (get_child_count()) {
|
||||
Node *child = get_child(0);
|
||||
// Move non-internal children to `p_node`.
|
||||
while (get_child_count(false)) {
|
||||
Node *child = get_child(0, false);
|
||||
remove_child(child);
|
||||
if (!child->is_internal()) {
|
||||
// Add the custom children to the p_node.
|
||||
Node *child_owner = child->get_owner() == this ? p_node : child->get_owner();
|
||||
child->set_owner(nullptr);
|
||||
p_node->add_child(child);
|
||||
child->set_owner(child_owner);
|
||||
}
|
||||
Node *child_owner = child->get_owner() == this ? p_node : child->get_owner();
|
||||
child->set_owner(nullptr);
|
||||
p_node->add_child(child);
|
||||
child->set_owner(child_owner);
|
||||
}
|
||||
|
||||
p_node->set_owner(owner);
|
||||
|
|
@ -3512,9 +3521,9 @@ void Node::get_argument_options(const StringName &p_function, int p_idx, List<St
|
|||
if (p_idx == 0 && (pf == "has_node" || pf == "get_node" || pf == "get_node_or_null")) {
|
||||
_add_nodes_to_options(this, this, r_options);
|
||||
} else if (p_idx == 0 && (pf == "add_to_group" || pf == "remove_from_group" || pf == "is_in_group")) {
|
||||
HashMap<StringName, String> global_groups = ProjectSettings::get_singleton()->get_global_groups_list();
|
||||
HashMap<StringName, String> global_groups(ProjectSettings::get_singleton()->get_global_groups_list());
|
||||
for (const KeyValue<StringName, String> &E : global_groups) {
|
||||
r_options->push_back(E.key.operator String().quote());
|
||||
r_options->push_back(E.key.string().quote());
|
||||
}
|
||||
}
|
||||
Object::get_argument_options(p_function, p_idx, r_options);
|
||||
|
|
@ -3624,7 +3633,7 @@ void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) {
|
|||
|
||||
void Node::_validate_property(PropertyInfo &p_property) const {
|
||||
if ((p_property.name == "process_thread_group_order" || p_property.name == "process_thread_messages") && data.process_thread_group == PROCESS_THREAD_GROUP_INHERIT) {
|
||||
p_property.usage = 0;
|
||||
p_property.usage = PROPERTY_USAGE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3746,6 +3755,14 @@ RID Node::get_focused_accessibility_element() const {
|
|||
}
|
||||
}
|
||||
|
||||
Transform2D Node::get_accessibility_transform() const {
|
||||
if (is_inside_tree() && data.parent) {
|
||||
return data.parent->get_accessibility_transform();
|
||||
} else {
|
||||
return Transform2D();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::queue_accessibility_update() {
|
||||
if (is_inside_tree() && !is_part_of_edited_scene()) {
|
||||
data.tree->_accessibility_notify_change(this);
|
||||
|
|
@ -3758,8 +3775,8 @@ RID Node::get_accessibility_element() const {
|
|||
}
|
||||
if (unlikely(data.accessibility_element.is_null())) {
|
||||
Window *w = get_non_popup_window();
|
||||
if (w && w->get_window_id() != DisplayServer::INVALID_WINDOW_ID && get_window()->is_visible()) {
|
||||
data.accessibility_element = DisplayServer::get_singleton()->accessibility_create_element(w->get_window_id(), DisplayServer::ROLE_CONTAINER);
|
||||
if (w && w->get_window_id() != DisplayServerEnums::INVALID_WINDOW_ID && get_window()->is_visible()) {
|
||||
data.accessibility_element = AccessibilityServer::get_singleton()->create_element(w->get_window_id(), AccessibilityServerEnums::ROLE_CONTAINER);
|
||||
}
|
||||
}
|
||||
return data.accessibility_element;
|
||||
|
|
@ -3986,6 +4003,7 @@ void Node::_bind_methods() {
|
|||
BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
|
||||
BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
|
||||
BIND_CONSTANT(NOTIFICATION_WM_POSITION_CHANGED);
|
||||
BIND_CONSTANT(NOTIFICATION_WM_OUTPUT_MAX_LINEAR_VALUE_CHANGED);
|
||||
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
|
||||
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
|
||||
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
|
||||
|
|
@ -3996,6 +4014,8 @@ void Node::_bind_methods() {
|
|||
BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN);
|
||||
BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
|
||||
BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
|
||||
BIND_CONSTANT(NOTIFICATION_APPLICATION_PIP_MODE_ENTERED);
|
||||
BIND_CONSTANT(NOTIFICATION_APPLICATION_PIP_MODE_EXITED);
|
||||
|
||||
BIND_CONSTANT(NOTIFICATION_ACCESSIBILITY_UPDATE);
|
||||
BIND_CONSTANT(NOTIFICATION_ACCESSIBILITY_INVALIDATE);
|
||||
|
|
@ -4049,8 +4069,8 @@ void Node::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name");
|
||||
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");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_owner", "get_owner");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "", "get_multiplayer");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, Node::get_class_static(), PROPERTY_USAGE_NONE), "set_owner", "get_owner");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, MultiplayerAPI::get_class_static(), PROPERTY_USAGE_NONE), "", "get_multiplayer");
|
||||
|
||||
ADD_GROUP("Process", "process_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue