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

Never duplicate script with Resource.duplicate() #65374

Closed

Conversation

Mickeon
Copy link
Contributor

@Mickeon Mickeon commented Sep 5, 2022

Fix #58031.

Excludes the script property of a Resource from being ever duplicated. This doesn't mean that a Script resource cannot ever be duplicated, however.

@Mickeon Mickeon requested a review from a team as a code owner September 5, 2022 18:30
@Calinou Calinou added this to the 4.0 milestone Sep 5, 2022
@Mickeon
Copy link
Contributor Author

Mickeon commented Sep 14, 2022

This PR would fix the same identical bug by adding a flag. #41923

However, it's 2 years old and the flags are reaching their limit. It's worth considering.

@asmaloney
Copy link
Contributor

Thanks @Mickeon. I tested the changes and they fix the perplexing Parse Error: Class "Foo" hides a global script class. errors I was getting with my project.

core/io/resource.cpp Outdated Show resolved Hide resolved
@kleonc
Copy link
Member

kleonc commented Oct 6, 2022

Might be worth adding a note in the docs that the script is not being duplicated even if subresources param is true.

BTW this note:

[b]Note:[/b] If [param subresources] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared.

doesn't seem true to me, it looks like this part would handle resursively duplicating subresources:

godot/core/io/resource.cpp

Lines 265 to 269 in 61021c0

} else if (p.get_type() == Variant::OBJECT && (p_subresources || (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) {
Ref<Resource> sr = p;
if (sr.is_valid()) {
r->set(E.name, sr->duplicate(p_subresources));
}

And indeed seems like they are being duplicated recusively, simple example:

class_name Res
extends Resource

@export var subresource: Resource = null
@tool
extends EditorScript

func _run():
	var r := Res.new()
	r.subresource = Res.new()
	r.subresource.subresource = Res.new()
	
	print_res_info(r)
	print_res_info(r.duplicate(false))
	print_res_info(r.duplicate(true))

func print_res_info(r) -> void:
	print("r=%s r.subresource=%s r.subresource.subresource=%s" % [r, r.subresource, r.subresource.subresource])

Output:

  • v4.0.beta2.official [f8745f2] (so script is also duplicated):
r=<Resource#-9223370009428808011> r.subresource=<Resource#-9223370009412030794> r.subresource.subresource=<Resource#-9223370009395253577>
r=<Resource#-9223370009361699143> r.subresource=<Resource#-9223370009412030794> r.subresource.subresource=<Resource#-9223370009395253577>
  built-in:1 - Parse Error: Class "Res" hides a global script class.
  built-in:1 - Parse Error: Class "Res" hides a global script class.
  built-in:1 - Parse Error: Class "Res" hides a global script class.
r=<Resource#-9223370009328144684> r.subresource=<Resource#-9223370009277813039> r.subresource.subresource=<Resource#-9223370009227481395>
  • this PR:
r=<Resource#-9223369792868520409> r.subresource=<Resource#-9223369792851726658> r.subresource.subresource=<Resource#-9223369792834949392>
r=<Resource#-9223369792801394962> r.subresource=<Resource#-9223369792851726658> r.subresource.subresource=<Resource#-9223369792834949392>
r=<Resource#-9223369792767840575> r.subresource=<Resource#-9223369792751063332> r.subresource.subresource=<Resource#-9223369792734308538>
  • v3.5.1.stable.official [6fed1ff] (analogous example):
r=[Resource:103201] r.subresource=[Resource:103202] r.subresource.subresource=[Resource:103203]
r=[Resource:103204] r.subresource=[Resource:103202] r.subresource.subresource=[Resource:103203]
r=[Resource:103205] r.subresource=[Resource:103207] r.subresource.subresource=[Resource:103209]

So even in 3.x subresources are being duplicated recursively... 🤔 That note was added in #40210, not sure what were the exact reason (haven't read #30385 deeply) but it should be corrected too (might be done in a seperate PR though if you want to keep things simple here @Mickeon).

@kleonc
Copy link
Member

kleonc commented Oct 6, 2022

And I'm not sure if not duplicating script is always desired, someone else would need to confirm/deny it. If there are situations where duplicating it is wanted then probably subresources parameter should be changed to some enum instead (like suggested in #30385 (comment)).

@Mickeon
Copy link
Contributor Author

Mickeon commented Oct 6, 2022

Might be worth adding a note in the docs that the script is not being duplicated even if subresources param is true.

Should do, can do.

So even in 3.x subresources are being duplicated recursively... 🤔 That note was added in #40210, not sure what were the exact reason (haven't read #30385 deeply) but it should be corrected too (might be done in a seperate PR though if you want to keep things simple here.

I could do it here, but I struggle to understand what is incorrect about it, at least at the time of writing this.

And I'm not sure if not duplicating script is always desired, someone else would need to confirm/deny it. If there are situations where duplicating it is wanted then probably subresources parameter should be changed to some enum instead

In those cases, wouldn't it be possible to write something like new_resource.set_script(r.get_script().duplicate) on the very next line of the var new_resource = r.duplicate()? Although, I suppose that by doing that, the original custom property values would be lost...

@Mickeon
Copy link
Contributor Author

Mickeon commented Oct 6, 2022

The entire description honestly smells, I think the behaviour should be re-analysed and the description rewritten. For now I'm just going to add another note to it in this PR.

@Mickeon Mickeon force-pushed the fix-resource-duplicate-script branch from fabe8c0 to d916d0f Compare October 6, 2022 14:40
@Mickeon Mickeon requested a review from a team as a code owner October 6, 2022 14:40
@Mickeon
Copy link
Contributor Author

Mickeon commented Oct 8, 2022

@kleonc See #67072.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

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

This makes sense, we discussed it in a PR meeting and couldn't find a reason why we'd want to duplicate Script resources.

We just need to decide if we prefer this approach or the one in #41923, which introduces PROPERTY_USAGE_ALWAYS_SHARE_ON_DUPLICATE as pendant to the existing PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE.

@Mickeon Mickeon force-pushed the fix-resource-duplicate-script branch from 7f61d40 to 1450441 Compare October 22, 2022 14:19
@mhilbrunner
Copy link
Member

PR review meeting: we prefer the implementation in #41923. Thanks for contributing!

@mhilbrunner mhilbrunner closed this Nov 1, 2022
@Mickeon Mickeon deleted the fix-resource-duplicate-script branch January 2, 2024 20:23
@AThousandShips AThousandShips removed this from the 4.0 milestone Jan 2, 2024
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.

Resource.duplicate(true) also duplicates the script
8 participants