savedata: fix dir name search with wildcard (#1552)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

* savedata: fix dir name search with wildcard

* psf: replace filesystem clock by system clock (utc)

* savedatadialog_ui: macOS zoned_time formatting

Signed-off-by: Vinicius Rangel <me@viniciusrangel.dev>

---------

Signed-off-by: Vinicius Rangel <me@viniciusrangel.dev>
Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com>
This commit is contained in:
Vinicius Rangel 2024-11-20 13:31:44 -03:00 committed by GitHub
parent 96cd79f272
commit b41664ac61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 14 deletions

View File

@ -21,8 +21,13 @@ static inline u32 get_max_size(std::string_view key, u32 default_value) {
} }
bool PSF::Open(const std::filesystem::path& filepath) { bool PSF::Open(const std::filesystem::path& filepath) {
using namespace std::chrono;
if (std::filesystem::exists(filepath)) { if (std::filesystem::exists(filepath)) {
last_write = std::filesystem::last_write_time(filepath); const auto t = std::filesystem::last_write_time(filepath);
const auto rel =
duration_cast<seconds>(t - std::filesystem::file_time_type::clock::now()).count();
const auto tp = system_clock::to_time_t(system_clock::now() + seconds{rel});
last_write = system_clock::from_time_t(tp);
} }
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read); Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
@ -99,7 +104,7 @@ bool PSF::Encode(const std::filesystem::path& filepath) const {
return false; return false;
} }
last_write = std::filesystem::file_time_type::clock::now(); last_write = std::chrono::system_clock::now();
const auto psf_buffer = Encode(); const auto psf_buffer = Encode();
const size_t written = file.Write(psf_buffer); const size_t written = file.Write(psf_buffer);

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <chrono>
#include <filesystem> #include <filesystem>
#include <span> #include <span>
#include <string> #include <string>
@ -71,7 +72,7 @@ public:
void AddString(std::string key, std::string value, bool update = false); void AddString(std::string key, std::string value, bool update = false);
void AddInteger(std::string key, s32 value, bool update = false); void AddInteger(std::string key, s32 value, bool update = false);
[[nodiscard]] std::filesystem::file_time_type GetLastWrite() const { [[nodiscard]] std::chrono::system_clock::time_point GetLastWrite() const {
return last_write; return last_write;
} }
@ -80,7 +81,7 @@ public:
} }
private: private:
mutable std::filesystem::file_time_type last_write; mutable std::chrono::system_clock::time_point last_write;
std::vector<Entry> entry_list; std::vector<Entry> entry_list;

View File

