Undo now takes into account list position, and started work on bookmark undo

This commit is contained in:
Yousef Khadadeh 2026-01-02 21:06:13 +03:00
parent 92115957b2
commit 0e22c8ac3e
7 changed files with 64 additions and 16 deletions

View file

@ -58,6 +58,9 @@ namespace NetworkingObjects {
static NetObjOrderedListIterator<T> push_back_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, T* newObj) {
return l->insert_single(l, nullptr, l->end(), l.get_obj_man()->template make_obj_from_ptr<T>(newObj));
}
template <typename ...Args> NetObjOrderedListIterator<T> emplace_direct(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjOrderedListIterator<T>& it, Args&&... items) {
return l->insert_single(l, nullptr, it, l.get_obj_man()->template make_obj_direct<T>(items...));
}
static NetObjOrderedListIterator<T> insert_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjOrderedListIterator<T>& it, T* newObj) {
return l->insert_single(l, nullptr, it, l.get_obj_man()->template make_obj_from_ptr<T>(newObj));
}

View file

@ -11,8 +11,26 @@ void BookmarkData::jump_to(World& world) const {
world.drawData.cam.smooth_move_to(world, coords, windowSize.cast<float>());
}
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>();
nameData->name = initData.name;
if(initData.folderList) {
auto& initFolderList = initData.folderList.value();
folderData = std::make_unique<BookmarkFolderData>();
folderData->folderList = netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>();
for(auto& initFolder : initFolderList)
folderData->folderList->emplace_back_direct(folderData->folderList, netObjMan, initFolder);
}
else
bookmarkData = std::make_unique<BookmarkData>(initData.bookmarkData.value());
}
BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder, const BookmarkData& initBookmarkData) {
if(isFolder) {
folderData = std::make_unique<BookmarkFolderData>();
@ -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<BookmarkCompleteInitData>();
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 {

View file

@ -14,12 +14,20 @@ struct BookmarkData {
template <class Archive> 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<std::vector<BookmarkCompleteInitData>> folderList;
std::optional<BookmarkData> 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:

View file

@ -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<AddGridWorldUndoAction>(g, world.undo.get_undoid_from_netid(it->obj.get_net_id())));
world.undo.push(std::make_unique<AddGridWorldUndoAction>(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<EraseGridWorldUndoAction>(*it->obj, world.undo.get_undoid_from_netid(it->obj.get_net_id())));
world.undo.push(std::make_unique<EraseGridWorldUndoAction>(*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 {

View file

@ -1237,8 +1237,8 @@ void Toolbar::performance_metrics() {
.backgroundColor = convert_vec4<Clay_Color>(io->theme->backColor1),
}) {
gui.text_label("Undo queue");
std::vector<const char*> undoList = main.world->undo.get_front_undo_queue_names(10);
for(const char* u : undoList)
std::vector<std::string> undoList = main.world->undo.get_front_undo_queue_names(10);
for(const std::string& u : undoList)
gui.text_label(u);
}
CLAY_AUTO_ID({

View file

@ -123,8 +123,8 @@ std::optional<NetworkingObjects::NetObjID> WorldUndoManager::get_netid_from_undo
return it->second;
}
std::vector<const char*> WorldUndoManager::get_front_undo_queue_names(unsigned count) {
std::vector<const char*> toRet;
std::vector<std::string> WorldUndoManager::get_front_undo_queue_names(unsigned count) {
std::vector<std::string> toRet;
for(auto& u : undoQueue | std::views::reverse) {
toRet.emplace_back(u->get_name());
if(toRet.size() == count)

View file

@ -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<NetworkingObjects::NetObjID> get_netid_from_undoid(UndoObjectID undoID);
std::vector<const char*> get_front_undo_queue_names(unsigned count);
std::vector<std::string> get_front_undo_queue_names(unsigned count);
World& world;
private: