summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Dubé <serprex@users.noreply.github.com>2026-03-22 06:03:41 +0000
committerGitHub <noreply@github.com>2026-03-22 06:03:41 +0000
commit96c4fef05c1dc4c093e83b2e5e2acf02092e5d9f (patch)
tree9625354c03ef0b11906711ac49e5d3c8bc462e71
parentb65c1c83172ec57040ba3240617ea1c7ead142bf (diff)
extraction: detect task crashing (#6386)
-rw-r--r--soh/soh/OTRGlobals.cpp77
1 files changed, 40 insertions, 37 deletions
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index f1d010414..7cd67c266 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -6,6 +6,7 @@
#include <fstream>
#include <vector>
#include <chrono>
+#include <optional>
#include "ResourceManagerHelpers.h"
#include <fast/Fast3dWindow.h>
@@ -408,7 +409,6 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
Extractor extract;
PromptSteps promptStep = PS_FILE_CHECK;
bool generatedIsMQ = false;
- std::atomic<bool> extracting = false;
std::atomic<size_t> extractCount = 0, totalExtract = 0;
std::string installPath = Ship::Context::GetAppBundlePath();
@@ -444,8 +444,9 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
}
std::shared_ptr<BS::thread_pool> threadPool = std::make_shared<BS::thread_pool>(1);
+ std::optional<std::future<void>> extractionTask;
while (!extractDone) {
- if (SohGui::PopupsQueued() > 0 || extracting) {
+ if (SohGui::PopupsQueued() > 0 || extractionTask.has_value()) {
goto render;
}
switch (extractStep) {
@@ -582,20 +583,16 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
if (std::filesystem::exists(Ship::Context::GetAppDirectoryPath(appShortName) + "/" + archive)) {
std::string msg = "Archive for current ROM, " + archive + ", already exists.\nExtract again?";
SohGui::RegisterPopup("Confirm Re-extract", msg.c_str(), "Yes", "No", [&]() {
- extracting = true;
- threadPool->submit_task([&]() -> void {
+ extractionTask = threadPool->submit_task([&]() -> void {
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
&extractCount, &totalExtract);
- extracting = false;
extractCount = totalExtract = 0;
});
});
} else {
- extracting = true;
- threadPool->submit_task([&]() -> void {
+ extractionTask = threadPool->submit_task([&]() -> void {
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
&extractCount, &totalExtract);
- extracting = false;
extractCount = totalExtract = 0;
});
}
@@ -648,12 +645,10 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
promptStep = PS_FILE_CHECK;
continue;
}
- extracting = true;
- threadPool->submit_task([&]() -> void {
+ extractionTask = threadPool->submit_task([&]() -> void {
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
&extractCount, &totalExtract);
generatedIsMQ = extract.IsMasterQuest();
- extracting = false;
promptStep = PS_SECOND;
extractCount = 0;
totalExtract = 0;
@@ -668,11 +663,9 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
: RomSearchMode::MQ)) {
extractStep = ES_VERIFY;
} else {
- extracting = true;
- threadPool->submit_task([&]() -> void {
+ extractionTask = threadPool->submit_task([&]() -> void {
extract.CallZapd(installPath, Ship::Context::GetAppDirectoryPath(appShortName),
&extractCount, &totalExtract);
- extracting = false;
extractStep = ES_VERIFY;
extractCount = 0;
totalExtract = 0;
@@ -722,30 +715,40 @@ void OTRGlobals::RunExtract(int argc, char* argv[]) {
gui->StartDraw();
sohFast3dWindow->StartFrame();
sohFast3dWindow->RunGuiOnly();
- if (extracting && !ImGui::IsPopupOpen("ROM Extraction")) {
- ImGui::OpenPopup("ROM Extraction");
- }
- if (extracting) {
- ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
- auto color = UIWidgets::ColorValues.at(THEME_COLOR);
- ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 0.6f));
- ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(color.x, color.y, color.z, 1.0f));
- ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
- if (ImGui::BeginPopupModal("ROM Extraction", NULL,
- ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
- ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
- ImGuiWindowFlags_NoSavedSettings)) {
- float progress = (totalExtract > 0.0f ? (float)extractCount / (float)totalExtract : 0) * 100.0f;
- auto filename = std::filesystem::path(file).filename().string();
- ImGui::Text("Extracting %s...%s", filename.c_str(),
- roundf(progress) == 100.0f ? " Done. Finishing up." : "");
- std::string overlay = extractCount > 0 ? fmt::format("{:.0f}%", progress) : "Starting Up";
- ImGui::ProgressBar(progress / 100.0f, ImVec2(600.0f, 50.0f), overlay.c_str());
- ImGui::EndPopup();
+ if (extractionTask.has_value()) {
+ auto status = extractionTask->wait_for(std::chrono::milliseconds(0));
+ if (status == std::future_status::ready) {
+ try {
+ extractionTask->get();
+ } catch (const std::exception& e) {
+ SohGui::RegisterPopup("Extraction Crashed", e.what(), "Close", "", []() { exit(1); });
+ }
+ extractionTask.reset();
+ } else {
+ if (!ImGui::IsPopupOpen("ROM Extraction")) {
+ ImGui::OpenPopup("ROM Extraction");
+ }
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
+ auto color = UIWidgets::ColorValues.at(THEME_COLOR);
+ ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 0.6f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(color.x, color.y, color.z, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
+ if (ImGui::BeginPopupModal("ROM Extraction", NULL,
+ ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
+ ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
+ ImGuiWindowFlags_NoSavedSettings)) {
+ float progress = (totalExtract > 0.0f ? (float)extractCount / (float)totalExtract : 0) * 100.0f;
+ auto filename = std::filesystem::path(file).filename().string();
+ ImGui::Text("Extracting %s...%s", filename.c_str(),
+ roundf(progress) == 100.0f ? " Done. Finishing up." : "");
+ std::string overlay = extractCount > 0 ? fmt::format("{:.0f}%", progress) : "Starting Up";
+ ImGui::ProgressBar(progress / 100.0f, ImVec2(600.0f, 50.0f), overlay.c_str());
+ ImGui::EndPopup();
+ }
+ ImGui::PopStyleColor(3);
+ ImGui::PopStyleVar(2);
}
- ImGui::PopStyleColor(3);
- ImGui::PopStyleVar(2);
}
gui->EndDraw();
sohFast3dWindow->EndFrame();