summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-25 19:00:36 -0400
committerGravatar Zach Hilman2018-09-04 16:21:40 -0400
commit9951f6d0543980e29e6107e0bd4ea35977f1cf29 (patch)
tree2ee34991b03ab10607d41c90588a52a0476ddfc6 /src/core
parentgame_list: Use RegisteredCacheUnion for installed (diff)
downloadyuzu-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.cpp114
-rw-r--r--src/core/file_sys/registered_cache.h40
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp7
-rw-r--r--src/core/hle/service/filesystem/filesystem.h3
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
283boost::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
283VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { 291VirtualFile 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
510RegisteredCacheUnion::RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches)
511 : caches(std::move(caches)) {}
512
513void RegisteredCacheUnion::Refresh() {
514 for (const auto& c : caches)
515 c->Refresh();
516}
517
518bool 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
527bool RegisteredCacheUnion::HasEntry(RegisteredCacheEntry entry) const {
528 return HasEntry(entry.title_id, entry.type);
529}
530
531boost::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
541VirtualFile 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
551VirtualFile RegisteredCacheUnion::GetEntryUnparsed(RegisteredCacheEntry entry) const {
552 return GetEntryUnparsed(entry.title_id, entry.type);
553}
554
555VirtualFile 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
565VirtualFile RegisteredCacheUnion::GetEntryRaw(RegisteredCacheEntry entry) const {
566 return GetEntryRaw(entry.title_id, entry.type);
567}
568
569std::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
576std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(RegisteredCacheEntry entry) const {
577 return GetEntry(entry.title_id, entry.type);
578}
579
580std::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
593std::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
46constexpr 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.
47bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); 51bool 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 */
62class RegisteredCache { 66class RegisteredCache {
67 friend class RegisteredCacheUnion;
68
63public: 69public:
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.
143class RegisteredCacheUnion {
144public:
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
170private:
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
23namespace Service::FileSystem { 24namespace 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
311std::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
310std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() { 317std::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 @@
13namespace FileSys { 13namespace FileSys {
14class BISFactory; 14class BISFactory;
15class RegisteredCache; 15class RegisteredCache;
16class RegisteredCacheUnion;
16class RomFSFactory; 17class RomFSFactory;
17class SaveDataFactory; 18class SaveDataFactory;
18class SDMCFactory; 19class SDMCFactory;
@@ -45,6 +46,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
45 FileSys::SaveDataDescriptor save_struct); 46 FileSys::SaveDataDescriptor save_struct);
46ResultVal<FileSys::VirtualDir> OpenSDMC(); 47ResultVal<FileSys::VirtualDir> OpenSDMC();
47 48
49std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents();
50
48std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); 51std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents();
49std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); 52std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents();
50std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); 53std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents();