From caf99a867533fb42a4d44176eff7d7c6347734ca Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 30 Dec 2025 21:18:59 +0300 Subject: [PATCH] Fixed multiple segfault bugs --- .../NetworkingObjects/NetObjOrderedList.hpp | 6 +++--- .../Layers/DrawingProgramLayer.cpp | 20 ++++++++++++++----- .../Layers/DrawingProgramLayer.hpp | 5 ++++- .../Layers/DrawingProgramLayerFolder.cpp | 10 +++++++++- .../Layers/DrawingProgramLayerFolder.hpp | 3 ++- .../Layers/DrawingProgramLayerListItem.cpp | 7 +++++++ .../Layers/DrawingProgramLayerListItem.hpp | 1 + 7 files changed, 41 insertions(+), 11 deletions(-) diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 4e61af3..94a19f2 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -515,18 +515,18 @@ namespace NetworkingObjects { serverIdToDataMap.emplace(newObjs[i].second.get_net_id(), serverIt); } + std::vector> insertedIterators; auto firstInsertedIt = clientData.end(); for(uint32_t i = 0; i < newObjs.size(); i++) { auto& [itToInsertAt, newObj] = newObjs[i]; auto newObjIt = clientData.emplace(itToInsertAt, std::move(newObj), itToInsertAt == clientData.end() ? clientData.size() : itToInsertAt->pos); // All position values will be wrong except the first one, which is all that matters clientIdToDataMap.emplace(newObjIt->obj.get_net_id(), newObjIt); + insertedIterators.emplace_back(newObjIt); if(i == 0) firstInsertedIt = newObjIt; } set_position_obj_info_list(firstInsertedIt, clientData.end()); - - for(auto& newObj : newObjs) - this->call_insert_callback(newObj.first); + this->call_insert_callback_list(insertedIterators); break; } diff --git a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp index 7632cea..7cd0df5 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp @@ -8,16 +8,16 @@ void DrawingProgramLayer::draw(SkCanvas* canvas, const DrawData& drawData) const p.obj->draw(canvas, drawData); } -void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) const { - components->set_insert_callback([&](const CanvasComponentContainer::ObjInfoIterator& c) { +void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) { + auto insertCallback = [&](const CanvasComponentContainer::ObjInfoIterator& c) { c->obj->objInfo = c; c->obj->parentLayer = &layerListItem; c->obj->commit_update(layerMan.drawP); // Run commit update on insert so that world bounds are calculated layerMan.drawP.drawCache.add_component(&(*c)); if(c->obj->get_comp().get_type() == CanvasComponentType::IMAGE) layerMan.drawP.updateableComponents.emplace(&(*c)); - }); - components->set_erase_callback([&](const CanvasComponentContainer::ObjInfoIterator& c) { + }; + eraseCallback = [&](const CanvasComponentContainer::ObjInfoIterator& c) { layerMan.drawP.selection.erase_component(&(*c)); layerMan.drawP.drawCache.erase_component(&(*c)); layerMan.drawP.drawTool->erase_component(&(*c)); @@ -25,10 +25,20 @@ void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListIt return downloadingFile.comp == &(*c); }); layerMan.drawP.updateableComponents.erase(&(*c)); - }); + }; + components->set_insert_callback(insertCallback); + components->set_erase_callback(eraseCallback); components->set_move_callback([&](const CanvasComponentContainer::ObjInfoIterator& c, uint32_t oldPos) { layerMan.drawP.drawCache.invalidate_cache_at_aabb(c->obj->get_world_bounds()); }); + // Make sure the insert callback is called on existing objects + for(auto it = components->begin(); it != components->end(); ++it) + insertCallback(it); +} + +void DrawingProgramLayer::set_to_erase() { + for(auto it = components->begin(); it != components->end(); ++it) + eraseCallback(it); } void DrawingProgramLayer::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const { diff --git a/src/DrawingProgram/Layers/DrawingProgramLayer.hpp b/src/DrawingProgram/Layers/DrawingProgramLayer.hpp index d73d186..8e01134 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayer.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayer.hpp @@ -9,9 +9,12 @@ class DrawingProgramLayerManager; class DrawingProgramLayer { public: void draw(SkCanvas* canvas, const DrawData& drawData) const; - void set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) const; + void set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan); void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const; void get_flattened_component_list(std::vector& objList) const; + void set_to_erase(); CanvasComponentContainer::NetListOwnerPtr components; + private: + std::function eraseCallback; }; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.cpp index dbbdae6..1acbf47 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.cpp @@ -8,14 +8,22 @@ void DrawingProgramLayerFolder::draw(SkCanvas* canvas, const DrawData& drawData) p.obj->draw(canvas, drawData); } -void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const { +void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) { folderList->set_insert_callback([&](auto& c) { c->obj->set_component_list_callbacks(layerMan); }); + folderList->set_erase_callback([&](auto& c) { + c->obj->set_to_erase(); + }); for(auto& listItem : *folderList) listItem.obj->set_component_list_callbacks(layerMan); } +void DrawingProgramLayerFolder::set_to_erase() { + for(auto& listItem : *folderList) + listItem.obj->set_to_erase(); +} + void DrawingProgramLayerFolder::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const { for(auto& listItem : *folderList) listItem.obj->commit_update_dont_invalidate_cache(layerMan); diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp index 21497cc..0f0892b 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp @@ -10,9 +10,10 @@ class DrawingProgramLayerManager; class DrawingProgramLayerFolder { public: void draw(SkCanvas* canvas, const DrawData& drawData) const; - void set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const; + void set_component_list_callbacks(DrawingProgramLayerManager& layerMan); void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const; void get_flattened_component_list(std::vector& objList) const; + void set_to_erase(); NetworkingObjects::NetObjOwnerPtr> folderList; bool isFolderOpen = false; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.cpp index 0de1a62..9429eff 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.cpp @@ -32,6 +32,13 @@ void DrawingProgramLayerListItem::reassign_netobj_ids_call() { displayData.reassign_ids(); } +void DrawingProgramLayerListItem::set_to_erase() { + if(folderData) + folderData->set_to_erase(); + else + layerData->set_to_erase(); +} + void DrawingProgramLayerListItem::set_component_list_callbacks(DrawingProgramLayerManager &layerMan) { if(folderData) folderData->set_component_list_callbacks(layerMan); diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp index 2dfe8ff..d34a6c7 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp @@ -21,6 +21,7 @@ class DrawingProgramLayerListItem { DrawingProgramLayer& get_layer() const; static void register_class(World& w); void reassign_netobj_ids_call(); + void set_to_erase(); void set_component_list_callbacks(DrawingProgramLayerManager &layerMan); void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan); void draw(SkCanvas* canvas, const DrawData& drawData) const;