iOS: Update recents paths on load

Fixes the main part of #19211
This commit is contained in:
Henrik Rydgård 2024-05-29 10:12:20 +02:00
parent a851e82b28
commit 606a895985
5 changed files with 54 additions and 6 deletions

View File

@ -340,6 +340,9 @@ std::string ResolvePath(const std::string &path) {
delete [] buf;
return output;
#elif PPSSPP_PLATFORM(IOS)
// Resolving has wacky effects on documents paths.
return path;
#else
std::unique_ptr<char[]> buf(new char[PATH_MAX + 32768]);
if (realpath(path.c_str(), buf.get()) == nullptr)
@ -404,8 +407,8 @@ bool Exists(const Path &path) {
SetErrorMode(OldMode);
#endif
return true;
#else
struct stat file_info;
#else // !WIN32
struct stat file_info{};
return stat(path.c_str(), &file_info) == 0;
#endif
}

View File

@ -381,8 +381,8 @@ void VulkanSetAvailable(bool available) {
bool VulkanMayBeAvailable() {
#if PPSSPP_PLATFORM(IOS)
g_vulkanAvailabilityChecked = true;
// MoltenVK does no longer seem to support iOS <= 12, despite what the docs say.
g_vulkanMayBeAvailable = System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 13;
INFO_LOG(SYSTEM, "VulkanMayBeAvailable: Detected version: %d", (int)System_GetPropertyInt(SYSPROP_SYSTEMVERSION));
return g_vulkanMayBeAvailable;
#else
// Unsupported in VR at the moment

View File

@ -1367,7 +1367,7 @@ bool Config::Save(const char *saveReason) {
playTimeTracker_.Save(playTime);
if (!iniFile.Save(iniFilename_)) {
ERROR_LOG(LOADER, "Error saving config (%s)- can't write ini '%s'", saveReason, iniFilename_.c_str());
ERROR_LOG(LOADER, "Error saving config (%s) - can't write ini '%s'", saveReason, iniFilename_.c_str());
return false;
}
INFO_LOG(LOADER, "Config saved (%s): '%s' (%0.1f ms)", saveReason, iniFilename_.c_str(), (time_now_d() - startTime) * 1000.0);
@ -1546,6 +1546,34 @@ void Config::RemoveRecent(const std::string &file) {
recentIsos.erase(iter, recentIsos.end());
}
// On iOS, the path to the app documents directory changes on each launch.
// Example path:
// /var/mobile/Containers/Data/Application/0E0E89DE-8D8E-485A-860C-700D8BC87B86/Documents/PSP/GAME/SuicideBarbie
// The GUID part changes on each launch.
bool TryUpdateSavedPath(Path *path) {
#if PPSSPP_PLATFORM(IOS)
INFO_LOG(LOADER, "Original path: %s", path->c_str());
std::string pathStr = path->ToString();
const std::string_view applicationRoot = "/var/mobile/Containers/Data/Application/";
if (startsWith(pathStr, applicationRoot)) {
size_t documentsPos = pathStr.find("/Documents/");
if (documentsPos == std::string::npos) {
return false;
}
std::string memstick = g_Config.memStickDirectory.ToString();
size_t memstickDocumentsPos = memstick.find("/Documents"); // Note: No trailing slash, or we won't find it.
*path = Path(memstick.substr(0, memstickDocumentsPos) + pathStr.substr(documentsPos));
return true;
} else {
// Path can't be auto-updated.
return false;
}
#else
return false;
#endif
}
void Config::CleanRecent() {
private_->SetRecentIsosThread([this] {
SetCurrentThreadName("RecentISOs");
@ -1556,6 +1584,10 @@ void Config::CleanRecent() {
std::lock_guard<std::mutex> guard(private_->recentIsosLock);
std::vector<std::string> cleanedRecent;
if (recentIsos.empty()) {
INFO_LOG(LOADER, "No recents list found.");
}
for (size_t i = 0; i < recentIsos.size(); i++) {
bool exists = false;
Path path = Path(recentIsos[i]);
@ -1563,6 +1595,12 @@ void Config::CleanRecent() {
case PathType::CONTENT_URI:
case PathType::NATIVE:
exists = File::Exists(path);
if (!exists) {
if (TryUpdateSavedPath(&path)) {
exists = File::Exists(path);
INFO_LOG(LOADER, "Exists=%d when checking updated path: %s", exists, path.c_str());
}
}
break;
default:
FileLoader *loader = ConstructFileLoader(path);
@ -1572,11 +1610,14 @@ void Config::CleanRecent() {
}
if (exists) {
std::string pathStr = path.ToString();
// Make sure we don't have any redundant items.
auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), recentIsos[i]);
auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), pathStr);
if (duplicate == cleanedRecent.end()) {
cleanedRecent.push_back(recentIsos[i]);
cleanedRecent.push_back(pathStr);
}
} else {
DEBUG_LOG(LOADER, "Removed %s from recent. errno=%d", path.c_str(), errno);
}
}

View File

@ -292,6 +292,8 @@ void GLRenderLoop(IOSGLESContext *graphicsContext) {
{
INFO_LOG(SYSTEM, "shutdown GL");
g_Config.Save("shutdown GL");
_dbg_assert_(graphicsContext);
_dbg_assert_(sharedViewController != nil);
sharedViewController = nil;

View File

@ -353,6 +353,8 @@ void VulkanRenderLoop(IOSVulkanContext *graphicsContext, CAMetalLayer *metalLaye
{
INFO_LOG(SYSTEM, "shutdown VK");
g_Config.Save("shutdown vk");
_dbg_assert_(sharedViewController != nil);
sharedViewController = nil;