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

Implement Unique Node IDs #86960

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

reduz
Copy link
Member

@reduz reduz commented Jan 8, 2024

  • Scene instantiation and inheritance now use unique IDs for referencing.
  • Ensures that if a node is moved or renamed, the scene that inherits keeps functioning by still referencing that node properly (which it does by ID, no longer by path).
  • Eventually will be extended to Asset IO

WARNING: THIS NEEDS A LOT OF TESTING AND REVIEW - DO NOT USE IN YOUR PROJECT, IT WILL BREAK IT.

Note: This bumps the binary format version, files saved with this will no longer work in earlier versions of Godot.

Note: ResourceFormatText::save_as_binary is broken with this, but this function is no longer in use, should it be removed as part of this PR?

Note: I am allowing negative numbers in there for IDs (only 0 is unassigned), I may as well not, let me know if you want me to change this.

@reduz reduz requested a review from a team as a code owner January 8, 2024 12:43
* Scene instantiation and inheritance now use unique IDs for referencing.
* Ensures that if a node is moved or renamed, the scene that inherits keeps functioning.
* Eventually will be extended to Asset IO

**WARNING**: THIS NEEDS A LOT OF TESTING AND REVIEW
// There is inheritance at play, try with parent.
Ref<PackedScene> parent = base_state->variants[base_state->base_scene_idx];
if (parent.is_valid()) {
base_state = parent->get_state().ptr();
Copy link
Member Author

Choose a reason for hiding this comment

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

This part here is pretty odd. It means if it did not find the node in the local scene, it will try with the scene that it inherits from. I am not sure if this is 100% correct, but It's the only way I can think of that works with inheritance.

@reduz
Copy link
Member Author

reduz commented Jan 8, 2024

I think what I may need to change is that if you instantiate a scene (not inherit it), the ID of the instance should probably be different than that of the scene when opened separatedly. I already change it if instantiated more than once, but may need to make an exception here by forcing the node ID to unassigned when called with GEN_EDIT_STATE_INSTANCE.

@adamscott adamscott self-requested a review January 8, 2024 13:09

uint32_t ResourceUID::generate_random_u32() const {
uint32_t num;
Error err = ((CryptoCore::RandomGenerator *)crypto)->get_random_bytes((uint8_t *)&num, sizeof(uint32_t));
Copy link
Member

@fire fire Jan 8, 2024

Choose a reason for hiding this comment

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

Will this ever change to an int64? I've seen other systems like https://en.wikipedia.org/wiki/Snowflake_ID use 64 bits.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a feeling 4,294,967,296 nodes in a single PackedScene is not an amount that will be reached any time soon.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't know we're incrementing. We are using random bytes here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, then, it may actually be an issue, but unsure.

Copy link
Member

Choose a reason for hiding this comment

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

It looks like where it is called, it checks for duplicates and calls again until a unique is found, so collisions shouldn't be a problem (aside from the time spent checking for duplicates).

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably no, this is only for a single scene so no need for so much.

@KoBeWi
Copy link
Member

KoBeWi commented Jan 8, 2024

I opened a scene (tscn), it added a bunch of IDs to nodes, but only that. I'd expect nodes to use these IDs instead of parent path, but that's not the case. I checked some simple inheritance case (added node in inherited scene and moved its parent in the base scene) and it still breaks.
What is this PR supposed to do?

btw so far modified text scenes can still be opened in an earlier Godot version.

@reduz
Copy link
Member Author

reduz commented Jan 9, 2024

@KoBeWi it won't use paths within the local scene because it does not make much sense (and path is more readable). IDs are used mostly when you do scene inheritance/instantiation with editable children and place nodes as children of nodes of other scenes. They are also used for signal connections.

@KoBeWi
Copy link
Member

KoBeWi commented Jan 9, 2024

IDs are used mostly when you do scene inheritance/instantiation with editable children and place nodes as children of nodes of other scenes.

Well that's what I tested and it didn't work correctly. Though I'll need to check again if the IDs are used correctly.

@KoBeWi
Copy link
Member

KoBeWi commented Jan 9, 2024

Ok I tested again and indeed, parent is always a path, even if the node is under inherited node or editable child. Both in tscn and scn. The only case that works correctly is binary inherited scene.

@reduz
Copy link
Member Author

reduz commented Jan 11, 2024

@KoBeWi Maybe I broke it, thanks still for giving it a spin, will see if I can fix it today!

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.

6 participants