From b9fd39b46909184a521fb322c42792825d92ce54 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Thu, 8 Jan 2026 14:02:37 +0300 Subject: [PATCH] Speed up paste action --- .../DrawingProgramSelection.cpp | 12 +++-- .../Layers/DrawingProgramLayer.cpp | 4 +- .../Layers/DrawingProgramLayerManager.cpp | 52 +++++++++++++------ .../Layers/DrawingProgramLayerManager.hpp | 5 +- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 62a7c51..b276e0d 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -435,12 +435,16 @@ void DrawingProgramSelection::paste_clipboard(Vector2f pasteScreenPos) { newComponentContainer->coords.scale_about(mousePos, scaleMultiplier); placedComponents.emplace_back(drawP.layerMan.get_edited_layer_end_iterator(), newComponentContainer); } - auto newlyInsertedObjectIts = drawP.layerMan.add_many_components_to_layer_being_edited(placedComponents); + std::vector newlyInsertedObjectIts; + drawP.layerMan.disable_add_to_cache_and_commit_update_block([&]() { + newlyInsertedObjectIts = drawP.layerMan.add_many_components_to_layer_being_edited(placedComponents); + }); std::vector compSetInserted; - for(auto& it : newlyInsertedObjectIts) { - drawP.drawCache.erase_component(&(*it)); + for(auto& it : newlyInsertedObjectIts) compSetInserted.emplace_back(&(*it)); - } + parallel_loop_container(compSetInserted, [&drawP = drawP](CanvasComponentContainer::ObjInfo* comp) { + comp->obj->commit_update_dont_invalidate_cache(drawP); + }); set_to_selection(compSetInserted); } } diff --git a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp index d1426fd..a2db2f5 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp @@ -13,10 +13,10 @@ void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListIt auto insertCallback = [&](const CanvasComponentContainer::ObjInfoIterator& c) { c->obj->objInfo = c; c->obj->parentLayer = &layerListItem; - if(layerMan.commitUpdateOnComponentInsert) { + if(layerMan.commitUpdateOnComponentInsert) c->obj->commit_update(layerMan.drawP); // Run commit update on insert so that world bounds are calculated + if(layerMan.addToCacheOnComponentInsert) layerMan.drawP.drawCache.add_component(&(*c)); - } if(c->obj->get_comp().get_type() == CanvasComponentType::IMAGE) layerMan.drawP.updateableComponents.emplace(&(*c)); }; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp index 7194055..c96b048 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerManager.cpp @@ -31,9 +31,9 @@ void DrawingProgramLayerManager::write_components_server(cereal::PortableBinaryO void DrawingProgramLayerManager::read_components_client(cereal::PortableBinaryInputArchive& a) { layerTreeRoot = drawP.world.netObjMan.read_create_message(a, nullptr); - commitUpdateOnComponentInsert = false; - layerTreeRoot->set_component_list_callbacks(*this); - commitUpdateOnComponentInsert = true; + disable_add_to_cache_and_commit_update_block([&]() { + layerTreeRoot->set_component_list_callbacks(*this); + }); auto flattenedCompList = get_flattened_component_list(); parallel_loop_container(flattenedCompList, [&drawP = drawP](CanvasComponentContainer::ObjInfo* comp) { comp->obj->commit_update_dont_invalidate_cache(drawP); @@ -107,6 +107,26 @@ std::vector DrawingProgramLayerManage return {}; } +void DrawingProgramLayerManager::disable_add_to_cache_block(const std::function& toRun) { + addToCacheOnComponentInsert = false; + toRun(); + addToCacheOnComponentInsert = true; +} + +void DrawingProgramLayerManager::disable_commit_update_block(const std::function& toRun) { + commitUpdateOnComponentInsert = false; + toRun(); + commitUpdateOnComponentInsert = true; +} + +void DrawingProgramLayerManager::disable_add_to_cache_and_commit_update_block(const std::function& toRun) { + addToCacheOnComponentInsert = false; + commitUpdateOnComponentInsert = false; + toRun(); + commitUpdateOnComponentInsert = true; + addToCacheOnComponentInsert = true; +} + CanvasComponentContainer::ObjInfo* DrawingProgramLayerManager::add_component_to_layer_being_edited(CanvasComponentContainer* newObj) { auto editLayerPtr = editingLayer.lock(); if(!editLayerPtr) @@ -118,22 +138,22 @@ void DrawingProgramLayerManager::load_file(cereal::PortableBinaryInputArchive& a if(version >= VersionNumber(0, 4, 0)) { layerTreeRoot = drawP.world.netObjMan.make_obj_from_ptr(new DrawingProgramLayerListItem()); layerTreeRoot->load_file(a, version, *this); - commitUpdateOnComponentInsert = false; - layerTreeRoot->get_folder().set_component_list_callbacks(*this); // Only need to call set_component_list_callbacks on root, and the rest will get the callbacks set as well - commitUpdateOnComponentInsert = true; + disable_add_to_cache_and_commit_update_block([&]() { + layerTreeRoot->get_folder().set_component_list_callbacks(*this); // Only need to call set_component_list_callbacks on root, and the rest will get the callbacks set as well + }); } else { server_init_no_file(); - commitUpdateOnComponentInsert = false; - CanvasComponentContainer::NetListTemporaryPtr editingLayerTmpPtrComponents = editingLayer.lock()->get_layer().components; - uint64_t compCount; - a(compCount); - for(uint64_t i = 0; i < compCount; i++) { - CanvasComponentContainer* newContainer = new CanvasComponentContainer(); - newContainer->load_file(a, version, drawP.world.netObjMan); - editingLayerTmpPtrComponents->push_back_and_send_create(editingLayerTmpPtrComponents, newContainer); - } - commitUpdateOnComponentInsert = true; + disable_add_to_cache_and_commit_update_block([&]() { + CanvasComponentContainer::NetListTemporaryPtr editingLayerTmpPtrComponents = editingLayer.lock()->get_layer().components; + uint64_t compCount; + a(compCount); + for(uint64_t i = 0; i < compCount; i++) { + CanvasComponentContainer* newContainer = new CanvasComponentContainer(); + newContainer->load_file(a, version, drawP.world.netObjMan); + editingLayerTmpPtrComponents->push_back_and_send_create(editingLayerTmpPtrComponents, newContainer); + } + }); } auto flattenedCompList = get_flattened_component_list(); parallel_loop_container(flattenedCompList, [&drawP = drawP](CanvasComponentContainer::ObjInfo* comp) { diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerManager.hpp b/src/DrawingProgram/Layers/DrawingProgramLayerManager.hpp index c4a4468..06c9a10 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerManager.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerManager.hpp @@ -17,6 +17,7 @@ class DrawingProgramLayerManager { void add_undo_place_components(DrawingProgramLayerListItem* parent, const std::vector& placeList); void erase_component_map(const std::unordered_map>& eraseMap); bool commitUpdateOnComponentInsert = true; + bool addToCacheOnComponentInsert = true; public: enum class LayerSelector { ALL_VISIBLE_LAYERS, @@ -46,6 +47,9 @@ class DrawingProgramLayerManager { uint32_t edited_layer_component_count(); CanvasComponentContainer::ObjInfoIterator get_edited_layer_end_iterator(); bool component_passes_layer_selector(CanvasComponentContainer::ObjInfo* c, LayerSelector layerSelector); + void disable_add_to_cache_block(const std::function& toRun); + void disable_commit_update_block(const std::function& toRun); + void disable_add_to_cache_and_commit_update_block(const std::function& toRun); void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version); void save_file(cereal::PortableBinaryOutputArchive& a) const; @@ -59,7 +63,6 @@ class DrawingProgramLayerManager { std::vector add_many_components_to_layer_being_edited(const std::vector>& newObjs); std::vector get_flattened_component_list() const; std::vector get_flattened_layer_list(); - void add_undo_place_component(CanvasComponentContainer::ObjInfo* objInfo); DrawingProgramLayerManagerGUI listGUI; };