diff options
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r-- | scene/main/node.cpp | 439 |
1 files changed, 203 insertions, 236 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1b6f73efe1..27712242d1 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -46,7 +46,7 @@ #include <stdint.h> -VARIANT_ENUM_CAST(Node::PauseMode); +VARIANT_ENUM_CAST(Node::ProcessMode); int Node::orphan_node_count = 0; @@ -69,14 +69,14 @@ void Node::_notification(int p_notification) { ERR_FAIL_COND(!get_viewport()); ERR_FAIL_COND(!get_tree()); - if (data.pause_mode == PAUSE_MODE_INHERIT) { + if (data.process_mode == PROCESS_MODE_INHERIT) { if (data.parent) { - data.pause_owner = data.parent->data.pause_owner; + data.process_owner = data.parent->data.process_owner; } else { - data.pause_owner = nullptr; + data.process_owner = nullptr; } } else { - data.pause_owner = this; + data.process_owner = this; } if (data.input) { @@ -110,7 +110,7 @@ void Node::_notification(int p_notification) { remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id())); } - data.pause_owner = nullptr; + data.process_owner = nullptr; if (data.path_cache) { memdelete(data.path_cache); data.path_cache = nullptr; @@ -367,8 +367,6 @@ void Node::set_physics_process(bool p_process) { } else { remove_from_group("physics_process"); } - - _change_notify("physics_process"); } bool Node::is_physics_processing() const { @@ -387,52 +385,87 @@ void Node::set_physics_process_internal(bool p_process_internal) { } else { remove_from_group("physics_process_internal"); } - - _change_notify("physics_process_internal"); } bool Node::is_physics_processing_internal() const { return data.physics_process_internal; } -void Node::set_pause_mode(PauseMode p_mode) { - if (data.pause_mode == p_mode) { +void Node::set_process_mode(ProcessMode p_mode) { + if (data.process_mode == p_mode) { return; } - bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT; - data.pause_mode = p_mode; if (!is_inside_tree()) { - return; //pointless - } - if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) { - return; ///nothing changed + data.process_mode = p_mode; + return; } - Node *owner = nullptr; + bool prev_can_process = can_process(); + + data.process_mode = p_mode; - if (data.pause_mode == PAUSE_MODE_INHERIT) { + if (data.process_mode == PROCESS_MODE_INHERIT) { if (data.parent) { - owner = data.parent->data.pause_owner; + data.process_owner = data.parent->data.owner; + } else { + data.process_owner = nullptr; } } else { - owner = this; + data.process_owner = this; + } + + bool next_can_process = can_process(); + + int pause_notification = 0; + + if (prev_can_process && !next_can_process) { + pause_notification = NOTIFICATION_PAUSED; + } else if (!prev_can_process && next_can_process) { + pause_notification = NOTIFICATION_UNPAUSED; } - _propagate_pause_owner(owner); + _propagate_process_owner(data.process_owner, pause_notification); +#ifdef TOOLS_ENABLED + // This is required for the editor to update the visibility of disabled nodes + // It's very expensive during runtime to change, so editor-only + if (Engine::get_singleton()->is_editor_hint()) { + get_tree()->emit_signal("tree_process_mode_changed"); + } +#endif } -Node::PauseMode Node::get_pause_mode() const { - return data.pause_mode; +void Node::_propagate_pause_notification(bool p_enable) { + bool prev_can_process = _can_process(!p_enable); + bool next_can_process = _can_process(p_enable); + + if (prev_can_process && !next_can_process) { + notification(NOTIFICATION_PAUSED); + } else if (!prev_can_process && next_can_process) { + notification(NOTIFICATION_UNPAUSED); + } + + for (int i = 0; i < data.children.size(); i++) { + data.children[i]->_propagate_pause_notification(p_enable); + } } -void Node::_propagate_pause_owner(Node *p_owner) { - if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) { - return; +Node::ProcessMode Node::get_process_mode() const { + return data.process_mode; +} + +void Node::_propagate_process_owner(Node *p_owner, int p_notification) { + data.process_owner = p_owner; + + if (p_notification != 0) { + notification(p_notification); } - data.pause_owner = p_owner; + for (int i = 0; i < data.children.size(); i++) { - data.children[i]->_propagate_pause_owner(p_owner); + Node *c = data.children[i]; + if (c->data.process_mode == PROCESS_MODE_INHERIT) { + c->_propagate_process_owner(p_owner, p_notification); + } } } @@ -466,7 +499,7 @@ uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_ nd.name = p_method; nd.mode = p_mode; data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); + return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); } else { int c_mid = (~(1 << 15)) & mid; data.rpc_methods.write[c_mid].mode = p_mode; @@ -555,7 +588,7 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -584,7 +617,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -607,7 +640,7 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Calla return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -636,7 +669,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Ca return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -809,30 +842,33 @@ 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()); +} - if (get_tree()->is_paused()) { - if (data.pause_mode == PAUSE_MODE_STOP) { - return false; - } - if (data.pause_mode == PAUSE_MODE_PROCESS) { - return true; - } - if (data.pause_mode == PAUSE_MODE_INHERIT) { - if (!data.pause_owner) { - return false; //clearly no pause owner by default - } - - if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) { - return true; - } +bool Node::_can_process(bool p_paused) const { + ProcessMode process_mode; - if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) { - return false; - } + if (data.process_mode == PROCESS_MODE_INHERIT) { + if (!data.process_owner) { + process_mode = PROCESS_MODE_PAUSABLE; + } else { + process_mode = data.process_owner->data.process_mode; } + } else { + process_mode = data.process_mode; } - return true; + if (process_mode == PROCESS_MODE_DISABLED) { + return false; + } else if (process_mode == PROCESS_MODE_ALWAYS) { + return true; + } + + if (p_paused) { + return process_mode == PROCESS_MODE_WHEN_PAUSED; + } else { + return process_mode == PROCESS_MODE_PAUSABLE; + } } float Node::get_physics_process_delta_time() const { @@ -863,8 +899,6 @@ void Node::set_process(bool p_process) { } else { remove_from_group("process"); } - - _change_notify("process"); } bool Node::is_processing() const { @@ -883,8 +917,6 @@ void Node::set_process_internal(bool p_process_internal) { } else { remove_from_group("process_internal"); } - - _change_notify("process_internal"); } bool Node::is_processing_internal() const { @@ -989,22 +1021,8 @@ void Node::_set_name_nocheck(const StringName &p_name) { data.name = p_name; } -String Node::invalid_character = ". : @ / \""; - -bool Node::_validate_node_name(String &p_name) { - String name = p_name; - Vector<String> chars = Node::invalid_character.split(" "); - for (int i = 0; i < chars.size(); i++) { - name = name.replace(chars[i], ""); - } - bool is_valid = name == p_name; - p_name = name; - return is_valid; -} - void Node::set_name(const String &p_name) { - String name = p_name; - _validate_node_name(name); + String name = p_name.validate_node_name(); ERR_FAIL_COND(name == ""); data.name = name; @@ -1112,11 +1130,11 @@ String increase_numeric_string(const String &s) { void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const { if (name == StringName()) { - //no name and a new nade is needed, create one. + //no name and a new name is needed, create one. name = p_child->get_class(); // Adjust casing according to project setting. The current type name is expected to be in PascalCase. - switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) { + switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) { case NAME_CASING_PASCAL_CASE: break; case NAME_CASING_CAMEL_CASE: { @@ -1138,7 +1156,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co bool exists = false; for (int i = 0; i < cc; i++) { - if (children_ptr[i] == p_child) { //exclude self in renaming if its already a child + if (children_ptr[i] == p_child) { //exclude self in renaming if it's already a child continue; } if (children_ptr[i]->data.name == name) { @@ -1410,7 +1428,15 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { Node *Node::get_node(const NodePath &p_path) const { Node *node = get_node_or_null(p_path); - ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + "."); + + if (p_path.is_absolute()) { + ERR_FAIL_COND_V_MSG(!node, nullptr, + vformat(R"(Node not found: "%s" (absolute path attempted from "%s").)", p_path, get_path())); + } else { + ERR_FAIL_COND_V_MSG(!node, nullptr, + vformat(R"(Node not found: "%s" (relative to "%s").)", p_path, get_path())); + } + return node; } @@ -1664,7 +1690,7 @@ NodePath Node::get_path_to(const Node *p_node) const { n = n->data.parent; } - path.invert(); + path.reverse(); return NodePath(path, false); } @@ -1685,7 +1711,7 @@ NodePath Node::get_path() const { n = n->data.parent; } - path.invert(); + path.reverse(); data.path_cache = memnew(NodePath(path, true)); @@ -1906,46 +1932,50 @@ String Node::get_filename() const { } void Node::set_editor_description(const String &p_editor_description) { - set_meta("_editor_description_", p_editor_description); + data.editor_description = p_editor_description; } String Node::get_editor_description() const { - if (has_meta("_editor_description_")) { - return get_meta("_editor_description_"); - } else { - return ""; - } + return data.editor_description; } void Node::set_editable_instance(Node *p_node, bool p_editable) { ERR_FAIL_NULL(p_node); ERR_FAIL_COND(!is_a_parent_of(p_node)); - NodePath p = get_path_to(p_node); if (!p_editable) { - data.editable_instances.erase(p); + p_node->data.editable_instance = false; // Avoid this flag being needlessly saved; - // also give more visual feedback if editable children is re-enabled + // also give more visual feedback if editable children are re-enabled set_display_folded(false); } else { - data.editable_instances[p] = true; + p_node->data.editable_instance = true; } } bool Node::is_editable_instance(const Node *p_node) const { if (!p_node) { - return false; //easier, null is never editable :) + return false; // Easier, null is never editable. :) } ERR_FAIL_COND_V(!is_a_parent_of(p_node), false); - NodePath p = get_path_to(p_node); - return data.editable_instances.has(p); + return p_node->data.editable_instance; } -void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) { - data.editable_instances = p_editable_instances; -} +Node *Node::get_deepest_editable_node(Node *p_start_node) const { + ERR_FAIL_NULL_V(p_start_node, nullptr); + ERR_FAIL_COND_V(!is_a_parent_of(p_start_node), p_start_node); + + Node const *iterated_item = p_start_node; + Node *node = p_start_node; -HashMap<NodePath, int> Node::get_editable_instances() const { - return data.editable_instances; + while (iterated_item->get_owner() && iterated_item->get_owner() != this) { + if (!is_editable_instance(iterated_item->get_owner())) { + node = iterated_item->get_owner(); + } + + iterated_item = iterated_item->get_owner(); + } + + return node; } void Node::set_scene_instance_state(const Ref<SceneState> &p_state) { @@ -2009,6 +2039,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const if (get_filename() != "") { //an instance node->set_filename(get_filename()); + node->data.editable_instance = data.editable_instance; } StringName script_property_name = CoreStringNames::get_singleton()->_script; @@ -2021,19 +2052,26 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const // Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory // of all the nodes in the tree of the instanced scene in order to transfer the values of the properties + Vector<const Node *> instance_roots; + instance_roots.push_back(this); + for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { for (int i = 0; i < N->get()->get_child_count(); ++i) { Node *descendant = N->get()->get_child(i); // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later // but remember non-instanced nodes that are hidden below instanced ones - if (descendant->data.owner != this) { - if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) { + if (!instance_roots.has(descendant->get_owner())) { + if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) { hidden_roots.push_back(descendant); } continue; } node_tree.push_back(descendant); + + if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) { + instance_roots.push_back(descendant); + } } } } @@ -2156,8 +2194,17 @@ Node *Node::duplicate(int p_flags) const { #ifdef TOOLS_ENABLED Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { + return duplicate_from_editor(r_duplimap, Map<RES, RES>()); +} + +Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const { Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); + // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. + if (!p_resource_remap.is_empty()) { + remap_node_resources(dupe, p_resource_remap); + } + // Duplication of signals must happen after all the node descendants have been copied, // because re-targeting of connections from some descendant to another is not possible // if the emitter node comes later in tree order than the receiver @@ -2165,75 +2212,55 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { return dupe; } -#endif - -void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const { - if (get_owner() != get_parent()->get_owner()) { - return; - } - - Node *node = nullptr; - - if (get_filename() != "") { - Ref<PackedScene> res = ResourceLoader::load(get_filename()); - ERR_FAIL_COND_MSG(res.is_null(), "Cannot load scene: " + get_filename()); - node = res->instance(); - ERR_FAIL_COND(!node); - } else { - Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + "."); - node = Object::cast_to<Node>(obj); - if (!node) { - memdelete(obj); - ERR_FAIL_MSG("Node: Could not duplicate: " + String(get_class()) + "."); - } - } - List<PropertyInfo> plist; +void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_node->get_property_list(&props); - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E->get().name; - - Variant value = get(name).duplicate(true); - node->set(name, value); + Variant v = p_node->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_node->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } + } + } } - List<GroupInfo> groups; - get_groups(&groups); - - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - node->add_to_group(E->get().name, E->get().persistent); + for (int i = 0; i < p_node->get_child_count(); i++) { + remap_node_resources(p_node->get_child(i), p_resource_remap); } +} - node->set_name(get_name()); - p_new_parent->add_child(node); - - Node *owner = get_owner(); +void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const { + List<PropertyInfo> props; + p_resource->get_property_list(&props); - if (p_reown_map.has(owner)) { - owner = p_reown_map[owner]; - } + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + continue; + } - if (owner) { - NodePath p = get_path_to(owner); - if (owner != this) { - Node *new_owner = node->get_node(p); - if (new_owner) { - node->set_owner(new_owner); + Variant v = p_resource->get(E->get().name); + if (v.is_ref()) { + RES res = v; + if (res.is_valid()) { + if (p_resource_remap.has(res)) { + p_resource->set(E->get().name, p_resource_remap[res]); + remap_nested_resources(res, p_resource_remap); + } } } } - - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); - } } +#endif // Duplication of signals must happen after all the node descendants have been copied, // because re-targeting of connections from some descendant to another is not possible @@ -2289,49 +2316,6 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { } } -Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { - ERR_FAIL_COND_V(get_filename() != "", nullptr); - - Object *obj = ClassDB::instance(get_class()); - ERR_FAIL_COND_V_MSG(!obj, nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); - - Node *node = Object::cast_to<Node>(obj); - if (!node) { - memdelete(obj); - ERR_FAIL_V_MSG(nullptr, "Node: Could not duplicate: " + String(get_class()) + "."); - } - node->set_name(get_name()); - - List<PropertyInfo> plist; - - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - String name = E->get().name; - node->set(name, get(name)); - } - - List<GroupInfo> groups; - get_groups(&groups); - - for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) { - node->add_to_group(E->get().name, E->get().persistent); - } - - for (int i = 0; i < get_child_count(); i++) { - get_child(i)->_duplicate_and_reown(node, p_reown_map); - } - - // Duplication of signals must happen after all the node descendants have been copied, - // because re-targeting of connections from some descendant to another is not possible - // if the emitter node comes later in tree order than the receiver - _duplicate_signals(this, node); - return node; -} - static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { if (p_node->get_owner() == p_by) { p_owned->push_back(p_node); @@ -2342,12 +2326,7 @@ static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { } } -struct _NodeReplaceByPair { - String name; - Variant value; -}; - -void Node::replace_by(Node *p_node, bool p_keep_data) { +void Node::replace_by(Node *p_node, bool p_keep_groups) { ERR_FAIL_NULL(p_node); ERR_FAIL_COND(p_node->data.parent); @@ -2355,21 +2334,7 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { List<Node *> owned_by_owner; Node *owner = (data.owner == this) ? p_node : data.owner; - List<_NodeReplaceByPair> replace_data; - - if (p_keep_data) { - List<PropertyInfo> plist; - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - _NodeReplaceByPair rd; - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - rd.name = E->get().name; - rd.value = get(rd.name); - } - + if (p_keep_groups) { List<GroupInfo> groups; get_groups(&groups); @@ -2414,10 +2379,6 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { } p_node->set_filename(get_filename()); - - for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) { - p_node->set(E->get().name, E->get().value); - } } void Node::_replace_connections_target(Node *p_new_target) { @@ -2709,10 +2670,10 @@ void Node::request_ready() { } void Node::_bind_methods() { - GLOBAL_DEF("node/name_num_separator", 0); - ProjectSettings::get_singleton()->set_custom_property_info("node/name_num_separator", PropertyInfo(Variant::INT, "node/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); - GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE); - ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); + GLOBAL_DEF("editor/node_naming/name_num_separator", 0); + ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_num_separator", PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); + GLOBAL_DEF("editor/node_naming/name_casing", NAME_CASING_PASCAL_CASE); + ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_casing", PropertyInfo(Variant::INT, "editor/node_naming/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false)); @@ -2767,8 +2728,8 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input); ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input); ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input); - ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Node::set_pause_mode); - ClassDB::bind_method(D_METHOD("get_pause_mode"), &Node::get_pause_mode); + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode); ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process); ClassDB::bind_method(D_METHOD("print_stray_nodes"), &Node::_print_stray_nodes); @@ -2784,7 +2745,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree); ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS)); - ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_data"), &Node::replace_by, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder); ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder); @@ -2806,12 +2767,12 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config); ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_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); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_editor_description", "_get_editor_description"); + 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); ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path); ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path"); { @@ -2875,9 +2836,11 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT); BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED); - BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); - BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); - BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS); + BIND_ENUM_CONSTANT(PROCESS_MODE_INHERIT); + BIND_ENUM_CONSTANT(PROCESS_MODE_PAUSABLE); + BIND_ENUM_CONSTANT(PROCESS_MODE_WHEN_PAUSED); + BIND_ENUM_CONSTANT(PROCESS_MODE_ALWAYS); + BIND_ENUM_CONSTANT(PROCESS_MODE_DISABLED); BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS); BIND_ENUM_CONSTANT(DUPLICATE_GROUPS); @@ -2890,15 +2853,19 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_exiting")); ADD_SIGNAL(MethodInfo("tree_exited")); - ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); + + ADD_GROUP("Process", "process_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); + ADD_GROUP("Editor Description", "editor_"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description"); + BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_enter_tree")); @@ -2911,7 +2878,7 @@ void Node::_bind_methods() { } String Node::_get_name_num_separator() { - switch (ProjectSettings::get_singleton()->get("node/name_num_separator").operator int()) { + switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_num_separator").operator int()) { case 0: return ""; case 1: |