Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a get_partial_path method to NodePath #78638

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions core/string/node_path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,21 @@ NodePath NodePath::get_as_property_path() const {
}
}

NodePath NodePath::get_partial_path(int p_name_count) const {
ERR_FAIL_COND_V(!data, NodePath());
int size = data->path.size();
if (p_name_count > size) {
WARN_PRINT("NodePath: The partial path was requested to have more names than are available. Returning the full path.");
return NodePath(*this);
}
Vector<StringName> new_path;
new_path.resize(p_name_count);
for (int i = 0; i < p_name_count; i++) {
new_path.set(i, data->path[i]);
}
return NodePath(new_path, data->absolute);
}

bool NodePath::is_empty() const {
return !data;
}
Expand Down Expand Up @@ -331,7 +346,7 @@ NodePath NodePath::simplified() const {
}

NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
if (p_path.size() == 0) {
if (p_path.size() == 0 && !p_absolute) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this change and the similar one below? Do I need to include a similar change when making the slice method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem was an edge case where p_absolute was being ignored if the path was empty.

return;
}

Expand All @@ -343,7 +358,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
}

NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
if (p_path.size() == 0 && p_subpath.size() == 0) {
if (p_path.size() == 0 && p_subpath.size() == 0 && !p_absolute) {
return;
}

Expand Down
1 change: 1 addition & 0 deletions core/string/node_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class NodePath {

NodePath rel_path_to(const NodePath &p_np) const;
NodePath get_as_property_path() const;
NodePath get_partial_path(int p_name_count) const;

void prepend_period();

Expand Down
1 change: 1 addition & 0 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2022,6 +2022,7 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_concatenated_names, sarray(), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
bind_method(NodePath, get_as_property_path, sarray(), varray());
bind_method(NodePath, get_partial_path, sarray("name_count"), varray());
bind_method(NodePath, is_empty, sarray(), varray());

/* Callable */
Expand Down
7 changes: 7 additions & 0 deletions doc/classes/NodePath.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@
For example, [code]"Path2D/PathFollow2D/Sprite2D"[/code] has 3 names.
</description>
</method>
<method name="get_partial_path" qualifiers="const">
<return type="NodePath" />
<param index="0" name="name_count" type="int" />
<description>
Gets a partial path out of this [NodePath]. The [code]name_count[/code] parameter must be non-negative and less than or equal to the NodePath's name count (see [method get_name_count]). The returned value has the same name count as the parameter, except when the name count parameter is invalid (negative or greater than the available names). This discards any subnames if present (for example, property names on a node).
</description>
</method>
<method name="get_subname" qualifiers="const">
<return type="StringName" />
<param index="0" name="idx" type="int" />
Expand Down
31 changes: 31 additions & 0 deletions tests/core/string/test_node_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,37 @@ TEST_CASE("[NodePath] Empty path") {
node_path_empty.is_empty(),
"The node path should be considered empty.");
}

TEST_CASE("[NodePath] Get Partial Path") {
const NodePath node_path_absolute = NodePath("/root/A");
const NodePath node_path_relative = NodePath("A/B");

CHECK_MESSAGE(
node_path_absolute.get_partial_path(0) == NodePath("/"),
"The returned partial path with a name count of 0 should match the expected value.");
CHECK_MESSAGE(
node_path_absolute.get_partial_path(1) == NodePath("/root"),
"The returned partial path with a name count of 1 should match the expected value.");
CHECK_MESSAGE(
node_path_absolute.get_partial_path(2) == NodePath("/root/A"),
"The returned partial path with a name count of 2 should match the expected value.");
CHECK_MESSAGE(
node_path_absolute.get_partial_path(3) == NodePath("/root/A"),
"The returned partial path with an invalid name count of 3 should match the expected value.");

CHECK_MESSAGE(
node_path_relative.get_partial_path(0) == NodePath(""),
"The returned partial path with a name count of 0 should match the expected value.");
CHECK_MESSAGE(
node_path_relative.get_partial_path(1) == NodePath("A"),
"The returned partial path with a name count of 1 should match the expected value.");
CHECK_MESSAGE(
node_path_relative.get_partial_path(2) == NodePath("A/B"),
"The returned partial path with a name count of 2 should match the expected value.");
CHECK_MESSAGE(
node_path_relative.get_partial_path(3) == NodePath("A/B"),
"The returned partial path with an invalid name count of 3 should match the expected value.");
}
} // namespace TestNodePath

#endif // TEST_NODE_PATH_H