From 0e22c8ac3e30a1bdcc6d9e162b0f3169ee41c44d Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Fri, 2 Jan 2026 21:06:13 +0300 Subject: [PATCH] Undo now takes into account list position, and started work on bookmark undo --- .../NetworkingObjects/NetObjOrderedList.hpp | 3 ++ src/Bookmarks/BookmarkListItem.cpp | 34 ++++++++++++++++++- src/Bookmarks/BookmarkListItem.hpp | 9 +++++ src/GridManager.cpp | 22 +++++++----- src/Toolbar.cpp | 4 +-- src/WorldUndoManager.cpp | 4 +-- src/WorldUndoManager.hpp | 4 +-- 7 files changed, 64 insertions(+), 16 deletions(-) diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 3c808c6..644fe2a 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -58,6 +58,9 @@ namespace NetworkingObjects { static NetObjOrderedListIterator push_back_and_send_create(const NetObjTemporaryPtr>& l, T* newObj) { return l->insert_single(l, nullptr, l->end(), l.get_obj_man()->template make_obj_from_ptr(newObj)); } + template NetObjOrderedListIterator emplace_direct(const NetObjTemporaryPtr>& l, const NetObjOrderedListIterator& it, Args&&... items) { + return l->insert_single(l, nullptr, it, l.get_obj_man()->template make_obj_direct(items...)); + } static NetObjOrderedListIterator insert_and_send_create(const NetObjTemporaryPtr>& l, const NetObjOrderedListIterator& it, T* newObj) { return l->insert_single(l, nullptr, it, l.get_obj_man()->template make_obj_from_ptr(newObj)); } diff --git a/src/Bookmarks/BookmarkListItem.cpp b/src/Bookmarks/BookmarkListItem.cpp index 261cb86..3990392 100644 --- a/src/Bookmarks/BookmarkListItem.cpp +++ b/src/Bookmarks/BookmarkListItem.cpp @@ -11,8 +11,26 @@ void BookmarkData::jump_to(World& world) const { world.drawData.cam.smooth_move_to(world, coords, windowSize.cast()); } +void BookmarkData::scale_up(const WorldScalar& scaleUpAmount) { + coords.scale_about(WorldVec{0, 0}, scaleUpAmount, true); +} + BookmarkListItem::BookmarkListItem() {} +BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const BookmarkCompleteInitData& initData) { + nameData = netObjMan.make_obj(); + nameData->name = initData.name; + if(initData.folderList) { + auto& initFolderList = initData.folderList.value(); + folderData = std::make_unique(); + folderData->folderList = netObjMan.make_obj>(); + for(auto& initFolder : initFolderList) + folderData->folderList->emplace_back_direct(folderData->folderList, netObjMan, initFolder); + } + else + bookmarkData = std::make_unique(initData.bookmarkData.value()); +} + BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder, const BookmarkData& initBookmarkData) { if(isFolder) { folderData = std::make_unique(); @@ -24,6 +42,20 @@ BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, nameData->name = initName; } +BookmarkCompleteInitData BookmarkListItem::get_complete_init_data() { + BookmarkCompleteInitData toRet; + toRet.name = nameData->name; + if(folderData) { + toRet.folderList = std::vector(); + auto& folderListToRet = toRet.folderList.value(); + for(auto& b : *folderData->folderList) + folderListToRet.emplace_back(b.obj->get_complete_init_data()); + } + else + toRet.bookmarkData = *bookmarkData; + return toRet; +} + void BookmarkListItem::reassign_netobj_ids_call() { if(folderData) folderData->folderList.reassign_ids(); @@ -36,7 +68,7 @@ void BookmarkListItem::scale_up(const WorldScalar& scaleUpAmount) { i.obj->scale_up(scaleUpAmount); } else - bookmarkData->coords.scale_about(WorldVec{0, 0}, scaleUpAmount, true); + bookmarkData->scale_up(scaleUpAmount); } bool BookmarkListItem::is_folder() const { diff --git a/src/Bookmarks/BookmarkListItem.hpp b/src/Bookmarks/BookmarkListItem.hpp index 9ed35d8..c1e4f70 100644 --- a/src/Bookmarks/BookmarkListItem.hpp +++ b/src/Bookmarks/BookmarkListItem.hpp @@ -14,12 +14,20 @@ struct BookmarkData { template void serialize(Archive& a) { a(coords, windowSize); } + void scale_up(const WorldScalar& scaleUpAmount); void jump_to(World& world) const; }; +struct BookmarkCompleteInitData { + std::string name; + std::optional> folderList; + std::optional bookmarkData; +}; + class BookmarkListItem { public: BookmarkListItem(); + BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const BookmarkCompleteInitData& initData); BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder, const BookmarkData& initBookmarkData); bool is_folder() const; const BookmarkData& get_bookmark_data() const; @@ -32,6 +40,7 @@ class BookmarkListItem { void scale_up(const WorldScalar& scaleUpAmount); void save_file(cereal::PortableBinaryOutputArchive& a) const; void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version, BookmarkManager& bMan); + BookmarkCompleteInitData get_complete_init_data(); void set_name(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, const std::string& newName); private: diff --git a/src/GridManager.cpp b/src/GridManager.cpp index aaef6dc..e285264 100644 --- a/src/GridManager.cpp +++ b/src/GridManager.cpp @@ -22,11 +22,12 @@ void GridManager::add_default_grid(const std::string& newName) { class AddGridWorldUndoAction : public WorldUndoAction { public: - AddGridWorldUndoAction(const WorldGrid& initGridData, WorldUndoManager::UndoObjectID initUndoID): + AddGridWorldUndoAction(const WorldGrid& initGridData, uint32_t newPos, WorldUndoManager::UndoObjectID initUndoID): gridData(initGridData), + pos(newPos), undoID(initUndoID) {} - const char* get_name() const override { + std::string get_name() const override { return "Add Grid"; } bool undo(WorldUndoManager& undoMan) override { @@ -42,7 +43,7 @@ void GridManager::add_default_grid(const std::string& newName) { if(toInsertID.has_value()) return false; auto& gridList = undoMan.world.gridMan.grids; - auto insertedIt = gridList->emplace_back_direct(gridList, gridData); + auto insertedIt = gridList->emplace_direct(gridList, gridList->at(pos), gridData); undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id()); return true; } @@ -52,10 +53,11 @@ void GridManager::add_default_grid(const std::string& newName) { ~AddGridWorldUndoAction() {} WorldGrid gridData; + uint32_t pos; WorldUndoManager::UndoObjectID undoID; }; - world.undo.push(std::make_unique(g, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); + world.undo.push(std::make_unique(g, it->pos, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); } } @@ -63,11 +65,12 @@ void GridManager::remove_grid(uint32_t indexToRemove) { if(grids) { class EraseGridWorldUndoAction : public WorldUndoAction { public: - EraseGridWorldUndoAction(const WorldGrid& initGridData, WorldUndoManager::UndoObjectID initUndoID): + EraseGridWorldUndoAction(const WorldGrid& initGridData, uint32_t newPos, WorldUndoManager::UndoObjectID initUndoID): gridData(initGridData), + pos(newPos), undoID(initUndoID) {} - const char* get_name() const override { + std::string get_name() const override { return "Remove Grid"; } bool undo(WorldUndoManager& undoMan) override { @@ -75,7 +78,7 @@ void GridManager::remove_grid(uint32_t indexToRemove) { if(toInsertID.has_value()) return false; auto& gridList = undoMan.world.gridMan.grids; - auto insertedIt = gridList->emplace_back_direct(gridList, gridData); + auto insertedIt = gridList->emplace_direct(gridList, gridList->at(pos), gridData); undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id()); return true; } @@ -93,11 +96,12 @@ void GridManager::remove_grid(uint32_t indexToRemove) { ~EraseGridWorldUndoAction() {} WorldGrid gridData; + uint32_t pos; WorldUndoManager::UndoObjectID undoID; }; auto it = grids->at(indexToRemove); - world.undo.push(std::make_unique(*it->obj, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); + world.undo.push(std::make_unique(*it->obj, it->pos, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); grids->erase(grids, it); } } @@ -110,7 +114,7 @@ void GridManager::finalize_grid_modify(const NetworkingObjects::NetObjTemporaryP gridDataNew(initGridDataNew), undoID(initUndoID) {} - const char* get_name() const override { + std::string get_name() const override { return "Modify Grid"; } bool undo(WorldUndoManager& undoMan) override { diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index f77e213..fb7d650 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -1237,8 +1237,8 @@ void Toolbar::performance_metrics() { .backgroundColor = convert_vec4(io->theme->backColor1), }) { gui.text_label("Undo queue"); - std::vector undoList = main.world->undo.get_front_undo_queue_names(10); - for(const char* u : undoList) + std::vector undoList = main.world->undo.get_front_undo_queue_names(10); + for(const std::string& u : undoList) gui.text_label(u); } CLAY_AUTO_ID({ diff --git a/src/WorldUndoManager.cpp b/src/WorldUndoManager.cpp index fb12920..cb81728 100644 --- a/src/WorldUndoManager.cpp +++ b/src/WorldUndoManager.cpp @@ -123,8 +123,8 @@ std::optional WorldUndoManager::get_netid_from_undo return it->second; } -std::vector WorldUndoManager::get_front_undo_queue_names(unsigned count) { - std::vector toRet; +std::vector WorldUndoManager::get_front_undo_queue_names(unsigned count) { + std::vector toRet; for(auto& u : undoQueue | std::views::reverse) { toRet.emplace_back(u->get_name()); if(toRet.size() == count) diff --git a/src/WorldUndoManager.hpp b/src/WorldUndoManager.hpp index f116c80..6a33aa0 100644 --- a/src/WorldUndoManager.hpp +++ b/src/WorldUndoManager.hpp @@ -9,7 +9,7 @@ class WorldUndoManager; class WorldUndoAction { public: - virtual const char* get_name() const = 0; + virtual std::string get_name() const = 0; virtual bool undo(WorldUndoManager& undoMan) = 0; virtual bool redo(WorldUndoManager& undoMan) = 0; virtual void scale_up(const WorldScalar& scaleAmount); @@ -35,7 +35,7 @@ class WorldUndoManager { UndoObjectID get_undoid_from_netid(const NetworkingObjects::NetObjID& netObjID); void register_new_netid_to_existing_undoid(UndoObjectID existingUndoID, const NetworkingObjects::NetObjID& netObjID); std::optional get_netid_from_undoid(UndoObjectID undoID); - std::vector get_front_undo_queue_names(unsigned count); + std::vector get_front_undo_queue_names(unsigned count); World& world; private: