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); | ||||
| } | ||||
| 
 | ||||
| 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 { | ||||
|     const auto id = GetNcaIDFromMetadata(title_id, type); | ||||
|     if (id == boost::none) | ||||
| @ -498,4 +506,110 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) { | ||||
|                                    kv.second.GetTitleID() == cnmt.GetTitleID(); | ||||
|                         }) != 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
 | ||||
|  | ||||
| @ -43,6 +43,10 @@ struct RegisteredCacheEntry { | ||||
|     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.
 | ||||
| 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.) | ||||
|  */ | ||||
| class RegisteredCache { | ||||
|     friend class RegisteredCacheUnion; | ||||
| 
 | ||||
| public: | ||||
|     // 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
 | ||||
| @ -74,6 +80,8 @@ public: | ||||
|     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; | ||||
| 
 | ||||
| @ -131,4 +139,36 @@ private: | ||||
|     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
 | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| #include "core/hle/service/filesystem/fsp_ldr.h" | ||||
| #include "core/hle/service/filesystem/fsp_pr.h" | ||||
| #include "core/hle/service/filesystem/fsp_srv.h" | ||||
| #include "filesystem.h" | ||||
| 
 | ||||
| namespace Service::FileSystem { | ||||
| 
 | ||||
| @ -307,6 +308,12 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { | ||||
|     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() { | ||||
|     LOG_TRACE(Service_FS, "Opening System NAND Contents"); | ||||
| 
 | ||||
|  | ||||
| @ -13,6 +13,7 @@ | ||||
| namespace FileSys { | ||||
| class BISFactory; | ||||
| class RegisteredCache; | ||||
| class RegisteredCacheUnion; | ||||
| class RomFSFactory; | ||||
| class SaveDataFactory; | ||||
| class SDMCFactory; | ||||
| @ -45,6 +46,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, | ||||
|                                             FileSys::SaveDataDescriptor save_struct); | ||||
| ResultVal<FileSys::VirtualDir> OpenSDMC(); | ||||
| 
 | ||||
| std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents(); | ||||
| 
 | ||||
| std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents(); | ||||
| std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents(); | ||||
| std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zach Hilman
						Zach Hilman