Skip to content

Commit 2f63b04

Browse files
committed
FSUI: Use locale sensitive sort for game list
1 parent 2d350b9 commit 2f63b04

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__)
@@ -687,3 +691,11 @@ int QtHost::LocaleSensitiveCompare(QStringView lhs, QStringView rhs)
687691
{
688692
return s_current_collator.compare(lhs, rhs);
689693
}
694+
695+
int Host::LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs)
696+
{
697+
QString qlhs = QString::fromUtf8(lhs.data(), lhs.size());
698+
QString qrhs = QString::fromUtf8(rhs.data(), rhs.size());
699+
std::lock_guard<std::mutex> guard(QtHost::s_collator_mtx);
700+
return QtHost::s_current_collator.compare(qlhs, qrhs);
701+
}

pcsx2/Host.h

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

152+
/// Compare strings in the locale of the current UI language from any thread. Prefer the QtHost version if you can use it.
153+
int LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs);
154+
152155
namespace Internal
153156
{
154157
/// 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
@@ -7683,11 +7683,41 @@ void FullscreenUI::PopulateGameListEntryList()
76837683
{
76847684
const int sort = Host::GetBaseIntSettingValue("UI", "FullscreenUIGameSort", 0);
76857685
const bool reverse = Host::GetBaseBoolSettingValue("UI", "FullscreenUIGameSortReverse", false);
7686+
static int s_last_sort = -1;
7687+
static bool s_last_reverse = false;
7688+
static bool s_last_prefer_eng = false;
7689+
static std::vector<const GameList::Entry*> s_last_unsorted_entries;
76867690

7691+
// Sort can be expensive, try to avoid when possible
76877692
const u32 count = GameList::GetEntryCount();
7693+
bool needs_update = sort != s_last_sort || reverse != s_last_reverse || s_last_prefer_eng != s_prefer_english_titles;
7694+
needs_update |= count != s_last_unsorted_entries.size();
7695+
if (!needs_update)
7696+
{
7697+
for (u32 i = 0; i < count; i++)
7698+
{
7699+
if (GameList::GetEntryByIndex(i) != s_last_unsorted_entries[i])
7700+
{
7701+
needs_update = true;
7702+
break;
7703+
}
7704+
}
7705+
}
7706+
7707+
if (!needs_update)
7708+
return;
7709+
7710+
s_last_sort = sort;
7711+
s_last_reverse = reverse;
7712+
s_last_prefer_eng = s_prefer_english_titles;
7713+
76887714
s_game_list_sorted_entries.resize(count);
7715+
s_last_unsorted_entries.resize(count);
76897716
for (u32 i = 0; i < count; i++)
7717+
{
76907718
s_game_list_sorted_entries[i] = GameList::GetEntryByIndex(i);
7719+
s_last_unsorted_entries[i] = s_game_list_sorted_entries[i];
7720+
}
76917721

76927722
std::sort(s_game_list_sorted_entries.begin(), s_game_list_sorted_entries.end(),
76937723
[sort, reverse](const GameList::Entry* lhs, const GameList::Entry* rhs) {
@@ -7758,7 +7788,7 @@ void FullscreenUI::PopulateGameListEntryList()
77587788
}
77597789

77607790
// fallback to title when all else is equal
7761-
const int res = StringUtil::Strcasecmp(lhs->GetTitleSort(s_prefer_english_titles).c_str(), rhs->GetTitleSort(s_prefer_english_titles).c_str());
7791+
const int res = Host::LocaleSensitiveCompare(lhs->GetTitleSort(s_prefer_english_titles), rhs->GetTitleSort(s_prefer_english_titles));
77627792
return reverse ? (res > 0) : (res < 0);
77637793
});
77647794
}

tests/ctest/core/StubHost.cpp

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

274+
int Host::LocaleSensitiveCompare(std::string_view lhs, std::string_view rhs)
275+
{
276+
int res = std::strncmp(lhs.data(), rhs.data(), std::min(lhs.size(), rhs.size()));
277+
if (res != 0)
278+
return res;
279+
return lhs.size() > rhs.size() ? 1 : lhs.size() < rhs.size() ? -1 : 0;
280+
}
281+
274282
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view str)
275283
{
276284
return std::nullopt;

0 commit comments

Comments
 (0)