Skip to content

GraphEdit/GraphNode Overhaul #108099

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

Draft
wants to merge 32 commits into
base: master
Choose a base branch
from

Conversation

dawdle-deer
Copy link

@dawdle-deer dawdle-deer commented Jun 29, 2025

Implements godotengine/godot-proposals#12207 - read the description there for more details.

As this is a substantial breaking change (and my first real contribution), I'm making this a draft PR to get early feedback and make progress more visible.

Notably, this implementation does not overhaul VisualShader or VisualShaderNode. I believe a future PR that overhauls the visual shader system in parallel would be a good idea, but for this PR, changes will be relegated to VisualShaderNodePlugin and seek to maintain compatibility as much as possible.

TODO:

  • Fix so many regressions and bugs
  • Associate slots with nested children of GraphNodeIndexed
  • Ensure back-compatibility with visual shaders
  • Improve keyboard navigation and accessibility features

void move_connections(const Ref<GraphPort> p_from_port, const Ref<GraphPort> p_to_port);
bool is_connected(const Ref<GraphPort> p_first_port, const Ref<GraphPort> p_second_port);
int get_connection_count(const Ref<GraphPort> p_port);
GraphNode *get_connection_target(const Ref<GraphPort> p_port);
Copy link
Contributor

Choose a reason for hiding this comment

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

We should not assume that a GraphPort has a single target. For example in my plug-in that heavily relies on this contract, a data output port can be connected to N targets while only control flow output ports can be connected to a single target.

So I think this method, as it's designed, introduces nuanced behavior we should probably avoid. I would say if we truly wanted to keep this method, it should be changed to:

  1. Return multiple targets by default, that way it satisfies both cases I referred to above.
  2. It should return a collection of GraphPort, not the nodes. The nodes can be inferred from the ports.

Copy link
Author

@dawdle-deer dawdle-deer Jul 2, 2025

Choose a reason for hiding this comment

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

The method get_connections_by_port already serves this purpose, returning a TypedArray of all GraphConnections on a given port. Target ports can be accessed from this by calling GraphConnection.get_other(), but I'll keep in mind that getting a collection of target ports all at once is a useful API.

You're right that this method should be changed, but currently, it's only used in GraphNode for keyboard navigation, so fixing this will wait until I rework the keyboard accessibility features of GraphNode and GraphPort.

Copy link
Contributor

Choose a reason for hiding this comment

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

I will say other than this, I am really stoked at seeing these new APIs. We've had to build a lot of this as part of our own GraphNode implementations, so seeing this pulled up into the base implementation really helps to reduce a technical debt. And when you pair that with the idea of decoupling slot/index from ports and leaving that as an internal detail -- this is a huge improvement IMO; so definitely looking forward to this!

Copy link
Author

Choose a reason for hiding this comment

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

Still need to rework keyboard nav, but I've added a new method get_connected_ports to GraphEdit, which returns an array of all ports connected to a given port. Should cover this use case!

yo dawg i heard you like fixes, so we put fixes in your fixes so you can fix while you fix
this commit marks a tipping point: i've begun rewriting VNML to rely on this PR! VNML was the project that justified this change to begin with, and now, changes will be made in tandem with testing to speed up bug-squashing and feature/API improvements
new method for GraphEdit that returns all connections to ports that match a filter direction on a node. also comes with similar methods on GraphNode and GraphNodeIndexed
mostly ease of use/shortcut methods on GraphNode and GraphPort, as well as get_first_connection_by_port on GraphEdit to shortcut get_connections_by_port()[0]
this time, it's some ways to get all ports on a node that match a filter direction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants