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

When saving a resource with an exported typed array, check whether the type is an external resource #85024

Conversation

Jordyfel
Copy link
Contributor

@Jordyfel Jordyfel commented Nov 17, 2023

Fix #84498

A type of an exported typed array (when it is a script) would not get recognized as an external resource if it was one, which prevented the script from being recognized as a dependency of the resource, which prevented the script path from being updated when moved (since scripts don't have UIDs, that couldn't help either).

Test with test_proj.zip by moving res.gd in and out of the additional dir.

Before:

[gd_scene load_steps=3 format=3 uid="uid://c3fdfa0an52aa"]

[ext_resource type="Script" path="res://main_scene.gd" id="1_vwyik"]
[ext_resource type="Resource" uid="uid://blikieqcyffrc" path="res://new_res.tres" id="3_88yrl"]

[node name="MainScene" type="Node2D"]
script = ExtResource("1_vwyik")
res_twos = Array[Resource("res://res.gd")]([ExtResource("3_88yrl")])

This doesn't allow the script path for the array type to be updated when that script is moved, making the scene unopenable.

After:

[gd_scene load_steps=4 format=3 uid="uid://c3fdfa0an52aa"]

[ext_resource type="Script" path="res://main_scene.gd" id="1_vwyik"]
[ext_resource type="Script" path="res://res.gd" id="2_e4r82"]
[ext_resource type="Resource" uid="uid://blikieqcyffrc" path="res://new_res.tres" id="3_88yrl"]

[node name="MainScene" type="Node2D"]
script = ExtResource("1_vwyik")
res_twos = Array[ExtResource("2_e4r82")]([ExtResource("3_88yrl")])

@AThousandShips
Copy link
Member

AThousandShips commented Nov 17, 2023

and an error about the EditorResourcePicker not seeing the type properly (appears very inconsistently).

This needs to be solved assuming it's introduced by this PR

Note that this surfaces other issues, one about gdscipts still being looked for at the old location

This should also not surface due to this PR if avoidable

@Jordyfel
Copy link
Contributor Author

Jordyfel commented Nov 17, 2023

This should also not surface due to this PR if avoidable

This one doesn't, will edit the OP to be clearer

@Jordyfel
Copy link
Contributor Author

I don't see how this is a gdscript issue, exporting a typed array is not language specific.

@AThousandShips
Copy link
Member

Based it on the specifics of the error report, wasn't possible to tell from it that it wasn't GDScript specific, updated both

@Jordyfel Jordyfel force-pushed the moving-scripts-of-types-of-exported-typed-arrays branch from 6bc8e5a to bc657c2 Compare November 18, 2023 19:44
@Jordyfel Jordyfel requested a review from a team as a code owner November 18, 2023 19:44
@akien-mga akien-mga requested a review from dalexeev April 8, 2024 11:45
Copy link
Member

@dalexeev dalexeev left a comment

Choose a reason for hiding this comment

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

I didn't find any issues with resource_format_text.cpp, but it doesn't work well with resource_format_binary.cpp. However, it seems that this PR does not introduce new issues, although it does not fix all.

A few notes:

  1. Renaming only works through the editor, since scripts do not yet support UID.
  2. Old scenes must be saved at least once so that the script path is replaced with ExtResource. Otherwise the issue persists.
  3. ResourceLoaderText uses VariantParser which supports SubResource/ExtResource in a unified manner. And ResourceLoaderBinary uses a custom format (even not Marshalls which only support absolute res:// paths for scripts). We should add support for typed arrays in the following places if possible without breaking compatibility:

case Variant::ARRAY: {
f->store_32(VARIANT_ARRAY);
Array a = p_property;
f->store_32(uint32_t(a.size()));
for (int i = 0; i < a.size(); i++) {
write_variant(f, a[i], resource_map, external_resources, string_map);
}

case VARIANT_ARRAY: {
uint32_t len = f->get_32();
Array a; //last bit means shared
len &= 0x7FFFFFFF;
a.resize(len);
for (uint32_t i = 0; i < len; i++) {
Variant val;
Error err = parse_variant(val);
ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Error when trying to parse Variant.");
a[i] = val;
}
r_v = a;

Given that users typically use tscn/tres (not scn/res) during development, I think we could merge this PR as is, and leave exploring the possibility of fixing binary scenes/resources for later. @Jordyfel Let me know if you want to work on this, otherwise I'll add it to my TODO list.

@akien-mga akien-mga modified the milestones: 4.x, 4.3 Apr 9, 2024
@akien-mga
Copy link
Member

@Jordyfel There's no conflicts, but could you rebase to make sure this passes CI and tests on latest master? The last rebase was a while ago.

@Jordyfel Jordyfel force-pushed the moving-scripts-of-types-of-exported-typed-arrays branch from bc657c2 to 82de00a Compare April 9, 2024 12:28
@Jordyfel
Copy link
Contributor Author

Jordyfel commented Apr 9, 2024

Rebased. I do want to try to fix the binary format properly

@dalexeev
Copy link
Member

dalexeev commented Apr 9, 2024

I do want to try to fix the binary format properly

Note that there are currently three kinds of typed arrays. You can see #78219 as an example.

@Jordyfel
Copy link
Contributor Author

Jordyfel commented Apr 9, 2024

I see that reading and writing would have to be reimplemented in the binary format much like in the marshalls

This makes me wonder, is there even a benefit to the binary format supporting typed arrays. It doesn't now and it hasn't come up.

@akien-mga akien-mga merged commit bff6955 into godotengine:master Apr 9, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks!

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.

Scene gets corrupted when a script file referenced inside an array is moved or renamed
4 participants