SaveTool: change how file update events are handled.

This commit is contained in:
Guillaume Jacquemin 2022-03-09 13:27:45 +01:00
parent f1a4b64219
commit dd9dcdb5f6
2 changed files with 115 additions and 82 deletions

View file

@ -20,7 +20,8 @@
#include <Corrade/Containers/Pair.h> #include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/ScopeGuard.h> #include <Corrade/Containers/ScopeGuard.h>
#include <Corrade/Utility/FormatStl.h> #include <Corrade/Containers/StringStl.h>
#include <Corrade/Utility/Format.h>
#include <Corrade/Utility/Path.h> #include <Corrade/Utility/Path.h>
#include <Corrade/Utility/String.h> #include <Corrade/Utility/String.h>
#include <Corrade/Utility/Unicode.h> #include <Corrade/Utility/Unicode.h>
@ -87,14 +88,15 @@ SaveTool::SaveTool(const Arguments& arguments):
initialiseGui(); initialiseGui();
if((_initEventId = SDL_RegisterEvents(2)) == UnsignedInt(-1)) { if((_initEventId = SDL_RegisterEvents(3)) == UnsignedInt(-1)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
"SDL_RegisterEvents failed in SaveTool::SaveTool(). Exiting...", window()); "SDL_RegisterEvents() failed in SaveTool::SaveTool(). Exiting...", window());
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
return; return;
} }
_updateEventId = _initEventId + 1; _updateEventId = _initEventId + 1;
_fileEventId = _initEventId + 2;
initialiseToolDirectories(); initialiseToolDirectories();
@ -187,88 +189,32 @@ void SaveTool::handleFileAction(efsw::WatchID watch_id,
efsw::Action action, efsw::Action action,
std::string old_filename) std::string old_filename)
{ {
SDL_Event event;
SDL_zero(event);
event.type = _fileEventId;
if(watch_id == _watchIDs[StagingDir] && Utility::String::endsWith(filename, ".sav")) { if(watch_id == _watchIDs[StagingDir] && Utility::String::endsWith(filename, ".sav")) {
_massManager->refreshStagedMasses(); event.user.code = StagedUpdate;
SDL_PushEvent(&event);
return; return;
} }
if(Utility::String::endsWith(filename, "Config.sav")) { if(Utility::String::endsWith(filename, "Config.sav")) {
return; return;
} // TODO: actually do something when config files will finally be handled
if(!Utility::String::endsWith(filename, _currentProfile->account() + ".sav")) {
return;
} }
static bool is_moved_after_save = false; event.user.code = action;
event.user.data1 = Containers::String{filename}.release();
switch(action) { if(action == efsw::Actions::Moved) {
case efsw::Actions::Add: event.user.data2 = Containers::String{old_filename}.release();
if(Utility::String::endsWith(filename, _currentProfile->account() + ".sav")) {
if(Utility::String::beginsWith(filename, Utility::formatString("{}Unit", _currentProfile->type() == ProfileType::Demo ? "Demo" : ""))) {
int index = ((filename[_currentProfile->type() == ProfileType::Demo ? 8 : 4] - 0x30) * 10) +
(filename[_currentProfile->type() == ProfileType::Demo ? 9 : 5] - 0x30);
if(!_currentMass || _currentMass != &(_massManager->hangar(index))) {
_massManager->refreshHangar(index);
}
else {
_currentMass->setDirty();
}
}
}
break;
case efsw::Actions::Delete:
if(Utility::String::endsWith(filename, _currentProfile->account() + ".sav")) {
if(Utility::String::beginsWith(filename, Utility::formatString("{}Unit", _currentProfile->type() == ProfileType::Demo ? "Demo" : ""))) {
int index = ((filename[_currentProfile->type() == ProfileType::Demo ? 8 : 4] - 0x30) * 10) +
(filename[_currentProfile->type() == ProfileType::Demo ? 9 : 5] - 0x30);
if(!_currentMass || _currentMass != &(_massManager->hangar(index))) {
_massManager->refreshHangar(index);
}
}
}
break;
case efsw::Actions::Modified:
if(filename == _currentProfile->filename()) {
_currentProfile->refreshValues();
}
else if(Utility::String::endsWith(filename, _currentProfile->account() + ".sav")) {
if(Utility::String::beginsWith(filename, Utility::formatString("{}Unit", _currentProfile->type() == ProfileType::Demo ? "Demo" : ""))) {
int index = ((filename[_currentProfile->type() == ProfileType::Demo ? 8 : 4] - 0x30) * 10) +
(filename[_currentProfile->type() == ProfileType::Demo ? 9 : 5] - 0x30);
if(!_currentMass || _currentMass != &(_massManager->hangar(index))) {
_massManager->refreshHangar(index);
}
else {
if(!is_moved_after_save) {
is_moved_after_save = false;
_currentMass->setDirty();
}
}
}
}
break;
case efsw::Actions::Moved:
if(Utility::String::endsWith(filename, _currentProfile->account() + ".sav")) {
if(Utility::String::endsWith(old_filename, ".tmp")) {
is_moved_after_save = true;
return;
}
if(Utility::String::beginsWith(filename, Utility::formatString("{}Unit", _currentProfile->type() == ProfileType::Demo ? "Demo" : "")) &&
Utility::String::endsWith(old_filename, ".sav"))
{
int index = ((filename[_currentProfile->type() == ProfileType::Demo ? 8 : 4] - 0x30) * 10) +
(filename[_currentProfile->type() == ProfileType::Demo ? 9 : 5] - 0x30);
_massManager->refreshHangar(index);
int old_index = ((old_filename[_currentProfile->type() == ProfileType::Demo ? 8 : 4] - 0x30) * 10) +
(old_filename[_currentProfile->type() == ProfileType::Demo ? 9 : 5] - 0x30);
_massManager->refreshHangar(old_index);
}
}
break;
default:
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Unknown file watcher action type.", window());
break;
} }
SDL_PushEvent(&event);
return;
} }
void SaveTool::drawEvent() { void SaveTool::drawEvent() {
@ -328,6 +274,9 @@ void SaveTool::anyEvent(SDL_Event& event) {
else if(event.type == _updateEventId) { else if(event.type == _updateEventId) {
updateCheckEvent(event); updateCheckEvent(event);
} }
else if(event.type == _fileEventId) {
fileUpdateEvent(event);
}
} }
void SaveTool::initEvent(SDL_Event& event) { void SaveTool::initEvent(SDL_Event& event) {
@ -359,7 +308,7 @@ void SaveTool::updateCheckEvent(SDL_Event& event) {
} }
if(r.status_code != 200) { if(r.status_code != 200) {
_queue.addToast(Toast::Type::Error, Utility::format("The request failed with error code {}: {}", r.status_code, r.reason)); _queue.addToast(Toast::Type::Error, Utility::format("The request failed with error code {}: {}", r.status_code, r.reason.c_str()));
return; return;
} }
@ -425,6 +374,84 @@ void SaveTool::updateCheckEvent(SDL_Event& event) {
} }
} }
void SaveTool::fileUpdateEvent(SDL_Event& event) {
Containers::String filename{static_cast<char*>(event.user.data1), std::strlen(static_cast<char*>(event.user.data1)), nullptr};
Containers::String old_filename;
Int index = 0;
Int 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);
}
static bool is_moved_after_save = false;
if(event.user.code == FileMoved) {
old_filename = Containers::String{static_cast<char*>(event.user.data2), std::strlen(static_cast<char*>(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;
_profileManager->refreshProfiles();
}
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(!is_moved_after_save) {
is_moved_after_save = false;
_currentMass->setDirty();
}
}
}
break;
case FileMoved:
if(is_unit) {
if(old_filename.hasSuffix(".tmp"_s)) {
is_moved_after_save = true;
return;
}
if(old_filename.hasSuffix(".sav"_s)) {
_massManager->refreshHangar(index);
_massManager->refreshHangar(old_index);
}
}
break;
case StagedUpdate:
_massManager->refreshStagedMasses();
break;
default:
_queue.addToast(Toast::Type::Warning, "Unknown file action type"_s);
}
}
void SaveTool::initialiseConfiguration() { void SaveTool::initialiseConfiguration() {
if(_conf.hasValue("cheat_mode"_s)) { if(_conf.hasValue("cheat_mode"_s)) {
_cheatMode = _conf.value<bool>("cheat_mode"_s); _cheatMode = _conf.value<bool>("cheat_mode"_s);
@ -587,11 +614,7 @@ auto SaveTool::findGameDataDirectory() -> bool {
} }
void SaveTool::initialiseMassManager() { void SaveTool::initialiseMassManager() {
_massManager.emplace(_saveDir, _massManager.emplace(_saveDir, _currentProfile->account(), _currentProfile->isDemo(), _stagingDir);
_currentProfile->account(),
_currentProfile->type() == ProfileType::Demo,
_stagingDir);
initialiseFileWatcher(); initialiseFileWatcher();
} }

View file

@ -83,6 +83,15 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void initEvent(SDL_Event& event); void initEvent(SDL_Event& event);
void updateCheckEvent(SDL_Event& event); void updateCheckEvent(SDL_Event& event);
enum FileEventType: Int {
FileAdded = efsw::Action::Add,
FileDeleted = efsw::Action::Delete,
FileModified = efsw::Action::Modified,
FileMoved = efsw::Action::Moved,
StagedUpdate
};
void fileUpdateEvent(SDL_Event& event);
// Initialisation methods // Initialisation methods
void initialiseConfiguration(); void initialiseConfiguration();
void initialiseGui(); void initialiseGui();
@ -217,6 +226,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
UnsignedInt _initEventId; UnsignedInt _initEventId;
UnsignedInt _updateEventId; UnsignedInt _updateEventId;
UnsignedInt _fileEventId;
Containers::String _lastError; Containers::String _lastError;