summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/io/json.cpp2
-rw-r--r--core/variant/variant.h13
-rw-r--r--core/variant/variant_parser.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp9
-rw-r--r--modules/gdscript/editor/gdscript_docgen.cpp2
-rw-r--r--tests/core/variant/test_variant.h8
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