Merge pull request #11607 from AdmiralCurtiss/sd-progress

Qt/WiiPane: Add progress window for SD card conversion.
This commit is contained in:
Mai 2023-03-02 15:08:18 -05:00 committed by GitHub
commit ab2f8d3475
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 19 deletions

View File

@ -191,12 +191,12 @@ Java_org_dolphinemu_dolphinemu_utils_WiiUtils_getSystemMenuVersion(JNIEnv* env,
JNIEXPORT jboolean JNICALL
Java_org_dolphinemu_dolphinemu_utils_WiiUtils_syncSdFolderToSdImage(JNIEnv* env, jclass)
{
return static_cast<jboolean>(Common::SyncSDFolderToSDImage(false));
return static_cast<jboolean>(Common::SyncSDFolderToSDImage([]() { return false; }, false));
}
JNIEXPORT jboolean JNICALL
Java_org_dolphinemu_dolphinemu_utils_WiiUtils_syncSdImageToSdFolder(JNIEnv* env, jclass)
{
return static_cast<jboolean>(Common::SyncSDImageToSDFolder());
return static_cast<jboolean>(Common::SyncSDImageToSDFolder([]() { return false; }));
}
}

View File

@ -353,8 +353,12 @@ static u64 GetSize(const File::FSTEntry& entry)
return size;
}
static bool Pack(const File::FSTEntry& entry, bool is_root, std::vector<u8>& tmp_buffer)
static bool Pack(const std::function<bool()>& cancelled, const File::FSTEntry& entry, bool is_root,
std::vector<u8>& tmp_buffer)
{
if (cancelled())
return false;
if (!entry.isDirectory)
{
File::IOFile src(entry.physicalName, "rb");
@ -392,6 +396,9 @@ static bool Pack(const File::FSTEntry& entry, bool is_root, std::vector<u8>& tmp
u64 size = entry.size;
while (size > 0)
{
if (cancelled())
return false;
u32 chunk_size = static_cast<u32>(std::min(size, static_cast<u64>(tmp_buffer.size())));
if (!src.ReadBytes(tmp_buffer.data(), chunk_size))
{
@ -456,7 +463,7 @@ static bool Pack(const File::FSTEntry& entry, bool is_root, std::vector<u8>& tmp
for (const File::FSTEntry& child : entry.children)
{
if (!Pack(child, false, tmp_buffer))
if (!Pack(cancelled, child, false, tmp_buffer))
return false;
}
@ -484,7 +491,7 @@ static void SortFST(File::FSTEntry* root)
SortFST(&child);
}
bool SyncSDFolderToSDImage(bool deterministic)
bool SyncSDFolderToSDImage(const std::function<bool()>& cancelled, bool deterministic)
{
const std::string source_dir = File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX);
const std::string image_path = File::GetUserPath(F_WIISDCARDIMAGE_IDX);
@ -528,7 +535,10 @@ bool SyncSDFolderToSDImage(bool deterministic)
}
// delete temp file in failure case
Common::ScopeGuard image_delete_guard{[&] { File::Delete(temp_image_path); }};
Common::ScopeGuard image_delete_guard{[&] {
image.Close();
File::Delete(temp_image_path);
}};
if (!image.Resize(size))
{
@ -563,7 +573,7 @@ bool SyncSDFolderToSDImage(bool deterministic)
}
Common::ScopeGuard unmount_guard{[] { f_unmount(""); }};
if (!Pack(root, true, tmp_buffer))
if (!Pack(cancelled, root, true, tmp_buffer))
{
ERROR_LOG_FMT(COMMON, "Failed to pack folder {} to SD image at {}", source_dir,
temp_image_path);
@ -590,9 +600,12 @@ bool SyncSDFolderToSDImage(bool deterministic)
return true;
}
static bool Unpack(const std::string path, bool is_directory, const char* name,
std::vector<u8>& tmp_buffer)
static bool Unpack(const std::function<bool()>& cancelled, const std::string path,
bool is_directory, const char* name, std::vector<u8>& tmp_buffer)
{
if (cancelled())
return false;
if (!is_directory)
{
FIL src{};
@ -614,6 +627,9 @@ static bool Unpack(const std::string path, bool is_directory, const char* name,
u32 size = f_size(&src);
while (size > 0)
{
if (cancelled())
return false;
u32 chunk_size = std::min(size, static_cast<u32>(tmp_buffer.size()));
u32 read_size;
const auto read_error_code = f_read(&src, tmp_buffer.data(), chunk_size, &read_size);
@ -717,8 +733,8 @@ static bool Unpack(const std::string path, bool is_directory, const char* name,
return false;
}
if (!Unpack(fmt::format("{}/{}", path, childname), entry.fattrib & AM_DIR, entry.fname,
tmp_buffer))
if (!Unpack(cancelled, fmt::format("{}/{}", path, childname), entry.fattrib & AM_DIR,
entry.fname, tmp_buffer))
{
return false;
}
@ -743,7 +759,7 @@ static bool Unpack(const std::string path, bool is_directory, const char* name,
return true;
}
bool SyncSDImageToSDFolder()
bool SyncSDImageToSDFolder(const std::function<bool()>& cancelled)
{
const std::string image_path = File::GetUserPath(F_WIISDCARDIMAGE_IDX);
const std::string target_dir = File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX);
@ -800,7 +816,7 @@ bool SyncSDImageToSDFolder()
}
std::vector<u8> tmp_buffer(MAX_CLUSTER_SIZE);
if (!Unpack(target_dir_without_slash, true, "", tmp_buffer))
if (!Unpack(cancelled, target_dir_without_slash, true, "", tmp_buffer))
{
ERROR_LOG_FMT(COMMON, "Failed to unpack SD image {} to {}", image_path, target_dir);
File::DeleteDirRecursively(target_dir_without_slash);

View File

@ -9,8 +9,8 @@
namespace Common
{
bool SyncSDFolderToSDImage(bool deterministic);
bool SyncSDImageToSDFolder();
bool SyncSDFolderToSDImage(const std::function<bool()>& cancelled, bool deterministic);
bool SyncSDImageToSDFolder(const std::function<bool()>& cancelled);
class FatFsCallbacks
{

View File

@ -503,11 +503,14 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
bool sync_sd_folder = core_parameter.bWii && Config::Get(Config::MAIN_WII_SD_CARD) &&
Config::Get(Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC);
if (sync_sd_folder)
sync_sd_folder = Common::SyncSDFolderToSDImage(Core::WantsDeterminism());
{
sync_sd_folder =
Common::SyncSDFolderToSDImage([]() { return false; }, Core::WantsDeterminism());
}
Common::ScopeGuard sd_folder_sync_guard{[sync_sd_folder] {
if (sync_sd_folder && Config::Get(Config::MAIN_ALLOW_SD_WRITES))
Common::SyncSDImageToSDFolder();
Common::SyncSDImageToSDFolder([]() { return false; });
}};
// Load Wiimotes - only if we are booting in Wii mode

View File

@ -3,6 +3,8 @@
#include "DolphinQt/Settings/WiiPane.h"
#include <future>
#include <QCheckBox>
#include <QComboBox>
#include <QDir>
@ -30,6 +32,7 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
@ -228,7 +231,17 @@ void WiiPane::CreateSDCard()
QMessageBox::Yes | QMessageBox::No);
if (result == QMessageBox::Yes)
{
if (!Common::SyncSDFolderToSDImage(false))
ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Cancel"), 0, 0, this);
progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));
auto success = std::async(std::launch::async, [&] {
const bool good = Common::SyncSDFolderToSDImage(
[&progress_dialog]() { return progress_dialog.WasCanceled(); }, false);
progress_dialog.Reset();
return good;
});
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr("Convert Folder to File Now"), tr("Conversion failed."));
}
});
@ -242,7 +255,17 @@ void WiiPane::CreateSDCard()
QMessageBox::Yes | QMessageBox::No);
if (result == QMessageBox::Yes)
{
if (!Common::SyncSDImageToSDFolder())
ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Cancel"), 0, 0, this);
progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));
auto success = std::async(std::launch::async, [&] {
const bool good = Common::SyncSDImageToSDFolder(
[&progress_dialog]() { return progress_dialog.WasCanceled(); });
progress_dialog.Reset();
return good;
});
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr("Convert File to Folder Now"), tr("Conversion failed."));
}
});