diff options
| author | 2018-08-25 19:00:36 -0400 | |
|---|---|---|
| committer | 2018-09-04 16:21:40 -0400 | |
| commit | 9951f6d0543980e29e6107e0bd4ea35977f1cf29 (patch) | |
| tree | 2ee34991b03ab10607d41c90588a52a0476ddfc6 /src/core | |
| parent | game_list: Use RegisteredCacheUnion for installed (diff) | |
| download | yuzu-9951f6d0543980e29e6107e0bd4ea35977f1cf29.tar.gz yuzu-9951f6d0543980e29e6107e0bd4ea35977f1cf29.tar.xz yuzu-9951f6d0543980e29e6107e0bd4ea35977f1cf29.zip | |
registration: Add RegisteredCacheUnion
Aggregates multiple caches into one interface
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 114 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.h | 40 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 3 |
4 files changed, 164 insertions, 0 deletions
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index cf6f77401..39c0710e1 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp | |||
| @@ -280,6 +280,14 @@ VirtualFile RegisteredCache::GetEntryUnparsed(RegisteredCacheEntry entry) const | |||
| 280 | return GetEntryUnparsed(entry.title_id, entry.type); | 280 | return GetEntryUnparsed(entry.title_id, entry.type); |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const { | ||
| 284 | if (meta.find(title_id) != meta.end()) | ||
| 285 | return meta.at(title_id).GetTitleVersion(); | ||
| 286 | if (yuzu_meta.find(title_id) != yuzu_meta.end()) | ||
| 287 | return yuzu_meta.at(title_id).GetTitleVersion(); | ||
| 288 | return boost::none; | ||
| 289 | } | ||
| 290 | |||
| 283 | VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { | 291 | VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { |
| 284 | const auto id = GetNcaIDFromMetadata(title_id, type); | 292 | const auto id = GetNcaIDFromMetadata(title_id, type); |
| 285 | if (id == boost::none) | 293 | if (id == boost::none) |
| @@ -498,4 +506,110 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) { | |||
| 498 | kv.second.GetTitleID() == cnmt.GetTitleID(); | 506 | kv.second.GetTitleID() == cnmt.GetTitleID(); |
| 499 | }) != yuzu_meta.end(); | 507 | }) != yuzu_meta.end(); |
| 500 | } | 508 | } |
| 509 | |||
| 510 | RegisteredCacheUnion::RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches) | ||
| 511 | : caches(std::move(caches)) {} | ||
| 512 | |||
| 513 | void RegisteredCacheUnion::Refresh() { | ||
| 514 | for (const auto& c : caches) | ||
| 515 | c->Refresh(); | ||
| 516 | } | ||
| 517 | |||
| 518 | bool RegisteredCacheUnion::HasEntry(u64 title_id, ContentRecordType type) const { | ||
| 519 | for (const auto& c : caches) { | ||
| 520 | if (c->HasEntry(title_id, type)) | ||
| 521 | return true; | ||
| 522 | } | ||
| 523 | |||
| 524 | return false; | ||
| 525 | } | ||
| 526 | |||
| 527 | bool RegisteredCacheUnion::HasEntry(RegisteredCacheEntry entry) const { | ||
| 528 | return HasEntry(entry.title_id, entry.type); | ||
| 529 | } | ||
| 530 | |||
| 531 | boost::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const { | ||
| 532 | for (const auto& c : caches) { | ||
| 533 | const auto res = c->GetEntryVersion(title_id); | ||
| 534 | if (res != boost::none) | ||
| 535 | return res; | ||
| 536 | } | ||
| 537 | |||
| 538 | return boost::none; | ||
| 539 | } | ||
| 540 | |||
| 541 | VirtualFile RegisteredCacheUnion::GetEntryUnparsed(u64 title_id, ContentRecordType type) const { | ||
| 542 | for (const auto& c : caches) { | ||
| 543 | const auto res = c->GetEntryUnparsed(title_id, type); | ||
| 544 | if (res != nullptr) | ||
| 545 | return res; | ||
| 546 | } | ||
| 547 | |||
| 548 | return nullptr; | ||
| 549 | } | ||
| 550 | |||
| 551 | VirtualFile RegisteredCacheUnion::GetEntryUnparsed(RegisteredCacheEntry entry) const { | ||
| 552 | return GetEntryUnparsed(entry.title_id, entry.type); | ||
| 553 | } | ||
| 554 | |||
| 555 | VirtualFile RegisteredCacheUnion::GetEntryRaw(u64 title_id, ContentRecordType type) const { | ||
| 556 | for (const auto& c : caches) { | ||
| 557 | const auto res = c->GetEntryRaw(title_id, type); | ||
| 558 | if (res != nullptr) | ||
| 559 | return res; | ||
| 560 | } | ||
| 561 | |||
| 562 | return nullptr; | ||
| 563 | } | ||
| 564 | |||
| 565 | VirtualFile RegisteredCacheUnion::GetEntryRaw(RegisteredCacheEntry entry) const { | ||
| 566 | return GetEntryRaw(entry.title_id, entry.type); | ||
| 567 | } | ||
| 568 | |||
| 569 | std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(u64 title_id, ContentRecordType type) const { | ||
| 570 | const auto raw = GetEntryRaw(title_id, type); | ||
| 571 | if (raw == nullptr) | ||
| 572 | return nullptr; | ||
| 573 | return std::make_shared<NCA>(raw); | ||
| 574 | } | ||
| 575 | |||
| 576 | std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(RegisteredCacheEntry entry) const { | ||
| 577 | return GetEntry(entry.title_id, entry.type); | ||
| 578 | } | ||
| 579 | |||
| 580 | std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntries() const { | ||
| 581 | std::vector<RegisteredCacheEntry> out; | ||
| 582 | for (const auto& c : caches) { | ||
| 583 | c->IterateAllMetadata<RegisteredCacheEntry>( | ||
| 584 | out, | ||
| 585 | [](const CNMT& c, const ContentRecord& r) { | ||
| 586 | return RegisteredCacheEntry{c.GetTitleID(), r.type}; | ||
| 587 | }, | ||
| 588 | [](const CNMT& c, const ContentRecord& r) { return true; }); | ||
| 589 | } | ||
| 590 | return out; | ||
| 591 | } | ||
| 592 | |||
| 593 | std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter( | ||
| 594 | boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type, | ||
| 595 | boost::optional<u64> title_id) const { | ||
| 596 | std::vector<RegisteredCacheEntry> out; | ||
| 597 | for (const auto& c : caches) { | ||
| 598 | c->IterateAllMetadata<RegisteredCacheEntry>( | ||
| 599 | out, | ||
| 600 | [](const CNMT& c, const ContentRecord& r) { | ||
| 601 | return RegisteredCacheEntry{c.GetTitleID(), r.type}; | ||
| 602 | }, | ||
| 603 | [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) { | ||
| 604 | if (title_type != boost::none && title_type.get() != c.GetType()) | ||
| 605 | return false; | ||
| 606 | if (record_type != boost::none && record_type.get() != r.type) | ||
| 607 | return false; | ||
| 608 | if (title_id != boost::none && title_id.get() != c.GetTitleID()) | ||
| 609 | return false; | ||
| 610 | return true; | ||
| 611 | }); | ||
| 612 | } | ||
| 613 | return out; | ||
| 614 | } | ||
| 501 | } // namespace FileSys | 615 | } // namespace FileSys |
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index 467ceeef1..dcce3fd16 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h | |||
| @@ -43,6 +43,10 @@ struct RegisteredCacheEntry { | |||
| 43 | std::string DebugInfo() const; | 43 | std::string DebugInfo() const; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | constexpr inline u64 GetUpdateTitleID(u64 base_title_id) { | ||
| 47 | return base_title_id | 0x800; | ||
| 48 | } | ||
| 49 | |||
| 46 | // boost flat_map requires operator< for O(log(n)) lookups. | 50 | // boost flat_map requires operator< for O(log(n)) lookups. |
| 47 | bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); | 51 | bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); |
| 48 | 52 | ||
| @@ -60,6 +64,8 @@ bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs) | |||
| 60 | * 4GB splitting can be ignored.) | 64 | * 4GB splitting can be ignored.) |
| 61 | */ | 65 | */ |
| 62 | class RegisteredCache { | 66 | class RegisteredCache { |
| 67 | friend class RegisteredCacheUnion; | ||
| 68 | |||
| 63 | public: | 69 | public: |
| 64 | // Parsing function defines the conversion from raw file to NCA. If there are other steps | 70 | // Parsing function defines the conversion from raw file to NCA. If there are other steps |
| 65 | // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom | 71 | // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom |
| @@ -74,6 +80,8 @@ public: | |||
| 74 | bool HasEntry(u64 title_id, ContentRecordType type) const; | 80 | bool HasEntry(u64 title_id, ContentRecordType type) const; |
| 75 | bool HasEntry(RegisteredCacheEntry entry) const; | 81 | bool HasEntry(RegisteredCacheEntry entry) const; |
| 76 | 82 | ||
| 83 | boost::optional<u32> GetEntryVersion(u64 title_id) const; | ||
| 84 | |||
| 77 | VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; | 85 | VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; |
| 78 | VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; | 86 | VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; |
| 79 | 87 | ||
| @@ -131,4 +139,36 @@ private: | |||
| 131 | boost::container::flat_map<u64, CNMT> yuzu_meta; | 139 | boost::container::flat_map<u64, CNMT> yuzu_meta; |
| 132 | }; | 140 | }; |
| 133 | 141 | ||
| 142 | // Combines multiple RegisteredCaches (i.e. SysNAND, UserNAND, SDMC) into one interface. | ||
| 143 | class RegisteredCacheUnion { | ||
| 144 | public: | ||
| 145 | explicit RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches); | ||
| 146 | |||
| 147 | void Refresh(); | ||
| 148 | |||
| 149 | bool HasEntry(u64 title_id, ContentRecordType type) const; | ||
| 150 | bool HasEntry(RegisteredCacheEntry entry) const; | ||
| 151 | |||
| 152 | boost::optional<u32> GetEntryVersion(u64 title_id) const; | ||
| 153 | |||
| 154 | VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; | ||
| 155 | VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; | ||
| 156 | |||
| 157 | VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const; | ||
| 158 | VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const; | ||
| 159 | |||
| 160 | std::shared_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const; | ||
| 161 | std::shared_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const; | ||
| 162 | |||
| 163 | std::vector<RegisteredCacheEntry> ListEntries() const; | ||
| 164 | // If a parameter is not boost::none, it will be filtered for from all entries. | ||
| 165 | std::vector<RegisteredCacheEntry> ListEntriesFilter( | ||
| 166 | boost::optional<TitleType> title_type = boost::none, | ||
| 167 | boost::optional<ContentRecordType> record_type = boost::none, | ||
| 168 | boost::optional<u64> title_id = boost::none) const; | ||
| 169 | |||
| 170 | private: | ||
| 171 | std::vector<std::shared_ptr<RegisteredCache>> caches; | ||
| 172 | }; | ||
| 173 | |||
| 134 | } // namespace FileSys | 174 | } // namespace FileSys |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index a4426af96..e9d5bd774 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/service/filesystem/fsp_ldr.h" | 19 | #include "core/hle/service/filesystem/fsp_ldr.h" |
| 20 | #include "core/hle/service/filesystem/fsp_pr.h" | 20 | #include "core/hle/service/filesystem/fsp_pr.h" |
| 21 | #include "core/hle/service/filesystem/fsp_srv.h" | 21 | #include "core/hle/service/filesystem/fsp_srv.h" |
| 22 | #include "filesystem.h" | ||
| 22 | 23 | ||
| 23 | namespace Service::FileSystem { | 24 | namespace Service::FileSystem { |
| 24 | 25 | ||
| @@ -307,6 +308,12 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { | |||
| 307 | return sdmc_factory->Open(); | 308 | return sdmc_factory->Open(); |
| 308 | } | 309 | } |
| 309 | 310 | ||
| 311 | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents() { | ||
| 312 | return std::make_shared<FileSys::RegisteredCacheUnion>( | ||
| 313 | std::vector<std::shared_ptr<FileSys::RegisteredCache>>{ | ||
| 314 | GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()}); | ||
| 315 | } | ||
| 316 | |||
| 310 | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() { | 317 | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() { |
| 311 | LOG_TRACE(Service_FS, "Opening System NAND Contents"); | 318 | LOG_TRACE(Service_FS, "Opening System NAND Contents"); |
| 312 | 319 | ||
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 9ba0e2eab..793a7b06f 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | class BISFactory; | 14 | class BISFactory; |
| 15 | class RegisteredCache; | 15 | class RegisteredCache; |
| 16 | class RegisteredCacheUnion; | ||
| 16 | class RomFSFactory; | 17 | class RomFSFactory; |
| 17 | class SaveDataFactory; | 18 | class SaveDataFactory; |
| 18 | class SDMCFactory; | 19 | class SDMCFactory; |
| @@ -45,6 +46,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, | |||
| 45 | FileSys::SaveDataDescriptor save_struct); | 46 | FileSys::SaveDataDescriptor save_struct); |
| 46 | ResultVal<FileSys::VirtualDir> OpenSDMC(); | 47 | ResultVal<FileSys::VirtualDir> OpenSDMC(); |
| 47 | 48 | ||
| 49 | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents(); | ||
| 50 | |||
| 48 | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); | 51 | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); |
| 49 | std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); | 52 | std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); |
| 50 | std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); | 53 | std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); |