@ -13,6 +13,33 @@
#include "imgui/imgui_std.h" #include "imgui/imgui_std.h"
#include "savedatadialog_ui.h" #include "savedatadialog_ui.h"
#ifdef __APPLE__
#include <date/tz.h>
// Need to make a copy of the formatter for std::chrono::local_time for use with date::local_time
template <typename Duration, typename Char>
struct fmt::formatter<date::local_time<Duration>, Char> : formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() {
this->format_str_ = fmt::detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
}
template <typename FormatContext>
auto format(date::local_time<Duration> val, FormatContext& ctx) const -> decltype(ctx.out()) {
using period = typename Duration::period;
if (period::num == 1 && period::den == 1 &&
!std::is_floating_point<typename Duration::rep>::value) {
return formatter<std::tm, Char>::format(
localtime(fmt::detail::to_time_t(date::current_zone()->to_sys(val))), ctx);
}
auto epoch = val.time_since_epoch();
auto subsecs = fmt::detail::duration_cast<Duration>(
epoch - fmt::detail::duration_cast<std::chrono::seconds>(epoch));
return formatter<std::tm, Char>::do_format(
localtime(fmt::detail::to_time_t(date::current_zone()->to_sys(val))), ctx, &subsecs);
}
};
#endif
using namespace ImGui; using namespace ImGui;
using namespace Libraries::CommonDialog; using namespace Libraries::CommonDialog;
using Common::ElfInfo; using Common::ElfInfo;
@ -98,12 +125,12 @@ SaveDialogState::SaveDialogState(const OrbisSaveDataDialogParam& param) {
param_sfo.Open(param_sfo_path); param_sfo.Open(param_sfo_path);
auto last_write = param_sfo.GetLastWrite(); auto last_write = param_sfo.GetLastWrite();
#if defined(_WIN32) && !defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) #ifdef __APPLE__
auto utc_time = std::chrono::file_clock::to_utc(last_write); auto t = date::zoned_time{date::current_zone(), last_write};
#else #else
auto utc_time = std::chrono::file_clock::to_sys(last_write); auto t = std::chrono::zoned_time{std::chrono::current_zone(), last_write};
#endif #endif
std::string date_str = fmt::format("{:%d %b, %Y %R}", utc_time); std::string date_str = fmt::format("{:%d %b, %Y %R}", t.get_local_time());
size_t size = Common::FS::GetDirectorySize(dir_path); size_t size = Common::FS::GetDirectorySize(dir_path);
std::string size_str = SpaceSizeToString(size); std::string size_str = SpaceSizeToString(size);
@ -592,7 +619,7 @@ void SaveDialogUi::DrawList() {
int idx = 0; int idx = 0;
int max_idx = 0; int max_idx = 0;
bool is_min = pos == FocusPos::DATAOLDEST; bool is_min = pos == FocusPos::DATAOLDEST;
std::filesystem::file_time_type max_write{}; std::chrono::system_clock::time_point max_write{};
if (state->new_item.has_value()) { if (state->new_item.has_value()) {
idx++; idx++;
} }

View File

@ -248,7 +248,7 @@ public:
std::string date{}; std::string date{};
std::string size{}; std::string size{};
std::filesystem::file_time_type last_write{}; std::chrono::system_clock::time_point last_write{};
PSF pfo{}; PSF pfo{};
bool is_corrupted{}; bool is_corrupted{};
}; };

View File

@ -149,7 +149,7 @@ struct OrbisSaveDataIcon {
size_t dataSize; size_t dataSize;
std::array<u8, 32> _reserved; std::array<u8, 32> _reserved;
Error LoadIcon(const std::filesystem::path& icon_path) { Error LoadIcon(const fs::path& icon_path) {
try { try {
const Common::FS::IOFile file(icon_path, Common::FS::FileAccessMode::Read); const Common::FS::IOFile file(icon_path, Common::FS::FileAccessMode::Read);
dataSize = file.GetSize(); dataSize = file.GetSize();
@ -345,7 +345,9 @@ static bool match(std::string_view str, std::string_view pattern) {
if (*pat_it == '_') { // 1 character wildcard if (*pat_it == '_') { // 1 character wildcard
++str_it; ++str_it;
++pat_it; ++pat_it;
} else if (*pat_it != *str_it) { continue;
}
if (*pat_it != *str_it) {
return false; return false;
} }
++str_it; ++str_it;
@ -1230,7 +1232,7 @@ Error PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint
return Error::PARAMETER; return Error::PARAMETER;
} }
LOG_DEBUG(Lib_SaveData, "called"); LOG_DEBUG(Lib_SaveData, "called");
std::filesystem::path path; fs::path path;
const std::string_view mount_point_str{mountPoint->data}; const std::string_view mount_point_str{mountPoint->data};
for (const auto& instance : g_mount_slots) { for (const auto& instance : g_mount_slots) {
if (instance.has_value() && instance->GetMountPoint() == mount_point_str) { if (instance.has_value() && instance->GetMountPoint() == mount_point_str) {
@ -1375,7 +1377,7 @@ Error PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint
return Error::PARAMETER; return Error::PARAMETER;
} }
LOG_DEBUG(Lib_SaveData, "called"); LOG_DEBUG(Lib_SaveData, "called");
std::filesystem::path path; fs::path path;
const std::string_view mount_point_str{mountPoint->data}; const std::string_view mount_point_str{mountPoint->data};
for (const auto& instance : g_mount_slots) { for (const auto& instance : g_mount_slots) {
if (instance.has_value() && instance->GetMountPoint() == mount_point_str) { if (instance.has_value() && instance->GetMountPoint() == mount_point_str) {