diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 250fa7f..ab67db9 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -112,6 +112,18 @@ namespace NetworkingObjects { } } + template void sort_netobj_ordered_list_iterator_list(const std::list>& l, std::vector>& itListToSort) { + std::stable_sort(itListToSort.begin(), itListToSort.end(), [&l](auto& a, auto& b) { + return b == l.end() || (a != l.end() && a->pos < b->pos); + }); + } + + template void sort_netobj_ordered_list_iterator_insert_list(const std::list>& l, std::vector, NetObjOwnerPtr>>& itListToSort) { + std::stable_sort(itListToSort.begin(), itListToSort.end(), [&l](auto& a, auto& b) { + return b.first == l.end() || (a.first != l.end() && a.first->pos < b.first->pos); + }); + } + template class NetObjOrderedList { public: // Don't use this function unless you're sure that class T isn't a base class @@ -127,7 +139,7 @@ namespace NetworkingObjects { 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)); } - static std::vector> insert_ordered_list_and_send_create(const NetObjTemporaryPtr>& l, const std::vector, T*>>& newObjs) { + static std::vector> insert_sorted_list_and_send_create(const NetObjTemporaryPtr>& l, const std::vector, T*>>& newObjs) { if(newObjs.empty()) return {}; std::vector, NetObjOwnerPtr>> ownerPtrOrderedList; @@ -135,11 +147,26 @@ namespace NetworkingObjects { ownerPtrOrderedList.emplace_back(newObjs[i].first, std::move(l.get_obj_man()->template make_obj_from_ptr(newObjs[i].second))); return l->insert_ordered_list(l, nullptr, ownerPtrOrderedList); } - static std::vector> insert_ordered_list_and_send_create(const NetObjTemporaryPtr>& l, std::vector, NetObjOwnerPtr>>& newObjPtrs) { + static std::vector> insert_sorted_list_and_send_create(const NetObjTemporaryPtr>& l, std::vector, NetObjOwnerPtr>>& newObjPtrs) { if(newObjPtrs.empty()) return {}; return l->insert_ordered_list(l, nullptr, newObjPtrs); } + static std::vector> insert_unsorted_list_and_send_create(const NetObjTemporaryPtr>& l, const std::vector, T*>>& newObjs) { + if(newObjs.empty()) + return {}; + std::vector, NetObjOwnerPtr>> ownerPtrOrderedList; + for(uint32_t i = 0; i < static_cast(newObjs.size()); i++) + ownerPtrOrderedList.emplace_back(newObjs[i].first, std::move(l.get_obj_man()->template make_obj_from_ptr(newObjs[i].second))); + sort_netobj_ordered_list_iterator_insert_list(l, ownerPtrOrderedList); + return l->insert_ordered_list(l, nullptr, ownerPtrOrderedList); + } + static std::vector> insert_unsorted_list_and_send_create(const NetObjTemporaryPtr>& l, std::vector, NetObjOwnerPtr>>& newObjPtrs) { + if(newObjPtrs.empty()) + return {}; + sort_netobj_ordered_list_iterator_insert_list(l, newObjPtrs); + return l->insert_ordered_list(l, nullptr, newObjPtrs); + } static void erase_list(const NetObjTemporaryPtr>& l, const std::vector>& iterators, std::vector>* erasedObjects = nullptr) { l->erase_it_list(l, iterators, erasedObjects); } @@ -257,6 +284,9 @@ namespace NetworkingObjects { toRet.emplace_back(get(id)); return toRet; } + void sort_it_list(std::vector>& itList) const { + sort_netobj_ordered_list_iterator_list(data_list(), itList); + } bool empty() const { return data_list().empty(); } diff --git a/src/Bookmarks/BookmarkManager.cpp b/src/Bookmarks/BookmarkManager.cpp index 05f5393..3e6fafa 100644 --- a/src/Bookmarks/BookmarkManager.cpp +++ b/src/Bookmarks/BookmarkManager.cpp @@ -137,7 +137,7 @@ void BookmarkManager::setup_list_gui(const char* id) { toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - std::vector> insertedIterators = listPtr->insert_ordered_list_and_send_create(listPtr, toInsert); + std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); // Prepare insert list for undo insertParentUndoID = world.undo.get_undoid_from_netid(listObj); @@ -210,7 +210,7 @@ void BookmarkManager::setup_list_gui(const char* id) { toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - parentListPtr->insert_ordered_list_and_send_create(parentListPtr, toInsert); + parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); } }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); return true; @@ -259,7 +259,7 @@ void BookmarkManager::setup_list_gui(const char* id) { toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - listPtr->insert_ordered_list_and_send_create(listPtr, toInsert); + listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); return true; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp index 7dd630b..7c88d2c 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp @@ -139,7 +139,7 @@ void DrawingProgramLayerManager::push_components_to(const std::vectorinsert_ordered_list_and_send_create(components, toInsert); + components->insert_sorted_list_and_send_create(components, toInsert); toEraseList.clear(); }; for(auto& obj : objs) { @@ -190,6 +190,8 @@ void DrawingProgramLayerManager::push_components_to(const std::vector(compNetID); std::vector>> toInsert; std::vector> toErase = components->get_list(moveData.objs); + components->sort_it_list(toErase); // There's a chance that objects could have changed order on the client side, so sort them + std::vector> erasedObjs; std::vector newPos; { @@ -205,7 +207,7 @@ void DrawingProgramLayerManager::push_components_to(const std::vectorinsert_ordered_list_and_send_create(components, toInsert); + components->insert_sorted_list_and_send_create(components, toInsert); *moveData.oldPos = newPos; } }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); @@ -223,7 +225,7 @@ std::vector DrawingProgramLayerManage auto editLayerPtr = editingLayer.lock(); if(!editLayerPtr) throw std::runtime_error("[DrawingProgramLayerManager::add_many_components_to_layer_being_edited] No layer selected!"); - auto toRet = editLayerPtr->get_layer().components->insert_ordered_list_and_send_create(editLayerPtr->get_layer().components, newObjs); + auto toRet = editLayerPtr->get_layer().components->insert_sorted_list_and_send_create(editLayerPtr->get_layer().components, newObjs); add_undo_place_components(editingLayer.lock().get(), toRet); return toRet; } @@ -405,7 +407,7 @@ void DrawingProgramLayerManager::add_undo_erase_components(const std::unordered_ toInsert[i].second = undoMan.world.netObjMan.make_obj_direct(undoMan.world.netObjMan, *insertData.copyData->at(i)); undoMan.register_new_netid_to_existing_undoid(insertData.undoID->at(i), toInsert[i].second.get_net_id()); } - parentListPtr->insert_ordered_list_and_send_create(parentListPtr, toInsert); + parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); insertData.copyData->clear(); } }, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); @@ -530,7 +532,7 @@ void DrawingProgramLayerManager::add_undo_place_components(DrawingProgramLayerLi toInsert[i].second = undoMan.world.netObjMan.make_obj_direct(undoMan.world.netObjMan, *undoPlaceData.copyData.at(i)); undoMan.register_new_netid_to_existing_undoid(undoPlaceData.undoID.at(i), toInsert[i].second.get_net_id()); } - parentListPtr->insert_ordered_list_and_send_create(parentListPtr, toInsert); + parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); undoPlaceData.copyData.clear(); return true; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp index 747d30b..c8d48e9 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp @@ -152,7 +152,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const char* id, bool& hoverin toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - std::vector> insertedIterators = listPtr->insert_ordered_list_and_send_create(listPtr, toInsert); + std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); // Prepare insert list for undo insertParentUndoID = world.undo.get_undoid_from_netid(listObj); @@ -225,7 +225,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const char* id, bool& hoverin toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - parentListPtr->insert_ordered_list_and_send_create(parentListPtr, toInsert); + parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); } }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); return true; @@ -274,7 +274,7 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const char* id, bool& hoverin toInsert.emplace_back(insertIt, std::move(*it)); toInsert.back().second.reassign_ids(); } - listPtr->insert_ordered_list_and_send_create(listPtr, toInsert); + listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); return true;