diff options
-rw-r--r-- | core/io/json.cpp | 2 | ||||
-rw-r--r-- | core/variant/variant.h | 13 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 9 | ||||
-rw-r--r-- | modules/gdscript/editor/gdscript_docgen.cpp | 2 | ||||
-rw-r--r-- | tests/core/variant/test_variant.h | 8 |
6 files changed, 28 insertions, 8 deletions
diff --git a/core/io/json.cpp b/core/io/json.cpp index 664ff7857b..22219fca29 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -121,7 +121,7 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_ d.get_key_list(&keys); if (p_sort_keys) { - keys.sort(); + keys.sort_custom<StringLikeVariantOrder>(); } bool first_key = true; diff --git a/core/variant/variant.h b/core/variant/variant.h index c76b849abd..3b1924e8ea 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -854,6 +854,19 @@ struct StringLikeVariantComparator { static bool compare(const Variant &p_lhs, const Variant &p_rhs); }; +struct StringLikeVariantOrder { + static _ALWAYS_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { + if (p_lhs.is_string() && p_rhs.is_string()) { + return p_lhs.operator String() < p_rhs.operator String(); + } + return p_lhs < p_rhs; + } + + _ALWAYS_INLINE_ bool operator()(const Variant &p_lhs, const Variant &p_rhs) const { + return compare(p_lhs, p_rhs); + } +}; + Variant::ObjData &Variant::_get_obj() { return *reinterpret_cast<ObjData *>(&_data._mem[0]); } diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index f5f96456d3..f05b9cd83a 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -2245,7 +2245,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } else { List<Variant> keys; dict.get_key_list(&keys); - keys.sort(); + keys.sort_custom<StringLikeVariantOrder>(); if (keys.is_empty()) { // Avoid unnecessary line break. diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index ede8351e41..a5df9edcf0 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2128,12 +2128,11 @@ void VisualShaderEditor::_update_nodes() { } } - Array keys = added.keys(); - keys.sort(); - - for (int i = 0; i < keys.size(); i++) { - const Variant &key = keys.get(i); + List<Variant> keys; + added.get_key_list(&keys); + keys.sort_custom<StringLikeVariantOrder>(); + for (const Variant &key : keys) { const Dictionary &value = (Dictionary)added[key]; add_custom_type(value["name"], value["type"], value["script"], value["description"], value["return_icon_type"], value["category"], value["highend"]); diff --git a/modules/gdscript/editor/gdscript_docgen.cpp b/modules/gdscript/editor/gdscript_docgen.cpp index 32ef429b0d..758887a723 100644 --- a/modules/gdscript/editor/gdscript_docgen.cpp +++ b/modules/gdscript/editor/gdscript_docgen.cpp @@ -217,7 +217,7 @@ String GDScriptDocGen::_docvalue_from_variant(const Variant &p_variant, int p_re List<Variant> keys; dict.get_key_list(&keys); - keys.sort(); + keys.sort_custom<StringLikeVariantOrder>(); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { if (E->prev()) { diff --git a/tests/core/variant/test_variant.h b/tests/core/variant/test_variant.h index be615975f8..599a282b20 100644 --- a/tests/core/variant/test_variant.h +++ b/tests/core/variant/test_variant.h @@ -1806,6 +1806,14 @@ TEST_CASE("[Variant] Writer and parser dictionary") { CHECK_MESSAGE(d_parsed == Variant(d), "Should parse back."); } +TEST_CASE("[Variant] Writer key sorting") { + Dictionary d = build_dictionary(StringName("C"), 3, "A", 1, StringName("B"), 2, "D", 4); + String d_str; + VariantWriter::write_to_string(d, d_str); + + CHECK_EQ(d_str, "{\n\"A\": 1,\n&\"B\": 2,\n&\"C\": 3,\n\"D\": 4\n}"); +} + TEST_CASE("[Variant] Writer recursive dictionary") { // There is no way to accurately represent a recursive dictionary, // the only thing we can do is make sure the writer doesn't blow up |