From d86b70e0063743a9b7107e4712f7456594405e7b Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Sat, 11 Oct 2025 18:56:11 +0100 Subject: [PATCH] feat: unlink fastfiles via ModMan --- src/ModMan/Web/Binds/Binds.cpp | 2 + src/ModMan/Web/Binds/UnlinkingBinds.cpp | 93 +++++++++++++++++++++++ src/ModMan/Web/Binds/UnlinkingBinds.h | 8 ++ src/ModMan/Web/Binds/ZoneBinds.cpp | 7 +- src/ModManUi/src/App.vue | 69 ++++++++++++++--- src/ModManUi/src/native/UnlinkingBinds.ts | 3 + src/ModManUi/src/native/ZoneBinds.ts | 2 +- src/ModManUi/src/native/index.ts | 3 +- 8 files changed, 174 insertions(+), 13 deletions(-) create mode 100644 src/ModMan/Web/Binds/UnlinkingBinds.cpp create mode 100644 src/ModMan/Web/Binds/UnlinkingBinds.h create mode 100644 src/ModManUi/src/native/UnlinkingBinds.ts diff --git a/src/ModMan/Web/Binds/Binds.cpp b/src/ModMan/Web/Binds/Binds.cpp index 94bd2ec5..7ae5ab9c 100644 --- a/src/ModMan/Web/Binds/Binds.cpp +++ b/src/ModMan/Web/Binds/Binds.cpp @@ -1,5 +1,6 @@ #include "Binds.h" +#include "UnlinkingBinds.h" #include "Web/Binds/DialogBinds.h" #include "ZoneBinds.h" @@ -8,6 +9,7 @@ namespace ui void RegisterAllBinds(webview::webview& wv) { RegisterDialogHandlerBinds(wv); + RegisterUnlinkingBinds(wv); RegisterZoneBinds(wv); } } // namespace ui diff --git a/src/ModMan/Web/Binds/UnlinkingBinds.cpp b/src/ModMan/Web/Binds/UnlinkingBinds.cpp new file mode 100644 index 00000000..bc281dcf --- /dev/null +++ b/src/ModMan/Web/Binds/UnlinkingBinds.cpp @@ -0,0 +1,93 @@ +#include "UnlinkingBinds.h" + +#include "Context/ModManContext.h" +#include "IObjWriter.h" +#include "SearchPath/OutputPathFilesystem.h" +#include "SearchPath/SearchPaths.h" +#include "Utils/PathUtils.h" +#include "Web/UiCommunication.h" + +#include "Json/JsonExtension.h" +#include + +namespace fs = std::filesystem; + +namespace +{ + class ZoneLoadedDto + { + public: + std::string zoneName; + std::string filePath; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadedDto, zoneName, filePath); + + class ZoneUnloadedDto + { + public: + std::string zoneName; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnloadedDto, zoneName); + + result::Expected UnlinkZoneInDbThread(const std::string& zoneName) + { + const auto& context = ModManContext::Get().m_fast_file; + const auto existingZone = std::ranges::find_if(context.m_loaded_zones, + [&zoneName](const std::unique_ptr& zone) + { + return zone->m_name == zoneName; + }); + + if (existingZone == context.m_loaded_zones.end()) + return result::Unexpected(std::format("No zone with name {} loaded", zoneName)); + + const auto& zone = *existingZone->get(); + + const auto* objWriter = IObjWriter::GetObjWriterForGame(zone.m_game_id); + + const auto outputFolderPath = fs::path(utils::GetExecutablePath()).parent_path() / "zone_dump" / zoneName; + const auto outputFolderPathStr = outputFolderPath.string(); + + OutputPathFilesystem outputFolderOutputPath(outputFolderPath); + SearchPaths searchPaths; + AssetDumpingContext dumpingContext(zone, outputFolderPathStr, outputFolderOutputPath, searchPaths); + objWriter->DumpZone(dumpingContext); + + return NoResult(); + } + + void UnlinkZone(webview::webview& wv, std::string id, std::string zoneName) // NOLINT(performance-unnecessary-value-param) Copy is made for thread safety + { + ModManContext::Get().m_db_thread.Dispatch( + [&wv, id, zoneName] + { + auto result = UnlinkZoneInDbThread(zoneName); + + if (result) + { + con::debug("Unlinked zone \"{}\"", zoneName); + ui::PromiseResolve(wv, id, true); + } + else + { + con::warn("Failed to unlink zone \"{}\": {}", zoneName, result.error()); + ui::PromiseReject(wv, id, std::move(result).error()); + } + }); + } +} // namespace + +namespace ui +{ + void RegisterUnlinkingBinds(webview::webview& wv) + { + BindAsync(wv, + "unlinkZone", + [&wv](const std::string& id, std::string zoneName) + { + UnlinkZone(wv, id, std::move(zoneName)); + }); + } +} // namespace ui diff --git a/src/ModMan/Web/Binds/UnlinkingBinds.h b/src/ModMan/Web/Binds/UnlinkingBinds.h new file mode 100644 index 00000000..4169a780 --- /dev/null +++ b/src/ModMan/Web/Binds/UnlinkingBinds.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Web/WebViewLib.h" + +namespace ui +{ + void RegisterUnlinkingBinds(webview::webview& wv); +} // namespace ui diff --git a/src/ModMan/Web/Binds/ZoneBinds.cpp b/src/ModMan/Web/Binds/ZoneBinds.cpp index 4291a1d1..8882a7d0 100644 --- a/src/ModMan/Web/Binds/ZoneBinds.cpp +++ b/src/ModMan/Web/Binds/ZoneBinds.cpp @@ -33,7 +33,12 @@ namespace if (maybeZone) { - ui::PromiseResolve(wv, id, true); + ui::PromiseResolve(wv, + id, + ZoneLoadedDto{ + .zoneName = maybeZone.value()->m_name, + .filePath = path, + }); con::debug("Loaded zone \"{}\"", maybeZone.value()->m_name); } else diff --git a/src/ModManUi/src/App.vue b/src/ModManUi/src/App.vue index 0da45521..8c4a4dc1 100644 --- a/src/ModManUi/src/App.vue +++ b/src/ModManUi/src/App.vue @@ -1,21 +1,29 @@