[Core] Fix sorting of Dictionary keys

`StringName` keys were sorted as `StringName` which is unstable.
This commit is contained in:
A Thousand Ships 2024-09-27 15:56:54 +02:00
parent 04692d83cb
commit 79f654ced5
No known key found for this signature in database
GPG Key ID: 2033189A662F8BD7
5 changed files with 20 additions and 8 deletions

View File

@ -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;

View File

@ -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]);
}

View File

@ -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.

View File

@ -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"]);

View File

@ -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()) {