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

Make Node an iterator for its children #10902

Open
snoopdouglas opened this issue Oct 4, 2024 · 1 comment
Open

Make Node an iterator for its children #10902

snoopdouglas opened this issue Oct 4, 2024 · 1 comment

Comments

@snoopdouglas
Copy link

snoopdouglas commented Oct 4, 2024

Describe the project you are working on

A collection of games (n/a here, this applies to anything using GDScript).

Describe the problem or limitation you are having in your project

I'm going to preface this with the fact that I'm not sure whether this is a good idea - but would like to get people's thoughts.

It's just occurred to me that I often find myself automatically typing this:

for child in node:
    # ...

...when I actually mean this:

for child in node.get_children():
    # ...

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I'm wondering whether it'd be a good idea to make Node an iterator for its children. Because the scene tree is such a fundamental part of developing games with Godot, I suppose this just feels like a natural thing to me.

As a small potential bonus, this wouldn't have to allocate an Array[Node] like get_children() does, as presumably it'd just be using get_child(i) in the iterator.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

As above, iteration over a node's children would be possible by simply doing:

for child in node:
    # 'child' would also be typed as Node here, ideally.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, because Node can't be monkey-patched AFAIK.

Is there a reason why this should be core and not an add-on in the asset library?

As above.

@dalexeev
Copy link
Member

dalexeev commented Oct 4, 2024

This is not obvious and is not the only possible behavior (for example, you can iterate over the properties). Also, you can already write a custom iterator:

class NodeChildrenIterator:
    var _node: Node
    var _include_internal: bool

    func _init(node: Node, include_internal: bool = false) -> void:
        _node = node
        _include_internal = include_internal

    func _iter_init(iter: Array) -> bool:
        iter[0] = 0
        return 0 < _node.get_child_count(_include_internal)

    func _iter_next(iter: Array) -> bool:
        iter[0] += 1
        return iter[0] < _node.get_child_count(_include_internal)

    func _iter_get(iter: Variant) -> Node:
        return _node.get_child(iter, _include_internal)

func _ready() -> void:
    for child in NodeChildrenIterator.new(self):
        print(child.name)

Note that you can provide an additional parameter (include_internal) and also specify a static return type for _iter_get(), GDScript uses it to infer the type of the iterator variable. So this is a full-featured solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants