mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	registration: Add RegisteredCacheUnion
Aggregates multiple caches into one interface
This commit is contained in:
		
							parent
							
								
									d2caf4af7d
								
							
						
					
					
						commit
						9951f6d054
					
				| @ -280,6 +280,14 @@ VirtualFile RegisteredCache::GetEntryUnparsed(RegisteredCacheEntry entry) const | |||||||
|     return GetEntryUnparsed(entry.title_id, entry.type); |     return GetEntryUnparsed(entry.title_id, entry.type); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const { | ||||||
|  |     if (meta.find(title_id) != meta.end()) | ||||||
|  |         return meta.at(title_id).GetTitleVersion(); | ||||||
|  |     if (yuzu_meta.find(title_id) != yuzu_meta.end()) | ||||||
|  |         return yuzu_meta.at(title_id).GetTitleVersion(); | ||||||
|  |     return boost::none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { | VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { | ||||||
|     const auto id = GetNcaIDFromMetadata(title_id, type); |     const auto id = GetNcaIDFromMetadata(title_id, type); | ||||||
|     if (id == boost::none) |     if (id == boost::none) | ||||||
| @ -498,4 +506,110 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) { | |||||||
|                                    kv.second.GetTitleID() == cnmt.GetTitleID(); |                                    kv.second.GetTitleID() == cnmt.GetTitleID(); | ||||||
|                         }) != yuzu_meta.end(); |                         }) != yuzu_meta.end(); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | RegisteredCacheUnion::RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches) | ||||||
|  |     : caches(std::move(caches)) {} | ||||||
|  | 
 | ||||||
