Skip to content

Commit dc0b211

Browse files
committed
FSUI: Use locale sensitive sort for game list
1 parent adeb406 commit dc0b211

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

pcsx2-qt/Translations.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ namespace QtHost
7171

7272
static QLocale s_current_locale;
7373
static QCollator s_current_collator;
74+
static std::mutex s_collator_mtx;
7475

7576
static std::vector<QTranslator*> s_translators;
7677
} // namespace QtHost
@@ -122,7 +123,10 @@ void QtHost::InstallTranslator(QWidget* dialog_parent)
122123
QString qlanguage = language;
123124
qlanguage.replace('-', '_');
124125
s_current_locale = QLocale(qlanguage);
125-
s_current_collator = QCollator(s_current_locale);
126+
{
127+
std::lock_guard<std::mutex> guard(s_collator_mtx);
128+
s_current_collator = QCollator(s_current_locale);
129+
}
126130

127131
// Install the base qt translation first.
128132
#if defined(__APPLE__)
@@ -694,3 +698,11 @@ int QtHost::LocaleSensitiveCompare(QStringView lhs, QStringView rhs)
694698
{
695699
return s_current_collator.compare(lhs, rhs);
696700
}
701+
702+
int Host::LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs)
703+
{
704+
QString qlhs = QString::fromUtf8(lhs.data(), lhs.size());
705+
QString qrhs = QString::fromUtf8(rhs.data(), rhs.size());
706+
std::lock_guard<std::mutex> guard(QtHost::s_collator_mtx);
707+
return QtHost::s_current_collator.compare(qlhs, qrhs);
708+
}

pcsx2/Host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ namespace Host
147147
/// Creates a progress callback that displays in the host.
148148
std::unique_ptr<ProgressCallback> CreateHostProgressCallback();
149149

150+
/// Compare strings in the locale of the current UI language from any thread. Prefer the QtHost version if you can use it.
151+
int LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs);
152+
150153
namespace Internal
151154
{
152155
/// Retrieves the base settings layer. Must call with lock held.

pcsx2/ImGui/FullscreenUI.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7787,11 +7787,41 @@ void FullscreenUI::PopulateGameListEntryList()
77877787
{
77887788
const int sort = Host::GetBaseIntSettingValue("UI", "FullscreenUIGameSort", 0);
77897789
const bool reverse = Host::GetBaseBoolSettingValue("UI", "FullscreenUIGameSortReverse", false);
7790+
static int s_last_sort = -1;
7791+
static bool s_last_reverse = false;
7792+
static bool s_last_prefer_eng = false;
7793+
static std::vector<const GameList::Entry*> s_last_unsorted_entries;
77907794

7795+
// Sort can be expensive, try to avoid when possible
77917796
const u32 count = GameList::GetEntryCount();
7797+
bool needs_update = sort != s_last_sort || reverse != s_last_reverse || s_last_prefer_eng != s_prefer_english_titles;
7798+
needs_update |= count != s_last_unsorted_entries.size();
7799+
if (!needs_update)
7800+
{
7801+
for (u32 i = 0; i < count; i++)
7802+
{
7803+
if (GameList::GetEntryByIndex(i) != s_last_unsorted_entries[i])
7804+
{
7805+
needs_update = true;
7806+
break;
7807+
}
7808+
}
7809+
}
7810+
7811+
if (!needs_update)
7812+
return;
7813+
7814+
s_last_sort = sort;
7815+
s_last_reverse = reverse;
7816+
s_last_prefer_eng = s_prefer_english_titles;
7817+
77927818
s_game_list_sorted_entries.resize(count);
7819+
s_last_unsorted_entries.resize(count);
77937820
for (u32 i = 0; i < count; i++)
7821+
{
77947822
s_game_list_sorted_entries[i] = GameList::GetEntryByIndex(i);
7823+
s_last_unsorted_entries[i] = s_game_list_sorted_entries[i];
7824+
}
77957825

77967826
std::sort(s_game_list_sorted_entries.begin(), s_game_list_sorted_entries.end(),
77977827
[sort, reverse](const GameList::Entry* lhs, const GameList::Entry* rhs) {
@@ -7862,7 +7892,7 @@ void FullscreenUI::PopulateGameListEntryList()
78627892
}
78637893

78647894
// fallback to title when all else is equal
7865-
const int res = StringUtil::Strcasecmp(lhs->GetTitleSort(s_prefer_english_titles).c_str(), rhs->GetTitleSort(s_prefer_english_titles).c_str());
7895+
const int res = Host::LocaleSensitiveCompare(lhs->GetTitleSort(s_prefer_english_titles), rhs->GetTitleSort(s_prefer_english_titles));
78667896
return reverse ? (res > 0) : (res < 0);
78677897
});
78687898
}

tests/ctest/core/StubHost.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ void Host::OpenHostFileSelectorAsync(std::string_view title, bool select_directo
266266
callback(std::string());
267267
}
268268

269+
int Host::LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs)
270+
{
271+
int res = std::strncmp(lhs.data(), rhs.data(), std::min(lhs.size(), rhs.size()));
272+
if (res != 0)
273+
return res;
274+
return lhs.size() > rhs.size() ? 1 : lhs.size() < rhs.size() ? -1 : 0;
275+
}
276+
269277
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view str)
270278
{
271279
return std::nullopt;

0 commit comments

Comments
 (0)