feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -111,6 +111,7 @@ void Node::_notification(int p_notification) {
data.auto_translate_mode = AUTO_TRANSLATE_MODE_ALWAYS;
}
data.is_auto_translate_dirty = true;
data.is_translation_domain_dirty = true;
#ifdef TOOLS_ENABLED
// Don't translate UI elements when they're being edited.
@ -119,10 +120,6 @@ void Node::_notification(int p_notification) {
}
#endif
if (data.auto_translate_mode != AUTO_TRANSLATE_MODE_DISABLED) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
if (data.input) {
add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
}
@ -138,6 +135,18 @@ void Node::_notification(int p_notification) {
get_tree()->nodes_in_tree_count++;
orphan_node_count--;
// Allow physics interpolated nodes to automatically reset when added to the tree
// (this is to save the user from doing this manually each time).
if (get_tree()->is_physics_interpolation_enabled()) {
_set_physics_interpolation_reset_requested(true);
}
} break;
case NOTIFICATION_POST_ENTER_TREE: {
if (data.auto_translate_mode != AUTO_TRANSLATE_MODE_DISABLED) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
} break;
case NOTIFICATION_EXIT_TREE: {
@ -177,6 +186,7 @@ void Node::_notification(int p_notification) {
}
} break;
case NOTIFICATION_SUSPENDED:
case NOTIFICATION_PAUSED: {
if (is_physics_interpolated_and_enabled() && is_inside_tree()) {
reset_physics_interpolation();
@ -437,6 +447,18 @@ void Node::_propagate_physics_interpolated(bool p_interpolated) {
data.blocked--;
}
void Node::_propagate_physics_interpolation_reset_requested(bool p_requested) {
if (is_physics_interpolated()) {
data.physics_interpolation_reset_requested = p_requested;
}
data.blocked++;
for (KeyValue<StringName, Node *> &K : data.children) {
K.value->_propagate_physics_interpolation_reset_requested(p_requested);
}
data.blocked--;
}
void Node::move_child(Node *p_child, int p_index) {
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).");
ERR_FAIL_NULL(p_child);
@ -656,6 +678,8 @@ void Node::set_process_mode(ProcessMode p_mode) {
if (Engine::get_singleton()->is_editor_hint()) {
get_tree()->emit_signal(SNAME("tree_process_mode_changed"));
}
_emit_editor_state_changed();
#endif
}
@ -676,6 +700,16 @@ void Node::_propagate_pause_notification(bool p_enable) {
data.blocked--;
}
void Node::_propagate_suspend_notification(bool p_enable) {
notification(p_enable ? NOTIFICATION_SUSPENDED : NOTIFICATION_UNSUSPENDED);
data.blocked++;
for (KeyValue<StringName, Node *> &KV : data.children) {
KV.value->_propagate_suspend_notification(p_enable);
}
data.blocked--;
}
Node::ProcessMode Node::get_process_mode() const {
return data.process_mode;
}
@ -739,7 +773,7 @@ void Node::rpc_config(const StringName &p_method, const Variant &p_config) {
}
}
const Variant Node::get_node_rpc_config() const {
Variant Node::get_rpc_config() const {
return data.rpc_config;
}
@ -752,8 +786,7 @@ Error Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallErro
return ERR_INVALID_PARAMETER;
}
Variant::Type type = p_args[0]->get_type();
if (type != Variant::STRING_NAME && type != Variant::STRING) {
if (!p_args[0]->is_string()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING_NAME;
@ -781,8 +814,7 @@ Error Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallE
return ERR_INVALID_PARAMETER;
}
Variant::Type type = p_args[1]->get_type();
if (type != Variant::STRING_NAME && type != Variant::STRING) {
if (!p_args[1]->is_string()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
@ -833,7 +865,7 @@ bool Node::can_process_notification(int p_what) const {
bool Node::can_process() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
return _can_process(get_tree()->is_paused());
return !get_tree()->is_suspended() && _can_process(get_tree()->is_paused());
}
bool Node::_can_process(bool p_paused) const {
@ -889,16 +921,24 @@ void Node::set_physics_interpolation_mode(PhysicsInterpolationMode p_mode) {
} break;
}
// If swapping from interpolated to non-interpolated, use this as an extra means to cause a reset.
if (is_physics_interpolated() && !interpolate) {
reset_physics_interpolation();
}
_propagate_physics_interpolated(interpolate);
// Auto-reset on changing interpolation mode.
if (is_physics_interpolated() && is_inside_tree()) {
propagate_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
}
}
void Node::reset_physics_interpolation() {
propagate_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
if (is_inside_tree()) {
propagate_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
// If `reset_physics_interpolation()` is called explicitly by the user
// (e.g. from scripts) then we prevent deferred auto-resets taking place.
// The user is trusted to call reset in the right order, and auto-reset
// will interfere with their control of prev / curr, so should be turned off.
_propagate_physics_interpolation_reset_requested(false);
}
}
bool Node::_is_enabled() const {
@ -1296,6 +1336,51 @@ bool Node::can_auto_translate() const {
return data.is_auto_translating;
}
StringName Node::get_translation_domain() const {
ERR_READ_THREAD_GUARD_V(StringName());
if (data.is_translation_domain_inherited && data.is_translation_domain_dirty) {
const_cast<Node *>(this)->_translation_domain = data.parent ? data.parent->get_translation_domain() : StringName();
data.is_translation_domain_dirty = false;
}
return _translation_domain;
}
void Node::set_translation_domain(const StringName &p_domain) {
ERR_THREAD_GUARD
if (!data.is_translation_domain_inherited && _translation_domain == p_domain) {
return;
}
_translation_domain = p_domain;
data.is_translation_domain_inherited = false;
data.is_translation_domain_dirty = false;
_propagate_translation_domain_dirty();
}
void Node::set_translation_domain_inherited() {
ERR_THREAD_GUARD
if (data.is_translation_domain_inherited) {
return;
}
data.is_translation_domain_inherited = true;
data.is_translation_domain_dirty = true;
_propagate_translation_domain_dirty();
}
void Node::_propagate_translation_domain_dirty() {
for (KeyValue<StringName, Node *> &K : data.children) {
Node *child = K.value;
if (child->data.is_translation_domain_inherited) {
child->data.is_translation_domain_dirty = true;
child->_propagate_translation_domain_dirty();
}
}
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
StringName Node::get_name() const {
return data.name;
}
@ -2080,6 +2165,7 @@ void Node::set_unique_name_in_owner(bool p_enabled) {
}
update_configuration_warnings();
_emit_editor_state_changed();
}
bool Node::is_unique_name_in_owner() const {
@ -2117,6 +2203,8 @@ void Node::set_owner(Node *p_owner) {
if (data.unique_name_in_owner) {
_acquire_unique_name_in_owner();
}
_emit_editor_state_changed();
}
Node *Node::get_owner() const {
@ -2300,6 +2388,9 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
gd.persistent = p_persistent;
data.grouped[p_identifier] = gd;
if (p_persistent) {
_emit_editor_state_changed();
}
}
void Node::remove_from_group(const StringName &p_identifier) {
@ -2310,11 +2401,21 @@ void Node::remove_from_group(const StringName &p_identifier) {
return;
}
#ifdef TOOLS_ENABLED
bool persistent = E->value.persistent;
#endif
if (data.tree) {
data.tree->remove_from_group(E->key, this);
}
data.grouped.remove(E);
#ifdef TOOLS_ENABLED
if (persistent) {
_emit_editor_state_changed();
}
#endif
}
TypedArray<StringName> Node::_get_groups() const {
@ -2477,6 +2578,7 @@ Ref<Tween> Node::create_tween() {
void Node::set_scene_file_path(const String &p_scene_file_path) {
ERR_THREAD_GUARD
data.scene_file_path = p_scene_file_path;
_emit_editor_state_changed();
}
String Node::get_scene_file_path() const {
@ -2509,6 +2611,8 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) {
} else {
p_node->data.editable_instance = true;
}
p_node->_emit_editor_state_changed();
}
bool Node::is_editable_instance(const Node *p_node) const {
@ -2619,6 +2723,7 @@ Ref<SceneState> Node::get_scene_instance_state() const {
void Node::set_scene_inherited_state(const Ref<SceneState> &p_state) {
ERR_THREAD_GUARD
data.inherited_state = p_state;
_emit_editor_state_changed();
}
Ref<SceneState> Node::get_scene_inherited_state() const {
@ -2783,9 +2888,11 @@ Node *Node::duplicate(int p_flags) const {
ERR_THREAD_GUARD_V(nullptr);
Node *dupe = _duplicate(p_flags);
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
_duplicate_properties(this, this, dupe, p_flags);
if (dupe && (p_flags & DUPLICATE_SIGNALS)) {
if (p_flags & DUPLICATE_SIGNALS) {
_duplicate_signals(this, dupe);
}
@ -2801,6 +2908,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con
int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR;
Node *dupe = _duplicate(flags, &r_duplimap);
ERR_FAIL_NULL_V_MSG(dupe, nullptr, "Failed to duplicate node.");
_duplicate_properties(this, this, dupe, flags);
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
@ -2863,6 +2972,14 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re
}
}
}
void Node::_emit_editor_state_changed() {
// This is required for the SceneTreeEditor to properly keep track of when an update is needed.
// This signal might be expensive and not needed for anything outside of the editor.
if (Engine::get_singleton()->is_editor_hint()) {
emit_signal(SNAME("editor_state_changed"));
}
}
#endif
// Duplicate node's properties.
@ -2970,11 +3087,12 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
if (copy && copytarget && E.callable.get_method() != StringName()) {
Callable copy_callable = Callable(copytarget, E.callable.get_method());
if (!copy->is_connected(E.signal.get_name(), copy_callable)) {
int arg_count = E.callable.get_bound_arguments_count();
if (arg_count > 0) {
int unbound_arg_count = E.callable.get_unbound_arguments_count();
if (unbound_arg_count > 0) {
copy_callable = copy_callable.unbind(unbound_arg_count);
}
if (E.callable.get_bound_arguments_count() > 0) {
copy_callable = copy_callable.bindv(E.callable.get_bound_arguments());
} else if (arg_count < 0) {
copy_callable = copy_callable.unbind(-arg_count);
}
copy->connect(E.signal.get_name(), copy_callable, E.flags);
}
@ -3406,7 +3524,7 @@ Variant Node::_call_deferred_thread_group_bind(const Variant **p_args, int p_arg
return Variant();
}
if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
if (!p_args[0]->is_string()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING_NAME;
@ -3429,7 +3547,7 @@ Variant Node::_call_thread_safe_bind(const Variant **p_args, int p_argcount, Cal
return Variant();
}
if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
if (!p_args[0]->is_string()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING_NAME;
@ -3582,6 +3700,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
ClassDB::bind_method(D_METHOD("set_translation_domain_inherited"), &Node::set_translation_domain_inherited);
ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
@ -3610,6 +3729,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
ClassDB::bind_method(D_METHOD("rpc_config", "method", "config"), &Node::rpc_config);
ClassDB::bind_method(D_METHOD("get_rpc_config"), &Node::get_rpc_config);
ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
@ -3753,6 +3873,7 @@ void Node::_bind_methods() {
ADD_SIGNAL(MethodInfo("child_order_changed"));
ADD_SIGNAL(MethodInfo("replacing_by", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
ADD_SIGNAL(MethodInfo("editor_description_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT, "Node")));
ADD_SIGNAL(MethodInfo("editor_state_changed"));
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");
@ -3825,6 +3946,9 @@ Node::Node() {
data.unhandled_key_input = false;
data.physics_interpolated = true;
data.physics_interpolation_reset_requested = false;
data.physics_interpolated_client_side = false;
data.use_identity_transform = false;
data.parent_owned = false;
data.in_constructor = true;
@ -3873,11 +3997,13 @@ bool Node::has_meta(const StringName &p_name) const {
void Node::set_meta(const StringName &p_name, const Variant &p_value) {
ERR_THREAD_GUARD;
Object::set_meta(p_name, p_value);
_emit_editor_state_changed();
}
void Node::remove_meta(const StringName &p_name) {
ERR_THREAD_GUARD;
Object::remove_meta(p_name);
_emit_editor_state_changed();
}
Variant Node::get_meta(const StringName &p_name, const Variant &p_default) const {
@ -3927,12 +4053,33 @@ void Node::get_signals_connected_to_this(List<Connection> *p_connections) const
Error Node::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) {
ERR_THREAD_GUARD_V(ERR_INVALID_PARAMETER);
return Object::connect(p_signal, p_callable, p_flags);
Error retval = Object::connect(p_signal, p_callable, p_flags);
#ifdef TOOLS_ENABLED
if (p_flags & CONNECT_PERSIST) {
_emit_editor_state_changed();
}
#endif
return retval;
}
void Node::disconnect(const StringName &p_signal, const Callable &p_callable) {
ERR_THREAD_GUARD;
#ifdef TOOLS_ENABLED
// Already under thread guard, don't check again.
int old_connection_count = Object::get_persistent_signal_connection_count();
#endif
Object::disconnect(p_signal, p_callable);
#ifdef TOOLS_ENABLED
int new_connection_count = Object::get_persistent_signal_connection_count();
if (old_connection_count != new_connection_count) {
_emit_editor_state_changed();
}
#endif
}
bool Node::is_connected(const StringName &p_signal, const Callable &p_callable) const {
@ -3940,4 +4087,9 @@ bool Node::is_connected(const StringName &p_signal, const Callable &p_callable)
return Object::is_connected(p_signal, p_callable);
}
bool Node::has_connections(const StringName &p_signal) const {
ERR_THREAD_GUARD_V(false);
return Object::has_connections(p_signal);
}
#endif