DiscIO: Use Common::Lazy for loading filesystems

This simplifies FileMonitor a lot and also lets us
clean up FilesystemPanel.
This commit is contained in:
JosJuice
2017-08-02 18:16:56 +02:00
parent 0d07821935
commit 38304da947
21 changed files with 182 additions and 172 deletions

View File

@ -116,7 +116,6 @@ void Stop()
{
StopDVDThread();
s_disc.reset();
FileMonitor::SetFileSystem(nullptr);
}
static void StopDVDThread()
@ -160,14 +159,9 @@ void DoState(PointerWrap& p)
if (had_disc != HasDisc())
{
if (had_disc)
{
PanicAlertT("An inserted disc was expected but not found.");
}
else
{
s_disc.reset();
FileMonitor::SetFileSystem(nullptr);
}
}
// TODO: Savestates can be smaller if the buffers of results aren't saved,
@ -185,7 +179,6 @@ void SetDisc(std::unique_ptr<DiscIO::Volume> disc)
{
WaitUntilIdle();
s_disc = std::move(disc);
FileMonitor::SetFileSystem(s_disc.get());
}
bool HasDisc()
@ -356,7 +349,7 @@ static void DVDThread()
ReadRequest request;
while (s_request_queue.Pop(request))
{
FileMonitor::Log(request.dvd_offset, request.partition);
FileMonitor::Log(*s_disc, request.partition, request.dvd_offset);
std::vector<u8> buffer(request.length);
if (!s_disc->Read(request.dvd_offset, request.length, buffer.data(), request.partition))

View File

@ -21,10 +21,7 @@
namespace FileMonitor
{
static const DiscIO::Volume* s_volume;
static bool s_new_volume = false;
static std::unique_ptr<DiscIO::FileSystem> s_filesystem;
static DiscIO::Partition s_partition;
static DiscIO::Partition s_previous_partition;
static std::string s_previous_file;
// Filtered files
@ -53,42 +50,19 @@ static bool IsSoundFile(const std::string& filename)
return extensions.find(extension) != extensions.end();
}
void SetFileSystem(const DiscIO::Volume* volume)
{
// Instead of creating the file system object right away, we will let Log
// create it later once we know that it actually will get used
s_volume = volume;
s_new_volume = true;
}
// Logs access to files in the file system set by SetFileSystem
void Log(u64 offset, const DiscIO::Partition& partition)
void Log(const DiscIO::Volume& volume, const DiscIO::Partition& partition, u64 offset)
{
// Do nothing if the log isn't selected
if (!LogManager::GetInstance()->IsEnabled(LogTypes::FILEMON, LogTypes::LWARNING))
return;
// If the volume or partition changed, load the filesystem of the new partition
if (s_new_volume || s_partition != partition)
{
// Discs with partitions don't have PARTITION_NONE filesystems,
// so let's not waste time trying to read one
const bool reading_from_partition = partition != DiscIO::PARTITION_NONE;
const bool disc_has_partitions = !s_volume->GetPartitions().empty();
if (reading_from_partition != disc_has_partitions)
return;
s_new_volume = false;
s_filesystem = DiscIO::CreateFileSystem(s_volume, partition);
s_partition = partition;
s_previous_file.clear();
}
const DiscIO::FileSystem* file_system = volume.GetFileSystem(partition);
// Do nothing if there is no valid file system
if (!s_filesystem)
if (!file_system)
return;
const std::unique_ptr<DiscIO::FileInfo> file_info = s_filesystem->FindFileInfo(offset);
const std::unique_ptr<DiscIO::FileInfo> file_info = file_system->FindFileInfo(offset);
// Do nothing if no file was found at that offset
if (!file_info)
@ -97,7 +71,7 @@ void Log(u64 offset, const DiscIO::Partition& partition)
const std::string path = file_info->GetPath();
// Do nothing if we found the same file again
if (s_previous_file == path)
if (s_previous_partition == partition && s_previous_file == path)
return;
const std::string size_string = ThousandSeparate(file_info->GetSize() / 1000, 7);
@ -109,6 +83,7 @@ void Log(u64 offset, const DiscIO::Partition& partition)
WARN_LOG(FILEMON, "%s", log_string.c_str());
// Update the last accessed file
s_previous_partition = partition;
s_previous_file = path;
}

View File

@ -14,9 +14,5 @@ class Volume;
namespace FileMonitor
{
// Can be called with nullptr to set the file system to nothing. When not called
// with nullptr, the volume must remain valid until the next SetFileSystem call.
void SetFileSystem(const DiscIO::Volume* volume);
// Logs access to files in the file system set by SetFileSystem
void Log(u64 offset, const DiscIO::Partition& partition);
void Log(const DiscIO::Volume& volume, const DiscIO::Partition& partition, u64 offset);
}

View File

@ -552,7 +552,7 @@ private:
UpdateCallback m_update_callback;
std::unique_ptr<DiscIO::Volume> m_volume;
std::unique_ptr<DiscIO::FileSystem> m_disc_fs;
DiscIO::Partition m_partition;
};
UpdateResult DiscSystemUpdater::DoDiscUpdate()
@ -578,16 +578,21 @@ UpdateResult DiscSystemUpdater::DoDiscUpdate()
return UpdateResult::MissingUpdatePartition;
}
m_disc_fs = DiscIO::CreateFileSystem(m_volume.get(), *update_partition);
if (!m_disc_fs || !m_disc_fs->IsValid())
return UpdateResult::DiscReadFailed;
m_partition = *update_partition;
return UpdateFromManifest("__update.inf");
}
UpdateResult DiscSystemUpdater::UpdateFromManifest(const std::string& manifest_name)
{
const std::unique_ptr<DiscIO::FileInfo> update_manifest = m_disc_fs->FindFileInfo(manifest_name);
const DiscIO::FileSystem* disc_fs = m_volume->GetFileSystem(m_partition);
if (!disc_fs)
{
ERROR_LOG(CORE, "Could not read the update partition file system");
return UpdateResult::DiscReadFailed;
}
const std::unique_ptr<DiscIO::FileInfo> update_manifest = disc_fs->FindFileInfo(manifest_name);
if (!update_manifest ||
(update_manifest->GetSize() - sizeof(ManifestHeader)) % sizeof(Entry) != 0)
{
@ -604,8 +609,8 @@ UpdateResult DiscSystemUpdater::UpdateFromManifest(const std::string& manifest_n
for (u32 i = 0; i < num_entries; ++i)
{
const u32 offset = sizeof(ManifestHeader) + sizeof(Entry) * i;
if (entry.size() != DiscIO::ReadFile(*m_volume, m_disc_fs->GetPartition(),
update_manifest.get(), entry.data(), entry.size(), offset))
if (entry.size() != DiscIO::ReadFile(*m_volume, m_partition, update_manifest.get(),
entry.data(), entry.size(), offset))
{
ERROR_LOG(CORE, "Failed to read update information from update manifest");
return UpdateResult::DiscReadFailed;
@ -654,14 +659,13 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
return UpdateResult::AlreadyUpToDate;
// Import the WAD.
const std::unique_ptr<DiscIO::FileInfo> wad_file = m_disc_fs->FindFileInfo(path);
if (!wad_file)
auto blob = DiscIO::VolumeFileBlobReader::Create(*m_volume, m_partition, path);
if (!blob)
{
ERROR_LOG(CORE, "Failed to get info for %s", path.c_str());
ERROR_LOG(CORE, "Could not find %s", path.c_str());
return UpdateResult::DiscReadFailed;
}
const DiscIO::WiiWAD wad{DiscIO::VolumeFileBlobReader::Create(*m_volume, *m_disc_fs, path)};
const DiscIO::WiiWAD wad{std::move(blob)};
return InstallWAD(m_ios, wad) ? UpdateResult::Succeeded : UpdateResult::ImportFailed;
}