aboutsummaryrefslogtreecommitdiff
path: root/src/core/launch_timestamp_cache.cpp
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2026-01-19 04:18:55 +0100
committercrueter <crueter@eden-emu.dev>2026-01-19 04:18:55 +0100
commit30cbec7ad5de5cde2f63f669139ea06e9e925aa7 (patch)
tree69067f049308b60a60b0394847200b8b662e3b6e /src/core/launch_timestamp_cache.cpp
parent1fbace438c375ca1e33f3cb09d7d85249cb51293 (diff)
[core/hle] Adds sorting game titles and prevents hard crashes in qlaunch (#3330)
Adds correct sorting in qlaunch (tested with FW 19 and FW20-21) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3330 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: MaranBr <maranbr@eden-emu.dev> Co-authored-by: Maufeat <sahyno1996@gmail.com> Co-committed-by: Maufeat <sahyno1996@gmail.com>
Diffstat (limited to 'src/core/launch_timestamp_cache.cpp')
-rw-r--r--src/core/launch_timestamp_cache.cpp55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/core/launch_timestamp_cache.cpp b/src/core/launch_timestamp_cache.cpp
index 5a154a5c2f..037992d69a 100644
--- a/src/core/launch_timestamp_cache.cpp
+++ b/src/core/launch_timestamp_cache.cpp
@@ -22,10 +22,12 @@ namespace Core::LaunchTimestampCache {
namespace {
using CacheMap = std::unordered_map<u64, s64>;
+using CountMap = std::unordered_map<u64, u64>;
-std::mutex mutex;
-CacheMap cache;
-bool loaded = false;
+std::mutex g_mutex;
+CacheMap g_cache;
+CountMap g_counts;
+bool g_loaded = false;
std::filesystem::path GetCachePath() {
return Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "launched.json";
@@ -54,11 +56,11 @@ bool WriteStringToFile(const std::filesystem::path& path, const std::string& dat
}
void Load() {
- if (loaded) {
+ if (g_loaded) {
return;
}
- loaded = true;
+ g_loaded = true;
const auto path = GetCachePath();
if (!std::filesystem::exists(path)) {
@@ -86,19 +88,31 @@ void Load() {
} catch (...) {
continue;
}
- if (value.is_number_integer()) {
- cache[key] = value.get<s64>();
+ if (value.is_object()) {
+ if (value.contains("timestamp") && value["timestamp"].is_number_integer()) {
+ g_cache[key] = value["timestamp"].get<s64>();
+ }
+ if (value.contains("launch_count") && value["launch_count"].is_number_unsigned()) {
+ g_counts[key] = value["launch_count"].get<u64>();
+ }
+ } else if (value.is_number_integer()) {
+ // Legacy format: raw timestamp only
+ g_cache[key] = value.get<s64>();
}
}
} catch (const std::exception& e) {
- LOG_WARNING(Core, "Failed to parse launch timestamp cache");
+ LOG_WARNING(Core, "Failed to parse launch timestamp cache: {}", e.what());
}
}
void Save() {
nlohmann::json json = nlohmann::json::object();
- for (const auto& [key, value] : cache) {
- json[fmt::format("{:016X}", key)] = value;
+ for (const auto& [key, value] : g_cache) {
+ nlohmann::json entry = nlohmann::json::object();
+ entry["timestamp"] = value;
+ const auto count_it = g_counts.find(key);
+ entry["launch_count"] = count_it != g_counts.end() ? count_it->second : 0;
+ json[fmt::format("{:016X}", key)] = entry;
}
const auto path = GetCachePath();
@@ -115,21 +129,32 @@ s64 NowSeconds() {
} // namespace
void SaveLaunchTimestamp(u64 title_id) {
- std::scoped_lock lk{mutex};
+ std::scoped_lock lk{g_mutex};
Load();
- cache[title_id] = NowSeconds();
+ g_cache[title_id] = NowSeconds();
+ g_counts[title_id] = g_counts[title_id] + 1;
Save();
}
s64 GetLaunchTimestamp(u64 title_id) {
- std::scoped_lock lk{mutex};
+ std::scoped_lock lk{g_mutex};
Load();
- const auto it = cache.find(title_id);
- if (it != cache.end()) {
+ const auto it = g_cache.find(title_id);
+ if (it != g_cache.end()) {
return it->second;
}
// we need a timestamp, i decided on 01/01/2026 00:00
return 1767225600;
}
+u64 GetLaunchCount(u64 title_id) {
+ std::scoped_lock lk{g_mutex};
+ Load();
+ const auto it = g_counts.find(title_id);
+ if (it != g_counts.end()) {
+ return it->second;
+ }
+ return 0;
+}
+
} // namespace Core::LaunchTimestampCache