Added grid undo actions

This commit is contained in:
Yousef Khadadeh 2026-01-02 19:24:12 +03:00
parent be2ba1e285
commit 2c9908bcea
5 changed files with 141 additions and 11 deletions

View file

@ -190,5 +190,5 @@ void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {
void GridModifyTool::switch_tool(DrawingProgramToolType newTool) {
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
if(gLock)
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gLock, true);
drawP.world.gridMan.finalize_grid_modify(gLock, oldGrid);
}

View file

@ -1,6 +1,7 @@
#include "GridManager.hpp"
#include "World.hpp"
#include "MainProgram.hpp"
#include "WorldUndoManager.hpp"
#include <cereal/types/unordered_map.hpp>
GridManager::GridManager(World& w):
@ -17,13 +18,123 @@ void GridManager::add_default_grid(const std::string& newName) {
g.color = color_mul_alpha(convert_vec4<Vector4f>(world.canvasTheme.get_tool_front_color()), 0.4f);
g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast<float>() * 0.5f);
grids->emplace_back_direct(grids, g);
auto it = grids->emplace_back_direct(grids, g);
class AddGridWorldUndoAction : public WorldUndoAction {
public:
AddGridWorldUndoAction(const WorldGrid& initGridData, WorldUndoManager::UndoObjectID initUndoID):
gridData(initGridData),
undoID(initUndoID)
{}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toEraseID = undoMan.get_netid_from_undoid(undoID);
if(!toEraseID.has_value())
return false;
auto& gridList = undoMan.world.gridMan.grids;
gridList->erase(gridList, gridList->get(toEraseID.value()));
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toInsertID = undoMan.get_netid_from_undoid(undoID);
if(toInsertID.has_value())
return false;
auto& gridList = undoMan.world.gridMan.grids;
auto insertedIt = gridList->emplace_back_direct(gridList, gridData);
undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id());
return true;
}
void scale_up(const WorldScalar& scaleAmount) override {
gridData.scale_up(scaleAmount);
}
~AddGridWorldUndoAction() {}
WorldGrid gridData;
WorldUndoManager::UndoObjectID undoID;
};
world.undo.push(std::make_unique<AddGridWorldUndoAction>(g, world.undo.get_undoid_from_netid(it->obj.get_net_id())));
}
}
void GridManager::remove_grid(uint32_t indexToRemove) {
if(grids)
grids->erase(grids, grids->at(indexToRemove));
if(grids) {
class EraseGridWorldUndoAction : public WorldUndoAction {
public:
EraseGridWorldUndoAction(const WorldGrid& initGridData, WorldUndoManager::UndoObjectID initUndoID):
gridData(initGridData),
undoID(initUndoID)
{}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toInsertID = undoMan.get_netid_from_undoid(undoID);
if(toInsertID.has_value())
return false;
auto& gridList = undoMan.world.gridMan.grids;
auto insertedIt = gridList->emplace_back_direct(gridList, gridData);
undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id());
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toEraseID = undoMan.get_netid_from_undoid(undoID);
if(!toEraseID.has_value())
return false;
auto& gridList = undoMan.world.gridMan.grids;
gridList->erase(gridList, gridList->get(toEraseID.value()));
return true;
}
void scale_up(const WorldScalar& scaleAmount) override {
gridData.scale_up(scaleAmount);
}
~EraseGridWorldUndoAction() {}
WorldGrid gridData;
WorldUndoManager::UndoObjectID undoID;
};
auto it = grids->at(indexToRemove);
world.undo.push(std::make_unique<EraseGridWorldUndoAction>(*it->obj, world.undo.get_undoid_from_netid(it->obj.get_net_id())));
grids->erase(grids, it);
}
}
void GridManager::finalize_grid_modify(const NetworkingObjects::NetObjTemporaryPtr<WorldGrid>& wGrid, const WorldGrid& oldGridData) {
class ModifyGridWorldUndoAction : public WorldUndoAction {
public:
ModifyGridWorldUndoAction(const WorldGrid& initGridDataOld, const WorldGrid& initGridDataNew, WorldUndoManager::UndoObjectID initUndoID):
gridDataOld(initGridDataOld),
gridDataNew(initGridDataNew),
undoID(initUndoID)
{}
bool undo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
return false;
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toModifyID.value());
*gridPtr = gridDataOld;
undoMan.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gridPtr, true);
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
return false;
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toModifyID.value());
*gridPtr = gridDataNew;
undoMan.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gridPtr, true);
return true;
}
void scale_up(const WorldScalar& scaleAmount) override {
gridDataOld.scale_up(scaleAmount);
gridDataNew.scale_up(scaleAmount);
}
~ModifyGridWorldUndoAction() {}
WorldGrid gridDataOld;
WorldGrid gridDataNew;
WorldUndoManager::UndoObjectID undoID;
};
world.undo.push(std::make_unique<ModifyGridWorldUndoAction>(oldGridData, *wGrid, world.undo.get_undoid_from_netid(wGrid.get_net_id())));
world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(wGrid, true);
}
void GridManager::draw_back(SkCanvas* canvas, const DrawData& drawData) {

View file

@ -34,6 +34,7 @@ class GridManager {
void scale_up(const WorldScalar& scaleUpAmount);
void save_file(cereal::PortableBinaryOutputArchive& a) const;
void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
void finalize_grid_modify(const NetworkingObjects::NetObjTemporaryPtr<WorldGrid>& wGrid, const WorldGrid& oldGridData);
NetworkingObjects::NetObjOwnerPtr<NetworkingObjects::NetObjOrderedList<WorldGrid>> grids;
World& world;

View file

@ -71,7 +71,7 @@ void WorldUndoManager::reassign_netid(const NetworkingObjects::NetObjID& oldNetO
if(netIDtoUndoIDIterator != netIDToUndoID.end()) {
UndoObjectID undoID = netIDtoUndoIDIterator->second;
netIDToUndoID.erase(netIDtoUndoIDIterator);
netIDToUndoID.emplace(newNetObjID, undoID);
netIDToUndoID[newNetObjID] = undoID;
undoIDToNetID[undoID] = newNetObjID;
}
}
@ -92,11 +92,28 @@ void WorldUndoManager::remove_by_undoid(UndoObjectID undoID) {
}
}
WorldUndoManager::UndoObjectID WorldUndoManager::register_new_netobj(const NetworkingObjects::NetObjID& netObjID) {
++lastUndoObjectID;
undoIDToNetID[lastUndoObjectID] = netObjID;
netIDToUndoID[netObjID] = lastUndoObjectID;
return lastUndoObjectID;
WorldUndoManager::UndoObjectID WorldUndoManager::get_undoid_from_netid(const NetworkingObjects::NetObjID& netObjID) {
auto it = netIDToUndoID.find(netObjID);
if(it == netIDToUndoID.end()) {
++lastUndoObjectID;
undoIDToNetID[lastUndoObjectID] = netObjID;
netIDToUndoID[netObjID] = lastUndoObjectID;
return lastUndoObjectID;
}
return it->second;
}
void WorldUndoManager::register_new_netid_to_existing_undoid(UndoObjectID existingUndoID, const NetworkingObjects::NetObjID& netObjID) {
auto undoIDToNetIDIterator = undoIDToNetID.find(existingUndoID);
if(undoIDToNetIDIterator != undoIDToNetID.end()) {
netIDToUndoID.erase(undoIDToNetIDIterator->second);
undoIDToNetIDIterator->second = netObjID;
netIDToUndoID[netObjID] = existingUndoID;
}
else {
netIDToUndoID[netObjID] = existingUndoID;
undoIDToNetID[existingUndoID] = netObjID;
}
}
std::optional<NetworkingObjects::NetObjID> WorldUndoManager::get_netid_from_undoid(UndoObjectID undoID) {

View file

@ -31,7 +31,8 @@ class WorldUndoManager {
void reassign_netid(const NetworkingObjects::NetObjID& oldNetObjID, const NetworkingObjects::NetObjID& newNetObjID);
void remove_by_netid(const NetworkingObjects::NetObjID& netObjID);
void remove_by_undoid(UndoObjectID undoID);
UndoObjectID register_new_netobj(const NetworkingObjects::NetObjID& netObjID);
UndoObjectID get_undoid_from_netid(const NetworkingObjects::NetObjID& netObjID);
void register_new_netid_to_existing_undoid(UndoObjectID existingUndoID, const NetworkingObjects::NetObjID& netObjID);
std::optional<NetworkingObjects::NetObjID> get_netid_from_undoid(UndoObjectID undoID);
World& world;