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

Fix C# tool script displaying exported variables in the wrong order #48143

Closed

Conversation

devin-liang
Copy link

@devin-liang devin-liang commented Apr 23, 2021

Hello all, first time contributor here :)

Previously, exported variables in a C# tool script would not appear in
the order they were exported within the inspector upon rebuilding the
project solution. The potential cause of this problem is that the
CSharpInstance::get_property_list method was iterating through
the member_info Map member variable to populate the p_properties
list argument.

Maps typically do not give guarantees about the ordering of elements
and I think that Godot's implementation of Map may also shuffle elements
around.

My proposed solution is to add a new list within the CSharpScript
class that contains the keys of the member_info Map in the order
they were inserted. This list is cleared and gets new elements
whenever the member_info Map is cleared or updated.

This fix causes exported variables in C# tools scripts to appear
in the order they were exported within the inspector after rebuilding
the project solution just like regular C# scripts.

Fixes #47465

Previously, exported variables in a C# tool script would not appear in
the order they were exported within the inspector upon rebuilding the
project solution. The potential cause of this problem is that the
CSharpInstance::get_property_list method was iterating through
the member_info Map member variable to populate the p_properties
list argument.

Maps typically do not give guarantees about the ordering of elements
and I think that Godot's implementation of Map may also shuffle elements
around.

My proposed solution is to add a new list within the CSharpScript
class that contains the keys of the member_info Map in the order
they were inserted. This list is cleared and gets new elements
whenever the member_info Map is cleared or updated.

This fix causes exported variables in C# tools scripts to appear
in the order they were exported within the inspector after rebuilding
the project solution just like regular C# scripts.

Fixes godotengine#47465
@devin-liang devin-liang requested a review from a team as a code owner April 23, 2021 22:08
@devin-liang devin-liang marked this pull request as draft April 23, 2021 22:09
@devin-liang devin-liang marked this pull request as ready for review April 23, 2021 22:11
@akien-mga akien-mga modified the milestones: 4.0, 3.4 Apr 23, 2021
@akien-mga
Copy link
Member

Thanks for the contribution :) I'll let @neikeq review the implementation for Mono specifically.

Some meta comments:

  • The bug likely exists in the master branch too, so that's where it should be fixed in priority. Otherwise if we merge this in 3.x only, it will be fixed in 3.4 but not in 4.0 and beyond.
  • The email used to author your commit is not linked to your GitHub account, which is why the commit doesn't show as authored by "@devin-liang". That's not a problem for Git nor Godot, but if you want to "claim" this commit as being authored by your account, you can add this email as secondary email in your GitHub profile.

@devin-liang
Copy link
Author

Thanks for the kind words and fast comment! The email tip is much appreciated.

@aaronfranke
Copy link
Member

@devin-liang Any update? There still needs to be a version of this PR for the master branch.

@neikeq
Copy link
Contributor

neikeq commented Aug 24, 2021

Maybe this should be done similarly to how GDScript does it:

Vector<_GDScriptMemberSort> msort;
for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) {
_GDScriptMemberSort ms;
ERR_CONTINUE(!sptr->member_indices.has(F->key()));
ms.index = sptr->member_indices[F->key()].index;
ms.name = F->key();
msort.push_back(ms);
}
msort.sort();
msort.reverse();
for (int i = 0; i < msort.size(); i++) {
props.push_front(sptr->member_info[msort[i].name]);
}

@akien-mga
Copy link
Member

Closing as this needs to be redone as advised above. Marking as salvageable.

@raulsntos
Copy link
Member

@neikeq It seems what GDScript does is simply sort the properties by their index which they keep in a different Map, how is that different from what devin-liang was trying to do but instead of keeping the index information in a Map he was using a List, maybe we should replace member_info with an OrderedHashMap which is basically a Map like before but it already includes that List with the order inside so they don't go out of sync.

@devin-liang Are you still working on this? If not, would you mind if I give it a try?

@devin-liang
Copy link
Author

@raulsntos Yeah go ahead and give it try if you'd like. I don't think I'll be actively working on this anymore. I apologize for no updates on this issue for so long.

@raulsntos
Copy link
Member

Opened #54130 for master and #54199 for 3.x

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.

5 participants