mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-21 08:14:48 +00:00
UI: Use atomic flags in game info cache.
Simpler, no need to lock the entire info when checking these.
This commit is contained in:
parent
c948a3df00
commit
d00dcb4400
@ -46,6 +46,7 @@
|
||||
GameInfoCache *g_gameInfoCache;
|
||||
|
||||
GameInfo::GameInfo() : fileType(IdentifiedFileType::UNKNOWN) {
|
||||
pending = true;
|
||||
}
|
||||
|
||||
GameInfo::~GameInfo() {
|
||||
@ -300,16 +301,6 @@ std::string GameInfo::GetTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
bool GameInfo::IsPending() {
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
return pending;
|
||||
}
|
||||
|
||||
bool GameInfo::IsWorking() {
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
return working;
|
||||
}
|
||||
|
||||
void GameInfo::SetTitle(const std::string &newTitle) {
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
title = newTitle;
|
||||
@ -368,12 +359,8 @@ public:
|
||||
if (!info_->LoadFromPath(gamePath_))
|
||||
return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(info_->lock);
|
||||
info_->working = true;
|
||||
info_->fileType = Identify_File(info_->GetFileLoader().get());
|
||||
}
|
||||
|
||||
info_->working = true;
|
||||
info_->fileType = Identify_File(info_->GetFileLoader().get());
|
||||
switch (info_->fileType) {
|
||||
case IdentifiedFileType::PSP_PBP:
|
||||
case IdentifiedFileType::PSP_PBP_DIRECTORY:
|
||||
@ -392,6 +379,7 @@ public:
|
||||
goto handleELF;
|
||||
}
|
||||
ERROR_LOG(LOADER, "invalid pbp %s\n", pbpLoader->Path().c_str());
|
||||
info_->working = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -556,11 +544,15 @@ handleELF:
|
||||
// TODO: This will currently read in the whole directory tree. Not really necessary for just a
|
||||
// few files.
|
||||
auto fl = info_->GetFileLoader();
|
||||
if (!fl)
|
||||
if (!fl) {
|
||||
info_->working = false;
|
||||
return; // Happens with UWP currently, TODO...
|
||||
}
|
||||
BlockDevice *bd = constructBlockDevice(info_->GetFileLoader().get());
|
||||
if (!bd)
|
||||
if (!bd) {
|
||||
info_->working = false;
|
||||
return; // nothing to do here..
|
||||
}
|
||||
ISOFileSystem umd(&handles, bd);
|
||||
|
||||
// Alright, let's fetch the PARAM.SFO.
|
||||
@ -639,7 +631,6 @@ handleELF:
|
||||
info_->installDataSize = info_->GetInstallDataSizeInBytes();
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(info_->lock);
|
||||
info_->pending = false;
|
||||
info_->working = false;
|
||||
// ILOG("Completed writing info for %s", info_->GetTitle().c_str());
|
||||
@ -721,7 +712,8 @@ void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
|
||||
gameInfoWQ_->Flush();
|
||||
restart:
|
||||
for (auto iter = info_.begin(); iter != info_.end(); iter++) {
|
||||
if (iter->second->fileType == fileType) {
|
||||
auto &info = iter->second;
|
||||
if (!info->working && info->fileType == fileType) {
|
||||
info_.erase(iter);
|
||||
goto restart;
|
||||
}
|
||||
@ -729,7 +721,7 @@ void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
|
||||
}
|
||||
|
||||
void GameInfoCache::WaitUntilDone(std::shared_ptr<GameInfo> &info) {
|
||||
while (info->IsPending()) {
|
||||
while (info->pending) {
|
||||
if (gameInfoWQ_->WaitUntilDone(false)) {
|
||||
// A true return means everything finished, so bail out.
|
||||
// This way even if something gets stuck, we won't hang.
|
||||
@ -769,7 +761,7 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
|
||||
info = std::make_shared<GameInfo>();
|
||||
}
|
||||
|
||||
if (info->IsWorking()) {
|
||||
if (info->working) {
|
||||
// Uh oh, it's currently in process. It could mark pending = false with the wrong wantFlags.
|
||||
// Let's wait it out, then queue.
|
||||
// NOTE: This is bad because we're likely on the UI thread....
|
||||
|
@ -108,9 +108,6 @@ public:
|
||||
std::string GetTitle();
|
||||
void SetTitle(const std::string &newTitle);
|
||||
|
||||
bool IsPending();
|
||||
bool IsWorking();
|
||||
|
||||
// Hold this when reading or writing from the GameInfo.
|
||||
// Don't need to hold it when just passing around the pointer,
|
||||
// and obviously also not when creating it and holding the only pointer
|
||||
@ -142,8 +139,8 @@ public:
|
||||
u64 gameSize = 0;
|
||||
u64 saveDataSize = 0;
|
||||
u64 installDataSize = 0;
|
||||
bool pending = true;
|
||||
bool working = false;
|
||||
std::atomic<bool> pending{};
|
||||
std::atomic<bool> working{};
|
||||
|
||||
protected:
|
||||
// Note: this can change while loading, use GetTitle().
|
||||
|
@ -123,7 +123,7 @@ void GameScreen::CreateViews() {
|
||||
rightColumnItems->Add(btnDeleteSaveData_)->OnClick.Handle(this, &GameScreen::OnDeleteSaveData);
|
||||
btnDeleteSaveData_->SetVisibility(V_GONE);
|
||||
|
||||
if (info && !info->IsPending()) {
|
||||
if (info && !info->pending) {
|
||||
otherChoices_.clear();
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ void GameScreen::update() {
|
||||
btnSetBackground_->SetVisibility(UI::V_VISIBLE);
|
||||
}
|
||||
}
|
||||
if (!info->IsPending()) {
|
||||
if (!info->pending) {
|
||||
// At this point, the above buttons won't become visible. We can show these now.
|
||||
for (UI::Choice *choice : otherChoices_) {
|
||||
choice->SetVisibility(UI::V_VISIBLE);
|
||||
@ -419,7 +419,7 @@ void SetBackgroundPopupScreen::update() {
|
||||
PopupScreen::update();
|
||||
|
||||
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTBGDATA);
|
||||
if (status_ == Status::PENDING && info && !info->IsPending()) {
|
||||
if (status_ == Status::PENDING && info && !info->pending) {
|
||||
GameInfoTex *pic = nullptr;
|
||||
if (info->pic1.dataLoaded && info->pic1.data.size()) {
|
||||
pic = &info->pic1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user