citra_qt: Track play time

Co-Authored-By: Mario Davó <66087392+mdmrk@users.noreply.github.com>
This commit is contained in:
FearlessTobi
2024-02-08 00:17:16 +01:00
committed by OpenSauce04
parent 89a119dbe9
commit 9ca3c5699f
16 changed files with 394 additions and 8 deletions

View File

@@ -53,6 +53,7 @@
#define SHADER_DIR "shaders"
#define STATES_DIR "states"
#define ICONS_DIR "icons"
#define PLAY_TIME_DIR "play_time"
// Filenames
// Files in the directory returned by GetUserPath(UserPath::LogDir)

View File

@@ -827,6 +827,7 @@ void SetUserPath(const std::string& path) {
g_paths.emplace(UserPath::LoadDir, user_path + LOAD_DIR DIR_SEP);
g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP);
g_paths.emplace(UserPath::IconsDir, user_path + ICONS_DIR DIR_SEP);
g_paths.emplace(UserPath::PlayTimeDir, user_path + PLAY_TIME_DIR DIR_SEP);
g_default_paths = g_paths;
}

View File

@@ -41,6 +41,7 @@ enum class UserPath {
SysDataDir,
UserDir,
IconsDir,
PlayTimeDir,
};
// Replaces install-specific paths with standard placeholders, and back again
@@ -344,6 +345,59 @@ public:
return WriteArray(str.data(), str.length());
}
/**
* Reads a span of T data from a file sequentially.
* This function reads from the current position of the file pointer and
* advances it by the (count of T * sizeof(T)) bytes successfully read.
*
* Failures occur when:
* - The file is not open
* - The opened file lacks read permissions
* - Attempting to read beyond the end-of-file
*
* @tparam T Data type
*
* @param data Span of T data
*
* @returns Count of T data successfully read.
*/
template <typename T>
[[nodiscard]] size_t ReadSpan(std::span<T> data) const {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
if (!IsOpen()) {
return 0;
}
return std::fread(data.data(), sizeof(T), data.size(), m_file);
}
/**
* Writes a span of T data to a file sequentially.
* This function writes from the current position of the file pointer and
* advances it by the (count of T * sizeof(T)) bytes successfully written.
*
* Failures occur when:
* - The file is not open
* - The opened file lacks write permissions
*
* @tparam T Data type
*
* @param data Span of T data
*
* @returns Count of T data successfully written.
*/
template <typename T>
[[nodiscard]] size_t WriteSpan(std::span<const T> data) const {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
if (!IsOpen()) {
return 0;
}
return std::fwrite(data.data(), sizeof(T), data.size(), m_file);
}
[[nodiscard]] bool IsOpen() const {
return nullptr != m_file;
}

View File

@@ -12,8 +12,11 @@
#ifdef __cpp_lib_jthread
#include <chrono>
#include <condition_variable>
#include <stop_token>
#include <thread>
#include <utility>
namespace Common {
@@ -22,11 +25,23 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
cv.wait(lock, token, std::move(pred));
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
std::condition_variable_any cv;
std::mutex m;
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); });
}
} // namespace Common
#else
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <map>
#include <memory>
@@ -333,6 +348,30 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
cv.wait(lock, [&] { return pred() || token.stop_requested(); });
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
if (token.stop_requested()) {
return false;
}
bool stop_requested = false;
std::condition_variable cv;
std::mutex m;
std::stop_callback cb(token, [&] {
// Wake up the waiting thread.
{
std::scoped_lock lk{m};
stop_requested = true;
}
cv.notify_one();
});
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
}
} // namespace Common
#endif // __cpp_lib_jthread