diff --git a/CMakeLists.txt b/CMakeLists.txt index 66f0c4a..cc69a2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ include(CMakeDependentOption) cmake_dependent_option(SAVETOOL_USE_SYSTEM_CORRADE_MAGNUM "Use system-wide versions of Corrade and Magnum." ON "SAVETOOL_USE_SYSTEM_LIBS" OFF) cmake_dependent_option(SAVETOOL_USE_SYSTEM_SDL2 "Use a system-wide version of SDL2." ON "SAVETOOL_USE_SYSTEM_LIBS" OFF) cmake_dependent_option(SAVETOOL_USE_SYSTEM_LIBZIP "Use a system-wide version of libzip." ON "SAVETOOL_USE_SYSTEM_LIBS" OFF) -cmake_dependent_option(SAVETOOL_USE_SYSTEM_EFSW "Use a system-wide version of EFSW." ON "SAVETOOL_USE_SYSTEM_LIBS" OFF) cmake_dependent_option(SAVETOOL_USE_SYSTEM_LIBCURL "Use a system-wide version of libcurl." ON "SAVETOOL_USE_SYSTEM_LIBS" OFF) if(NOT SAVETOOL_USE_SYSTEM_LIBS OR NOT (SAVETOOL_USE_SYSTEM_CORRADE_MAGNUM AND SAVETOOL_USE_SYSTEM_SDL2 AND SAVETOOL_USE_SYSTEM_LIBZIP AND SAVETOOL_USE_SYSTEM_EFSW AND SAVETOOL_USE_SYSTEM_LIBCURL)) @@ -114,13 +113,6 @@ if(NOT SAVETOOL_USE_SYSTEM_LIBZIP) add_subdirectory(third-party/libzip EXCLUDE_FROM_ALL) endif(NOT SAVETOOL_USE_SYSTEM_LIBZIP) -if(NOT SAVETOOL_USE_SYSTEM_EFSW) - set(VERBOSE OFF CACHE BOOL "" FORCE) - set(BUILD_TEST_APP OFF CACHE BOOL "" FORCE) - set(EFSW_INSTALL OFF CACHE BOOL "" FORCE) - add_subdirectory(third-party/efsw EXCLUDE_FROM_ALL) -endif(NOT SAVETOOL_USE_SYSTEM_EFSW) - if(NOT SAVETOOL_USE_SYSTEM_LIBCURL) set(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE) set(ENABLE_UNICODE ON CACHE BOOL "" FORCE) diff --git a/src/Application/Application.cpp b/src/Application/Application.cpp index 3bb9f24..1b00fa3 100644 --- a/src/Application/Application.cpp +++ b/src/Application/Application.cpp @@ -92,7 +92,6 @@ Application::Application(const Arguments& arguments): } _updateEventId = _initEventId + 1; - _fileEventId = _initEventId + 2; LOG_INFO("Initialising the timer subsystem."); if(SDL_InitSubSystem(SDL_INIT_TIMER) != 0) { @@ -226,9 +225,6 @@ Application::anyEvent(SDL_Event& event) { else if(event.type == _updateEventId) { updateCheckEvent(event); } - else if(event.type == _fileEventId) { - fileUpdateEvent(event); - } } void diff --git a/src/Application/Application.h b/src/Application/Application.h index 45f5834..f7a0335 100644 --- a/src/Application/Application.h +++ b/src/Application/Application.h @@ -17,7 +17,6 @@ // along with this program. If not, see . #include -#include #include #include @@ -35,8 +34,6 @@ #include -#include - #include "../Managers/BackupManager.h" #include "../Managers/MassManager.h" #include "../Managers/ProfileManager.h" @@ -54,17 +51,11 @@ using namespace Magnum; namespace mbst { -class Application: public Platform::Sdl2Application, public efsw::FileWatchListener { +class Application: public Platform::Sdl2Application { public: explicit Application(const Arguments& arguments); - ~Application() override; - - void handleFileAction(efsw::WatchID watch_id, - const std::string& dir, - const std::string& filename, - efsw::Action action, - std::string old_filename) override; + virtual ~Application(); private: // Events @@ -90,21 +81,11 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe void updateCheckEvent(SDL_Event& event); - enum FileEventType: std::int32_t { - FileAdded = efsw::Action::Add, - FileDeleted = efsw::Action::Delete, - FileModified = efsw::Action::Modified, - FileMoved = efsw::Action::Moved, - StagedUpdate = 1 << 3 - }; - void fileUpdateEvent(SDL_Event& event); - // Initialisation methods void initialiseConfiguration(); void initialiseGui(); void initialiseManager(); void initialiseMassManager(); - void initialiseFileWatcher(); // GUI-related methods void drawImGui(); @@ -244,7 +225,6 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe std::uint32_t _initEventId; std::uint32_t _updateEventId; - std::uint32_t _fileEventId; Containers::String _lastError; @@ -266,17 +246,9 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe GameObjects::Weapon* _currentWeapon = nullptr; - Containers::Pointer _fileWatcher; - enum watchID { - SaveDir = 0, - StagingDir = 1 - }; - Containers::StaticArray<2, efsw::WatchID> _watchIDs; - Containers::Optional _checker{Containers::NullOpt}; std::mutex _checkerMutex; - bool _modifiedBySaveTool = false; bool _jointsDirty = false; bool _stylesDirty = false; bool _eyeFlareDirty = false; diff --git a/src/Application/Application_FileWatcher.cpp b/src/Application/Application_FileWatcher.cpp deleted file mode 100644 index 9771a24..0000000 --- a/src/Application/Application_FileWatcher.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// MassBuilderSaveTool -// Copyright (C) 2021-2024 Guillaume Jacquemin -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include "Application.h" - -namespace mbst { - -void -Application::handleFileAction(efsw::WatchID watch_id, const std::string&, const std::string& filename, - efsw::Action action, std::string old_filename) -{ - SDL_Event event; - SDL_zero(event); - event.type = _fileEventId; - - event.user.data1 = Containers::String{Containers::AllocatedInit, filename.c_str()}.release(); - - if(watch_id == _watchIDs[StagingDir] && Utility::String::endsWith(filename, ".sav")) { - event.user.code = StagedUpdate | action; - SDL_PushEvent(&event); - return; - } - - if(Utility::String::endsWith(filename, "Config.sav")) { - return; - } // TODO: actually do something when config files will finally be handled - - if(!Utility::String::endsWith(filename, Utility::format("Profile{}.sav", _currentProfile->account()).data()) && - filename.find("Unit") == std::string::npos) - { - return; - } - - event.user.code = action; - if(action == efsw::Actions::Moved) { - event.user.data2 = Containers::String{Containers::AllocatedInit, old_filename.c_str()}.release(); - } - - SDL_PushEvent(&event); -} - -void -Application::fileUpdateEvent(SDL_Event& event) { - Containers::String filename{static_cast(event.user.data1), - std::strlen(static_cast(event.user.data1)), nullptr}; - - if((event.user.code & StagedUpdate) == StagedUpdate) { - _stagedMassManager->refreshMass(filename); - return; - } - - Containers::String old_filename; - - std::int32_t index = 0; - std::int32_t old_index = 0; - bool is_current_profile = filename == _currentProfile->filename(); - bool is_unit = filename.hasPrefix(_currentProfile->isDemo() ? "DemoUnit"_s : "Unit"_s); - if(is_unit) { - index = ((filename[_currentProfile->isDemo() ? 8 : 4] - 0x30) * 10) + - (filename[_currentProfile->isDemo() ? 9 : 5] - 0x30); - } - - if(event.user.code == FileMoved) { - old_filename = Containers::String{static_cast(event.user.data2), - std::strlen(static_cast(event.user.data2)), nullptr}; - old_index = ((old_filename[_currentProfile->isDemo() ? 8 : 4] - 0x30) * 10) + - (old_filename[_currentProfile->isDemo() ? 9 : 5] - 0x30); - } - - switch(event.user.code) { - case FileAdded: - if(is_unit) { - if(!_currentMass || _currentMass != &(_massManager->hangar(index))) { - _massManager->refreshHangar(index); - } - else { - _currentMass->setDirty(); - } - } - break; - case FileDeleted: - if(is_current_profile) { - _currentProfile = nullptr; - _uiState = UiState::ProfileManager; - if(!_profileManager->refreshProfiles()) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", - _profileManager->lastError().data(), window()); - exit(EXIT_FAILURE); - } - } - else if(is_unit) { - if(!_currentMass || _currentMass != &(_massManager->hangar(index))) { - _massManager->refreshHangar(index); - } - } - break; - case FileModified: - if(is_current_profile) { - _currentProfile->refreshValues(); - } - else if(is_unit) { - if(!_currentMass || _currentMass != &(_massManager->hangar(index))) { - _massManager->refreshHangar(index); - } - else { - if(_modifiedBySaveTool && _currentMass->filename() == filename) { - auto handle = CreateFileW(Utility::Unicode::widen(Containers::StringView{filename}), - GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr); - if(handle && handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - _modifiedBySaveTool = false; - } - } - else { - _currentMass->setDirty(); - } - } - } - break; - case FileMoved: - if(is_unit) { - if(old_filename.hasSuffix(".sav"_s)) { - _massManager->refreshHangar(index); - _massManager->refreshHangar(old_index); - } - } - break; - default: - _queue.addToast(Toast::Type::Warning, "Unknown file action type"_s); - } -} - -} diff --git a/src/Application/Application_Initialisation.cpp b/src/Application/Application_Initialisation.cpp index d7500e1..0805209 100644 --- a/src/Application/Application_Initialisation.cpp +++ b/src/Application/Application_Initialisation.cpp @@ -122,8 +122,6 @@ Application::initialiseManager() { _backupManager.emplace(); - _stagedMassManager.emplace(); - event.user.code = InitSuccess; SDL_PushEvent(&event); } @@ -132,15 +130,8 @@ void Application::initialiseMassManager() { LOG_INFO("Initialising the M.A.S.S. manager."); _massManager.emplace(_currentProfile->account(), _currentProfile->isDemo()); -} - -void -Application::initialiseFileWatcher() { - LOG_INFO("Initialising the file watcher."); - _fileWatcher.emplace(); - _watchIDs[SaveDir] = _fileWatcher->addWatch(conf().directories().gameSaves, this, false); - _watchIDs[StagingDir] = _fileWatcher->addWatch(conf().directories().staging, this, false); - _fileWatcher->watch(); + LOG_INFO("Initialising the staged M.A.S.S. manager."); + _stagedMassManager.emplace(); } } diff --git a/src/Application/Application_MainManager.cpp b/src/Application/Application_MainManager.cpp index 6bc1578..8a7c439 100644 --- a/src/Application/Application_MainManager.cpp +++ b/src/Application/Application_MainManager.cpp @@ -55,9 +55,20 @@ Application::drawManager() { if(ImGui::Button(ICON_FA_ARROW_LEFT " Back to profile manager")) { _currentProfile = nullptr; _massManager.reset(); - _fileWatcher.reset(); + _stagedMassManager.reset(); _uiState = UiState::ProfileManager; } + ImGui::SameLine(); + if(ImGui::Button(ICON_FA_SYNC_ALT " Refresh external changes")) { + _currentProfile->refreshValues(); + if(!_currentProfile->valid()) { + _currentProfile = nullptr; + _profileManager->refreshProfiles(); + _queue.addToast(Toast::Type::Error, "The current profile isn't valid anymore."_s); + ImGui::End(); + return; + } + } if(ImGui::BeginChild("##ProfileInfo", {ImGui::GetContentRegionAvail().x * 0.60f, 0.0f}, @@ -93,6 +104,11 @@ Application::drawManager() { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("M.A.S.S. management"); drawHelpMarker("To move, import, or export builds, drag-and-drop them."); + if(ImGui::SmallButton(ICON_FA_SYNC_ALT " Refresh")) { + for(int i = 0; i < 32 ; i++) { + _massManager->refreshHangar(i); + } + } ImGui::EndMenuBar(); } @@ -527,10 +543,13 @@ Application::drawMassManager() { ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Staging area"); - ImGui::SameLine(); if(ImGui::SmallButton(ICON_FA_FOLDER_OPEN " Open staging folder")) { openUri(Utility::Path::toNativeSeparators(conf().directories().staging)); } + ImGui::SameLine(); + if(ImGui::SmallButton(ICON_FA_SYNC_ALT " Refresh")) { + _stagedMassManager->refresh(); + } for(const auto& mass : _stagedMassManager->stagedMasses()) { ImGui::TableNextRow(); @@ -575,6 +594,7 @@ Application::drawMassManager() { if(!_massManager->exportMass(index)) { _queue.addToast(Toast::Type::Error, _massManager->lastError()); } + _stagedMassManager->refresh(); } ImGui::EndDragDropTarget(); diff --git a/src/Application/Application_MassViewer.cpp b/src/Application/Application_MassViewer.cpp index 4e12f8a..9425803 100644 --- a/src/Application/Application_MassViewer.cpp +++ b/src/Application/Application_MassViewer.cpp @@ -72,16 +72,12 @@ Application::drawMassViewer() { drawTooltip(_currentMass->filename()); ImGui::TableSetColumnIndex(2); - if(_currentMass->dirty()) { - ImGui::TextUnformatted("External changes detected"); - ImGui::SameLine(); - if(ImGui::SmallButton(ICON_FA_SYNC_ALT " Refresh")) { - _currentMass->refreshValues(); - _currentMass->setDirty(false); - _jointsDirty = false; - _stylesDirty = false; - _eyeFlareDirty = false; - } + if(ImGui::SmallButton(ICON_FA_SYNC_ALT " Refresh external changes")) { + _currentMass->refreshValues(); + _currentMass->setDirty(false); + _jointsDirty = false; + _stylesDirty = false; + _eyeFlareDirty = false; } ImGui::TableSetColumnIndex(3); @@ -190,9 +186,7 @@ Application::drawGlobalStyles() { _currentMass->getGlobalStyles(); break; case DCS_Save: - _modifiedBySaveTool = true; if(!_currentMass->writeGlobalStyle(i)) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; diff --git a/src/Application/Application_MassViewer_Armour.cpp b/src/Application/Application_MassViewer_Armour.cpp index ea9bdd1..379131c 100644 --- a/src/Application/Application_MassViewer_Armour.cpp +++ b/src/Application/Application_MassViewer_Armour.cpp @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include + #include #include "../FontAwesome/IconsFontAwesome5.h" @@ -197,9 +199,7 @@ Application::drawArmour() { ImGui::EndChild(); if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _modifiedBySaveTool = true; if(!_currentMass->writeArmourPart(part.slot)) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } } @@ -357,11 +357,8 @@ Application::drawBLAttachment() { ImGui::EndGroup(); } - _modifiedBySaveTool = true; if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _modifiedBySaveTool = true; if(!_currentMass->writeBulletLauncherAttachments()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } } @@ -388,9 +385,7 @@ Application::drawCustomArmourStyles() { _currentMass->getArmourCustomStyles(); break; case DCS_Save: - _modifiedBySaveTool = true; if(!_currentMass->writeArmourCustomStyle(i)) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; diff --git a/src/Application/Application_MassViewer_Frame.cpp b/src/Application/Application_MassViewer_Frame.cpp index 2ccead1..c1dd9d4 100644 --- a/src/Application/Application_MassViewer_Frame.cpp +++ b/src/Application/Application_MassViewer_Frame.cpp @@ -149,9 +149,7 @@ Application::drawJointSliders() { } else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _modifiedBySaveTool = true; if(!_currentMass->writeJointSliders()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _jointsDirty = false; @@ -206,9 +204,7 @@ Application::drawFrameStyles() { } else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _modifiedBySaveTool = true; if(!_currentMass->writeFrameStyles()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _stylesDirty = false; @@ -240,9 +236,7 @@ Application::drawEyeColourPicker() { } else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _modifiedBySaveTool = true; if(!_currentMass->writeEyeFlareColour()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _eyeFlareDirty = false; @@ -276,9 +270,7 @@ Application::drawCustomFrameStyles() { _currentMass->getFrameCustomStyles(); break; case DCS_Save: - _modifiedBySaveTool = true; if(!_currentMass->writeFrameCustomStyle(i)) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; diff --git a/src/Application/Application_MassViewer_Weapons.cpp b/src/Application/Application_MassViewer_Weapons.cpp index 170f600..fc0f4f1 100644 --- a/src/Application/Application_MassViewer_Weapons.cpp +++ b/src/Application/Application_MassViewer_Weapons.cpp @@ -94,47 +94,39 @@ Application::drawWeaponCategory(Containers::StringView name, GameObjects::Weapon ImGui::PushID(name.cbegin()); if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_SAVE " Save")) { - _modifiedBySaveTool = true; switch(category) { case GameObjects::Weapon::Type::Melee: if(!_currentMass->writeMeleeWeapons()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case GameObjects::Weapon::Type::Shield: if(!_currentMass->writeShields()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case GameObjects::Weapon::Type::BulletShooter: if(!_currentMass->writeBulletShooters()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case GameObjects::Weapon::Type::EnergyShooter: if(!_currentMass->writeEnergyShooters()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case GameObjects::Weapon::Type::BulletLauncher: if(!_currentMass->writeBulletLaunchers()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case GameObjects::Weapon::Type::EnergyLauncher: if(!_currentMass->writeEnergyLaunchers()) { - _modifiedBySaveTool = false; _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; default: - _modifiedBySaveTool = false; - _queue.addToast(Toast::Type::Error, "Unknown weapon type"); + _queue.addToast(Toast::Type::Error, "Unknown weapon type"); } } diff --git a/src/Application/Application_ProfileManager.cpp b/src/Application/Application_ProfileManager.cpp index ce103a0..a724679 100644 --- a/src/Application/Application_ProfileManager.cpp +++ b/src/Application/Application_ProfileManager.cpp @@ -91,7 +91,6 @@ Application::drawProfileManager() { { _currentProfile = _profileManager->getProfile(i); initialiseMassManager(); - initialiseFileWatcher(); _uiState = UiState::MainManager; } diff --git a/src/Application/Application_drawAbout.cpp b/src/Application/Application_drawAbout.cpp index 477be5d..df6314a 100644 --- a/src/Application/Application_drawAbout.cpp +++ b/src/Application/Application_drawAbout.cpp @@ -193,23 +193,6 @@ Application::drawAbout() { ImGui::TreePop(); } - if(ImGui::TreeNodeEx("Entropia File System Watcher (efsw)", ImGuiTreeNodeFlags_SpanAvailWidth)) { - auto efsw_repo = "https://github.com/SpartanJ/efsw"; - drawAlignedText(ICON_FA_GITHUB " %s", efsw_repo); - ImGui::SameLine(); - if(ImGui::Button("Copy to clipboard")) { - ImGui::SetClipboardText(efsw_repo); - } - ImGui::SameLine(); - if(ImGui::Button("Open in browser")) { - openUri(efsw_repo); - } - - ImGui::TextUnformatted("Licence: MIT"); - - ImGui::TreePop(); - } - if(ImGui::TreeNodeEx("libcurl", ImGuiTreeNodeFlags_SpanAvailWidth)) { ImGui::Text("Version used: %s", LIBCURL_VERSION); auto curl_website = "https://curl.se/libcurl"; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bdaa2a..ae19017 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,10 +31,6 @@ if(SAVETOOL_USE_SYSTEM_LIBZIP) find_package(libzip REQUIRED) endif(SAVETOOL_USE_SYSTEM_LIBZIP) -if(SAVETOOL_USE_SYSTEM_EFSW) - find_package(efsw REQUIRED) -endif(SAVETOOL_USE_SYSTEM_EFSW) - if(SAVETOOL_USE_SYSTEM_LIBCURL) find_package(CURL REQUIRED HTTPS) endif(SAVETOOL_USE_SYSTEM_LIBCURL) @@ -145,7 +141,6 @@ add_executable(MassBuilderSaveTool Application/Application.cpp Application/Application_drawAbout.cpp Application/Application_drawMainMenu.cpp - Application/Application_FileWatcher.cpp Application/Application_Initialisation.cpp Application/Application_MainManager.cpp Application/Application_MassViewer.cpp @@ -262,12 +257,6 @@ else() target_link_libraries(MassBuilderSaveTool PRIVATE zip) endif() -if(SAVETOOL_USE_SYSTEM_EFSW) - target_link_libraries(MassBuilderSaveTool PRIVATE efsw::efsw) -else() - target_link_libraries(MassBuilderSaveTool PRIVATE efsw) -endif() - if(CORRADE_TARGET_WINDOWS) target_link_libraries(MassBuilderSaveTool PRIVATE Corrade::Main