impr: Make long running tasks not freeze ImHex, fix saving non-continuous providers
Fixes #1454
This commit is contained in:
parent
13145bba03
commit
760b8c7a88
@ -207,6 +207,9 @@ namespace hex {
|
||||
return 0;
|
||||
|
||||
auto task = this->m_task.lock();
|
||||
if (task->getMaxValue() == 0)
|
||||
return 0;
|
||||
|
||||
return u32((task->getValue() * 100) / task->getMaxValue());
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,14 @@
|
||||
|
||||
#include <hex/helpers/magic.hpp>
|
||||
#include <wolv/io/file.hpp>
|
||||
#include <wolv/literals.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
using namespace wolv::literals;
|
||||
|
||||
namespace {
|
||||
|
||||
u32 s_idCounter = 0;
|
||||
@ -53,21 +56,13 @@ namespace hex::prv {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
|
||||
if (file.isValid()) {
|
||||
std::vector<u8> buffer(std::min<size_t>(0xFF'FFFF, this->getActualSize()), 0x00);
|
||||
std::vector<u8> buffer(std::min<size_t>(2_MiB, this->getActualSize()), 0x00);
|
||||
size_t bufferSize = 0;
|
||||
|
||||
for (u64 offset = 0; offset < this->getActualSize(); offset += bufferSize) {
|
||||
bufferSize = buffer.size();
|
||||
bufferSize = std::min<size_t>(buffer.size(), this->getActualSize() - offset);
|
||||
|
||||
auto [region, valid] = this->getRegionValidity(offset + this->getBaseAddress());
|
||||
if (!valid)
|
||||
offset = region.getEndAddress() + 1;
|
||||
|
||||
auto [newRegion, newValid] = this->getRegionValidity(offset + this->getBaseAddress());
|
||||
bufferSize = std::min<size_t>(bufferSize, (newRegion.getEndAddress() - offset) + 1);
|
||||
bufferSize = std::min<size_t>(bufferSize, this->getActualSize() - offset);
|
||||
|
||||
this->read(offset + this->getBaseAddress(), buffer.data(), bufferSize, true);
|
||||
this->read(this->getBaseAddress() + offset, buffer.data(), bufferSize, true);
|
||||
file.writeBuffer(buffer.data(), bufferSize);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/ui/popup.hpp>
|
||||
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class PopupBlockingTask : public Popup<PopupBlockingTask> {
|
||||
public:
|
||||
PopupBlockingTask(TaskHolder &&task) : hex::Popup<PopupBlockingTask>("hex.builtin.popup.blocking_task.title", false), m_task(std::move(task)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGui::TextUnformatted("hex.builtin.popup.blocking_task.desc"_lang);
|
||||
ImGui::Separator();
|
||||
|
||||
if (this->m_task.getProgress() == 0)
|
||||
ImGuiExt::TextSpinner("");
|
||||
else
|
||||
ImGui::ProgressBar(this->m_task.getProgress() / 100.0F);
|
||||
|
||||
ImGui::NewLine();
|
||||
if (ImGui::ButtonEx("hex.builtin.common.cancel"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
this->m_task.interrupt();
|
||||
|
||||
if (!this->m_task.isRunning()) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
return ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove;
|
||||
}
|
||||
|
||||
private:
|
||||
TaskHolder m_task;
|
||||
};
|
||||
|
||||
}
|
@ -490,6 +490,8 @@
|
||||
"hex.builtin.popup.exit_application.desc": "You have unsaved changes made to your Project.\nAre you sure you want to exit?",
|
||||
"hex.builtin.popup.exit_application.title": "Exit Application?",
|
||||
"hex.builtin.popup.waiting_for_tasks.title": "Waiting for Tasks",
|
||||
"hex.builtin.popup.blocking_task.title": "Running Task",
|
||||
"hex.builtin.popup.blocking_task.desc": "A task is currently executing.",
|
||||
"hex.builtin.popup.save_layout.title": "Save Layout",
|
||||
"hex.builtin.popup.save_layout.desc": "Enter a name under which to save the current layout.",
|
||||
"hex.builtin.popup.waiting_for_tasks.desc": "There are still tasks running in the background.\nImHex will close after they are finished.",
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <content/popups/popup_file_chooser.hpp>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
#include <content/popups/popup_blocking_task.hpp>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
@ -692,7 +693,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
static void saveAs() {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
|
||||
ImHexApi::Provider::get()->saveAs(path);
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
PopupBlockingTask::open(TaskManager::createTask("Saving...", TaskManager::NoProgress, [=](Task &){
|
||||
provider->saveAs(path);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -759,8 +759,8 @@ namespace hex::plugin::builtin::ui {
|
||||
ImGuiExt::TextFormatted("{}:", "hex.builtin.hex_editor.data_size"_lang);
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::TextFormattedSelectable("0x{0:08X} (0x{1:X} | {2})",
|
||||
this->m_provider->getActualSize(),
|
||||
this->m_provider->getActualSize(),
|
||||
this->m_provider->getBaseAddress(),
|
||||
this->m_provider->getBaseAddress() + this->m_provider->getActualSize(),
|
||||
this->m_showHumanReadableUnits
|
||||
? hex::toByteString(this->m_provider->getActualSize())
|
||||
: hex::format("{}", this->m_provider->getActualSize())
|
||||
|
Loading…
x
Reference in New Issue
Block a user