Speed up paste action

This commit is contained in:
Yousef Khadadeh 2026-01-08 14:02:37 +03:00
parent cf9e8a6848
commit b9fd39b469
4 changed files with 50 additions and 23 deletions

View file

@ -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<CanvasComponentContainer::ObjInfoIterator> newlyInsertedObjectIts;
drawP.layerMan.disable_add_to_cache_and_commit_update_block([&]() {
newlyInsertedObjectIts = drawP.layerMan.add_many_components_to_layer_being_edited(placedComponents);
});
std::vector<CanvasComponentContainer::ObjInfo*> 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);
}
}

View file

@ -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));
};

View file

@ -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<DrawingProgramLayerListItem>(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<CanvasComponentContainer::ObjInfoIterator> DrawingProgramLayerManage
return {};
}
void DrawingProgramLayerManager::disable_add_to_cache_block(const std::function<void()>& toRun) {
addToCacheOnComponentInsert = false;
toRun();
addToCacheOnComponentInsert = true;
}
void DrawingProgramLayerManager::disable_commit_update_block(const std::function<void()>& toRun) {
commitUpdateOnComponentInsert = false;
toRun();
commitUpdateOnComponentInsert = true;
}
void DrawingProgramLayerManager::disable_add_to_cache_and_commit_update_block(const std::function<void()>& 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<DrawingProgramLayerListItem>(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) {

View file

@ -17,6 +17,7 @@ class DrawingProgramLayerManager {
void add_undo_place_components(DrawingProgramLayerListItem* parent, const std::vector<CanvasComponentContainer::ObjInfoIterator>& placeList);
void erase_component_map(const std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfoIterator>>& 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<void()>& toRun);
void disable_commit_update_block(const std::function<void()>& toRun);
void disable_add_to_cache_and_commit_update_block(const std::function<void()>& toRun);
void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
void save_file(cereal::PortableBinaryOutputArchive& a) const;
@ -59,7 +63,6 @@ class DrawingProgramLayerManager {
std::vector<CanvasComponentContainer::ObjInfoIterator> add_many_components_to_layer_being_edited(const std::vector<std::pair<CanvasComponentContainer::ObjInfoIterator, CanvasComponentContainer*>>& newObjs);
std::vector<CanvasComponentContainer::ObjInfo*> get_flattened_component_list() const;
std::vector<DrawingProgramLayerListItem*> get_flattened_layer_list();
void add_undo_place_component(CanvasComponentContainer::ObjInfo* objInfo);
DrawingProgramLayerManagerGUI listGUI;
};