|  | void RegisteredCacheUnion::Refresh() { | ||||||
|  |     for (const auto& c : caches) | ||||||
|  |         c->Refresh(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RegisteredCacheUnion::HasEntry(u64 title_id, ContentRecordType type) const { | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         if (c->HasEntry(title_id, type)) | ||||||
|  |             return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RegisteredCacheUnion::HasEntry(RegisteredCacheEntry entry) const { | ||||||
|  |     return HasEntry(entry.title_id, entry.type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | boost::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const { | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         const auto res = c->GetEntryVersion(title_id); | ||||||
|  |         if (res != boost::none) | ||||||
|  |             return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return boost::none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | VirtualFile RegisteredCacheUnion::GetEntryUnparsed(u64 title_id, ContentRecordType type) const { | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         const auto res = c->GetEntryUnparsed(title_id, type); | ||||||
|  |         if (res != nullptr) | ||||||
|  |             return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | VirtualFile RegisteredCacheUnion::GetEntryUnparsed(RegisteredCacheEntry entry) const { | ||||||
|  |     return GetEntryUnparsed(entry.title_id, entry.type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | VirtualFile RegisteredCacheUnion::GetEntryRaw(u64 title_id, ContentRecordType type) const { | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         const auto res = c->GetEntryRaw(title_id, type); | ||||||
|  |         if (res != nullptr) | ||||||
|  |             return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | VirtualFile RegisteredCacheUnion::GetEntryRaw(RegisteredCacheEntry entry) const { | ||||||
|  |     return GetEntryRaw(entry.title_id, entry.type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(u64 title_id, ContentRecordType type) const { | ||||||
|  |     const auto raw = GetEntryRaw(title_id, type); | ||||||
|  |     if (raw == nullptr) | ||||||
|  |         return nullptr; | ||||||
|  |     return std::make_shared<NCA>(raw); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(RegisteredCacheEntry entry) const { | ||||||
|  |     return GetEntry(entry.title_id, entry.type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntries() const { | ||||||
|  |     std::vector<RegisteredCacheEntry> out; | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         c->IterateAllMetadata<RegisteredCacheEntry>( | ||||||
|  |             out, | ||||||
|  |             [](const CNMT& c, const ContentRecord& r) { | ||||||
|  |                 return RegisteredCacheEntry{c.GetTitleID(), r.type}; | ||||||
|  |             }, | ||||||
|  |             [](const CNMT& c, const ContentRecord& r) { return true; }); | ||||||
|  |     } | ||||||
|  |     return out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter( | ||||||
|  |     boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type, | ||||||
|  |     boost::optional<u64> title_id) const { | ||||||
|  |     std::vector<RegisteredCacheEntry> out; | ||||||
|  |     for (const auto& c : caches) { | ||||||
|  |         c->IterateAllMetadata<RegisteredCacheEntry>( | ||||||
|  |             out, | ||||||
|  |             [](const CNMT& c, const ContentRecord& r) { | ||||||
|  |                 return RegisteredCacheEntry{c.GetTitleID(), r.type}; | ||||||
|  |             }, | ||||||
|  |             [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) { | ||||||
|  |                 if (title_type != boost::none && title_type.get() != c.GetType()) | ||||||
|  |                     return false; | ||||||
|  |                 if (record_type != boost::none && record_type.get() != r.type) | ||||||
|  |                     return false; | ||||||
|  |                 if (title_id != boost::none && title_id.get() != c.GetTitleID()) | ||||||
|  |                     return false; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  |     return out; | ||||||
|  | } | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
|  | |||||||
| @ -43,6 +43,10 @@ struct RegisteredCacheEntry { | |||||||
|     std::string DebugInfo() const; |     std::string DebugInfo() const; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | constexpr inline u64 GetUpdateTitleID(u64 base_title_id) { | ||||||
|  |     return base_title_id | 0x800; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // boost flat_map requires operator< for O(log(n)) lookups.
 | // boost flat_map requires operator< for O(log(n)) lookups.
 | ||||||
| bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); | bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); | ||||||
| 
 | 
 | ||||||
| @ -60,6 +64,8 @@ bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs) | |||||||
|  * 4GB splitting can be ignored.) |  * 4GB splitting can be ignored.) | ||||||
|  */ |  */ | ||||||
| class RegisteredCache { | class RegisteredCache { | ||||||
|  |     friend class RegisteredCacheUnion; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     // Parsing function defines the conversion from raw file to NCA. If there are other steps
 |     // Parsing function defines the conversion from raw file to NCA. If there are other steps
 | ||||||
|     // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom
 |     // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom
 | ||||||
| @ -74,6 +80,8 @@ public: | |||||||
|     bool HasEntry(u64 title_id, ContentRecordType type) const; |     bool HasEntry(u64 title_id, ContentRecordType type) const; | ||||||
|     bool HasEntry(RegisteredCacheEntry entry) const; |     bool HasEntry(RegisteredCacheEntry entry) const; | ||||||
| 
 | 
 | ||||||
|  |     boost::optional<u32> GetEntryVersion(u64 title_id) const; | ||||||
|  | 
 | ||||||
|     VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; |     VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; | ||||||
|     VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; |     VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; | ||||||
| 
 | 
 | ||||||
| @ -131,4 +139,36 @@ private: | |||||||
|     boost::container::flat_map<u64, CNMT> yuzu_meta; |     boost::container::flat_map<u64, CNMT> yuzu_meta; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // Combines multiple RegisteredCaches (i.e. SysNAND, UserNAND, SDMC) into one interface.
 | ||||||
|  | class RegisteredCacheUnion { | ||||||
|  | public: | ||||||
|  |     explicit RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches); | ||||||
|  | 
 | ||||||
|  |     void Refresh(); | ||||||
|  | 
 | ||||||
|  |     bool HasEntry(u64 title_id, ContentRecordType type) const; | ||||||
|  |     bool HasEntry(RegisteredCacheEntry entry) const; | ||||||
|  | 
 | ||||||
|  |     boost::optional<u32> GetEntryVersion(u64 title_id) const; | ||||||
|  | 
 | ||||||
|  |     VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; | ||||||
|  |     VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; | ||||||
|  | 
 | ||||||
|  |     VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const; | ||||||
|  |     VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const; | ||||||
|  | 
 | ||||||
|  |     std::shared_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const; | ||||||
|  |     std::shared_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const; | ||||||
|  | 
 | ||||||
|  |     std::vector<RegisteredCacheEntry> ListEntries() const; | ||||||
|  |     // If a parameter is not boost::none, it will be filtered for from all entries.
 | ||||||
|  |     std::vector<RegisteredCacheEntry> ListEntriesFilter( | ||||||
|  |         boost::optional<TitleType> title_type = boost::none, | ||||||
|  |         boost::optional<ContentRecordType> record_type = boost::none, | ||||||
|  |         boost::optional<u64> title_id = boost::none) const; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::vector<std::shared_ptr<RegisteredCache>> caches; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
| #include "core/hle/service/filesystem/fsp_ldr.h" | #include "core/hle/service/filesystem/fsp_ldr.h" | ||||||
| #include "core/hle/service/filesystem/fsp_pr.h" | #include "core/hle/service/filesystem/fsp_pr.h" | ||||||
| #include "core/hle/service/filesystem/fsp_srv.h" | #include "core/hle/service/filesystem/fsp_srv.h" | ||||||
|  | #include "filesystem.h" | ||||||
| 
 | 
 | ||||||
| namespace Service::FileSystem { | namespace Service::FileSystem { | ||||||
| 
 | 
 | ||||||
| @ -307,6 +308,12 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { | |||||||
|     return sdmc_factory->Open(); |     return sdmc_factory->Open(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents() { | ||||||
|  |     return std::make_shared<FileSys::RegisteredCacheUnion>( | ||||||
|  |         std::vector<std::shared_ptr<FileSys::RegisteredCache>>{ | ||||||
|  |             GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() { | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() { | ||||||
|     LOG_TRACE(Service_FS, "Opening System NAND Contents"); |     LOG_TRACE(Service_FS, "Opening System NAND Contents"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ | |||||||
| namespace FileSys { | namespace FileSys { | ||||||
| class BISFactory; | class BISFactory; | ||||||
| class RegisteredCache; | class RegisteredCache; | ||||||
|  | class RegisteredCacheUnion; | ||||||
| class RomFSFactory; | class RomFSFactory; | ||||||
| class SaveDataFactory; | class SaveDataFactory; | ||||||
| class SDMCFactory; | class SDMCFactory; | ||||||
| @ -45,6 +46,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, | |||||||
|                                             FileSys::SaveDataDescriptor save_struct); |                                             FileSys::SaveDataDescriptor save_struct); | ||||||
| ResultVal<FileSys::VirtualDir> OpenSDMC(); | ResultVal<FileSys::VirtualDir> OpenSDMC(); | ||||||
| 
 | 
 | ||||||
|  | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents(); | ||||||
|  | 
 | ||||||
| std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); | std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); | ||||||
| std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); | std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); | ||||||
| std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); | std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zach Hilman
						Zach Hilman