@@ -54,7 +54,7 @@ void GameInfoTex::Clear() {
54
54
}
55
55
}
56
56
57
- GameInfo::GameInfo () {
57
+ GameInfo::GameInfo (const Path &gamePath) : filePath_(gamePath ) {
58
58
// here due to a forward decl.
59
59
fileType = IdentifiedFileType::UNKNOWN;
60
60
}
@@ -231,26 +231,13 @@ u64 GameInfo::GetInstallDataSizeInBytes() {
231
231
return totalSize;
232
232
}
233
233
234
- bool GameInfo::LoadFromPath (const Path &gamePath) {
235
- {
236
- std::lock_guard<std::mutex> guard (lock);
237
- // No need to rebuild if we already have it loaded.
238
- if (filePath_ == gamePath) {
239
- return true ;
240
- }
241
- }
242
-
243
- {
234
+ bool GameInfo::CreateLoader () {
235
+ if (!fileLoader) {
244
236
std::lock_guard<std::mutex> guard (loaderLock);
245
- fileLoader.reset (ConstructFileLoader (gamePath ));
237
+ fileLoader.reset (ConstructFileLoader (filePath_ ));
246
238
if (!fileLoader)
247
239
return false ;
248
240
}
249
-
250
- std::lock_guard<std::mutex> guard (lock);
251
- filePath_ = gamePath;
252
- // This is a fallback title, while we're loading / if unable to load.
253
- title = filePath_.GetFilename ();
254
241
return true ;
255
242
}
256
243
@@ -463,7 +450,7 @@ class GameInfoWorkItem : public Task {
463
450
void Run () override {
464
451
// An early-return will result in the destructor running, where we can set
465
452
// flags like working and pending.
466
- if (!info_->LoadFromPath (gamePath_ )) {
453
+ if (!info_->CreateLoader ( )) {
467
454
return ;
468
455
}
469
456
@@ -515,6 +502,7 @@ class GameInfoWorkItem : public Task {
515
502
info_->id_version = info_->id + " _1.00" ;
516
503
info_->region = GAMEREGION_MAX + 1 ; // Homebrew
517
504
}
505
+ info_->MarkReadyNoLock (GameInfoFlags::PARAM_SFO);
518
506
}
519
507
}
520
508
@@ -606,6 +594,7 @@ class GameInfoWorkItem : public Task {
606
594
std::lock_guard<std::mutex> lock (info_->lock );
607
595
info_->paramSFO .ReadSFO ((const u8 *)paramSFOcontents.data (), paramSFOcontents.size ());
608
596
info_->ParseParamSFO ();
597
+ info_->MarkReadyNoLock (GameInfoFlags::PARAM_SFO);
609
598
}
610
599
}
611
600
if (flags_ & GameInfoFlags::ICON) {
@@ -623,6 +612,8 @@ class GameInfoWorkItem : public Task {
623
612
{
624
613
if (flags_ & GameInfoFlags::PARAM_SFO) {
625
614
info_->SetTitle (SaveState::GetTitle (gamePath_));
615
+ std::lock_guard<std::mutex> lock (info_->lock );
616
+ info_->MarkReadyNoLock (GameInfoFlags::PARAM_SFO);
626
617
}
627
618
628
619
// Let's use the screenshot as an icon, too.
@@ -664,8 +655,10 @@ class GameInfoWorkItem : public Task {
664
655
}
665
656
}
666
657
667
- ReadFileToString (&umd, " /PSP_GAME/ICON0.PNG" , &info_->icon .data , &info_->lock );
668
- info_->icon .dataLoaded = true ;
658
+ if (flags_ & GameInfoFlags::ICON) {
659
+ ReadFileToString (&umd, " /PSP_GAME/ICON0.PNG" , &info_->icon .data , &info_->lock );
660
+ info_->icon .dataLoaded = true ;
661
+ }
669
662
if (flags_ & GameInfoFlags::BG) {
670
663
ReadFileToString (&umd, " /PSP_GAME/PIC0.PNG" , &info_->pic0 .data , &info_->lock );
671
664
info_->pic0 .dataLoaded = true ;
@@ -704,6 +697,9 @@ class GameInfoWorkItem : public Task {
704
697
std::lock_guard<std::mutex> lock (info_->lock );
705
698
info_->paramSFO .ReadSFO ((const u8 *)paramSFOcontents.data (), paramSFOcontents.size ());
706
699
info_->ParseParamSFO ();
700
+
701
+ // quick-update the info while we have the lock, so we don't need to wait for the image load to display the title.
702
+ info_->MarkReadyNoLock (GameInfoFlags::PARAM_SFO);
707
703
}
708
704
}
709
705
}
@@ -781,8 +777,7 @@ class GameInfoWorkItem : public Task {
781
777
782
778
// Time to update the flags.
783
779
std::unique_lock<std::mutex> lock (info_->lock );
784
- info_->hasFlags |= flags_;
785
- info_->pendingFlags &= ~flags_;
780
+ info_->MarkReadyNoLock (flags_);
786
781
// INFO_LOG(SYSTEM, "Completed writing info for %s", info_->GetTitle().c_str());
787
782
}
788
783
@@ -846,26 +841,39 @@ void GameInfoCache::FlushBGs() {
846
841
847
842
void GameInfoCache::PurgeType (IdentifiedFileType fileType) {
848
843
bool retry = false ;
844
+ int retryCount = 10 ;
849
845
// Trickery to avoid sleeping with the lock held.
850
846
do {
847
+ if (retry) {
848
+ retryCount--;
849
+ if (retryCount == 0 ) {
850
+ break ;
851
+ }
852
+ }
853
+ retry = false ;
851
854
{
852
855
std::lock_guard<std::mutex> lock (mapLock_);
853
856
for (auto iter = info_.begin (); iter != info_.end ();) {
854
857
auto &info = iter->second ;
855
-
858
+ if (!(info->hasFlags & GameInfoFlags::FILE_TYPE)) {
859
+ iter++;
860
+ continue ;
861
+ }
862
+ if (info->fileType != fileType) {
863
+ iter++;
864
+ continue ;
865
+ }
856
866
// TODO: Find a better way to wait here.
857
- while (info->pendingFlags != (GameInfoFlags)0 ) {
867
+ if (info->pendingFlags != (GameInfoFlags)0 ) {
868
+ INFO_LOG (LOADER, " %s: pending flags %08x, retrying" , info->GetTitle ().c_str (), info->pendingFlags );
858
869
retry = true ;
859
870
break ;
860
871
}
861
- if (info->fileType == fileType) {
862
- iter = info_.erase (iter);
863
- } else {
864
- iter++;
865
- }
872
+ iter = info_.erase (iter);
866
873
}
867
874
}
868
- sleep_ms (1 );
875
+
876
+ sleep_ms (10 );
869
877
} while (retry);
870
878
}
871
879
@@ -903,7 +911,7 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
903
911
return info;
904
912
}
905
913
906
- std::shared_ptr<GameInfo> info = std::make_shared<GameInfo>();
914
+ std::shared_ptr<GameInfo> info = std::make_shared<GameInfo>(gamePath );
907
915
info->pendingFlags = wantFlags;
908
916
info->lastAccessedTime = time_now_d ();
909
917
info_.insert (std::make_pair (pathStr, info));
0 commit comments