From 4e9fb8183e4f9f3dbcf951eb1111126da05a9808 Mon Sep 17 00:00:00 2001 From: Devin Liang Date: Fri, 23 Apr 2021 17:31:37 -0400 Subject: [PATCH] Fix C# tool script displaying exported variables in the wrong order 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 --- modules/mono/csharp_script.cpp | 14 ++++++++++---- modules/mono/csharp_script.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 2adee4c565fa..04dc24ebd0fe 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1614,8 +1614,8 @@ void CSharpInstance::get_properties_state_for_reloading(List *p_properties) const { - for (Map::Element *E = script->member_info.front(); E; E = E->next()) { - p_properties->push_back(E->value()); + for (const List::Element *E = script->member_order.front(); E; E = E->next()) { + p_properties->push_back(script->member_info[E->get()]); } // Call _get_property_list @@ -2234,6 +2234,7 @@ void CSharpScript::_update_member_info_no_exports() { exports_invalidated = false; member_info.clear(); + member_order.clear(); GDMonoClass *top = script_class; @@ -2250,6 +2251,7 @@ void CSharpScript::_update_member_info_no_exports() { StringName member_name = field->get_name(); member_info[member_name] = prop_info; + member_order.push_front(member_name); exported_members_cache.push_front(prop_info); exported_members_defval_cache[member_name] = Variant(); } @@ -2264,6 +2266,7 @@ void CSharpScript::_update_member_info_no_exports() { StringName member_name = property->get_name(); member_info[member_name] = prop_info; + member_order.push_front(member_name); exported_members_cache.push_front(prop_info); exported_members_defval_cache[member_name] = Variant(); } @@ -2297,6 +2300,7 @@ bool CSharpScript::_update_exports() { changed = true; member_info.clear(); + member_order.clear(); #ifdef TOOLS_ENABLED MonoObject *tmp_object = nullptr; @@ -2357,6 +2361,7 @@ bool CSharpScript::_update_exports() { StringName member_name = field->get_name(); member_info[member_name] = prop_info; + member_order.push_front(member_name); if (exported) { #ifdef TOOLS_ENABLED @@ -2385,6 +2390,7 @@ bool CSharpScript::_update_exports() { StringName member_name = property->get_name(); member_info[member_name] = prop_info; + member_order.push_front(member_name); if (exported) { #ifdef TOOLS_ENABLED @@ -3302,8 +3308,8 @@ Ref