Detect when local changes occured to file

This commit is contained in:
Yousef Khadadeh 2026-01-17 20:11:13 +03:00
parent 8f03080b87
commit 1955de9e3e
5 changed files with 47 additions and 4 deletions

View file

@ -485,7 +485,7 @@ void Toolbar::top_toolbar() {
}
std::vector<std::pair<std::string, std::string>> tabNames;
for(size_t i = 0; i < main.worlds.size(); i++)
tabNames.emplace_back(main.worlds[i]->netObjMan.is_connected() ? "data/icons/network.svg" : "", main.worlds[i]->name);
tabNames.emplace_back(main.worlds[i]->netObjMan.is_connected() ? "data/icons/network.svg" : "", main.worlds[i]->name + (main.worlds[i]->hasUnsavedLocalChanges ? "*" : ""));
std::optional<size_t> closedTab;
gui.tab_list("file tab list", tabNames, main.worldIndex, closedTab);
if(!main.world->clientStillConnecting) {

View file

@ -404,6 +404,7 @@ void World::save_to_file(const std::filesystem::path& filePathToSaveAt) {
#endif
Logger::get().log("USERINFO", "File saved");
undo.set_save_action();
}
catch(const std::exception& e) {
Logger::get().log("WORLDFATAL", std::string("Save error: ") + e.what());

View file

@ -89,6 +89,7 @@ class World {
void scale_up(const WorldScalar& scaleUpAmount);
void scale_up_step();
bool hasUnsavedLocalChanges = false;
bool setToDestroy = false;
NetworkingObjects::DelayUpdateSerializedClassManager delayedUpdateObjectManager;

View file

@ -1,4 +1,5 @@
#include "WorldUndoManager.hpp"
#include "World.hpp"
void WorldUndoAction::scale_up(const WorldScalar& scaleAmount) {}
WorldUndoAction::~WorldUndoAction() {}
@ -18,17 +19,23 @@ bool WorldUndoManager::can_redo() {
void WorldUndoManager::push(std::unique_ptr<WorldUndoAction> undoAction) {
push_undo(std::move(undoAction));
redoQueue.clear();
world.hasUnsavedLocalChanges = true;
}
void WorldUndoManager::push_undo(std::unique_ptr<WorldUndoAction> undoAction) {
if(undoQueue.size() == UNDO_QUEUE_LIMIT)
if(undoQueue.size() == UNDO_QUEUE_LIMIT) {
if(undoActionSavedAt.has_value()) {
if(undoQueue.front().get() == undoActionSavedAt.value())
undoActionSavedAt = nullptr;
else if(undoActionSavedAt.value() == nullptr)
undoActionSavedAt = std::nullopt;
}
undoQueue.pop_front();
}
undoQueue.emplace_back(std::move(undoAction));
}
void WorldUndoManager::push_redo(std::unique_ptr<WorldUndoAction> undoAction) {
if(redoQueue.size() == UNDO_QUEUE_LIMIT)
redoQueue.pop_front();
redoQueue.emplace_back(std::move(undoAction));
}
@ -41,6 +48,8 @@ void WorldUndoManager::undo() {
push_redo(std::move(undoQueue.back()));
undoQueue.pop_back();
}
set_world_has_unsaved_local_changes();
}
void WorldUndoManager::redo() {
@ -52,11 +61,14 @@ void WorldUndoManager::redo() {
push_undo(std::move(redoQueue.back()));
redoQueue.pop_back();
}
set_world_has_unsaved_local_changes();
}
void WorldUndoManager::clear() {
redoQueue.clear();
undoQueue.clear();
undoActionSavedAt = std::nullopt;
}
void WorldUndoManager::scale_up(const WorldScalar& scaleAmount) {
@ -142,3 +154,26 @@ std::vector<std::string> WorldUndoManager::get_front_undo_queue_names(unsigned c
}
return toRet;
}
void WorldUndoManager::set_save_action() {
if(undoQueue.empty())
undoActionSavedAt = nullptr;
else
undoActionSavedAt = undoQueue.back().get();
world.hasUnsavedLocalChanges = false;
}
void WorldUndoManager::set_world_has_unsaved_local_changes() {
// Saved action value meanings:
// - a pointer to an action: The file was saved when that undo action was the last one in place
// - nullptr: The file was saved when undoQueue was empty
// - nullopt: The undo action the file was saved at was lost
if(!undoActionSavedAt.has_value())
world.hasUnsavedLocalChanges = true;
else {
if(undoQueue.empty())
world.hasUnsavedLocalChanges = undoActionSavedAt.value() != nullptr;
else
world.hasUnsavedLocalChanges = undoActionSavedAt.value() != undoQueue.back().get();
}
}

View file

@ -38,6 +38,8 @@ class WorldUndoManager {
bool fill_netid_list_from_undoid_list(std::vector<NetworkingObjects::NetObjID>& netIDList, const std::vector<UndoObjectID>& undoIDList);
std::vector<std::string> get_front_undo_queue_names(unsigned count);
void set_save_action();
World& world;
private:
void push_undo(std::unique_ptr<WorldUndoAction> undoAction);
@ -49,5 +51,9 @@ class WorldUndoManager {
std::deque<std::unique_ptr<WorldUndoAction>> undoQueue;
std::deque<std::unique_ptr<WorldUndoAction>> redoQueue;
std::optional<WorldUndoAction*> undoActionSavedAt = nullptr;
void set_world_has_unsaved_local_changes();
UndoObjectID lastUndoObjectID = 0;
};