From 47d7675c0ec6a65e27e9ff69a8bfd34b621effab Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sat, 21 Feb 2015 17:23:30 +0100 Subject: Fix for the performance loss in ungrouping observed by Tavmjong in rev 13933 Added std::list hrefList member to SPObject class. (bzr r13935) --- src/object-test.h | 2 +- src/selection-chemistry.cpp | 3 +-- src/sp-item-group.cpp | 12 ++++-------- src/sp-item-group.h | 2 +- src/sp-object.cpp | 12 +++++++++--- src/sp-object.h | 5 +++-- 6 files changed, 19 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/object-test.h b/src/object-test.h index 4fd3d67b5..06363c372 100644 --- a/src/object-test.h +++ b/src/object-test.h @@ -178,7 +178,7 @@ public: Inkscape::XML::Document *xml_doc = node->document(); TS_TRACE("Benchmarking groups..."); - const size_t num_elements = 2000; + const size_t num_elements = 10000; Inkscape::XML::Node *new_group = xml_doc->createElement("svg:g"); Inkscape::GC::release(new_group); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index e2fbaa73d..5e8fd5e07 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1332,8 +1332,7 @@ void sp_selection_change_layer_maintain_clones(GSList const *items,SPObject *whe if (item) { SPItem *oldparent = dynamic_cast(item->parent); SPItem *newparent = dynamic_cast(where); - sp_item_group_ungroup_handle_clones(item->document->getRoot(), - item, + sp_item_group_ungroup_handle_clones(item, (oldparent->i2doc_affine()) *((newparent->i2doc_affine()).inverse())); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 3c2053cb2..0f76051bc 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -399,10 +399,10 @@ void SPGroup::snappoints(std::vector &p, Inkscape: } } -void sp_item_group_ungroup_handle_clones(SPGroup *group,SPItem *parent, Geom::Affine const g) +void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g) { - for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { - SPItem *citem = dynamic_cast(child); + for(std::list::const_iterator refd=parent->hrefList.begin();refd!=parent->hrefList.end();refd++){ + SPItem *citem = dynamic_cast(*refd); if (citem) { SPUse *useitem = dynamic_cast(citem); if (useitem && useitem->get_original() == parent) { @@ -412,10 +412,6 @@ void sp_item_group_ungroup_handle_clones(SPGroup *group,SPItem *parent, Geom::Af citem->setAttribute("transform", affinestr); g_free(affinestr); } - SPGroup *groupitem = dynamic_cast(citem); - if (groupitem) { - sp_item_group_ungroup_handle_clones(groupitem,parent,g); - } } } } @@ -459,7 +455,7 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) if (SPItem *citem = dynamic_cast(child)) - sp_item_group_ungroup_handle_clones(root,citem,g); + sp_item_group_ungroup_handle_clones(citem,g); for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 4bac0b269..f9a8b88f5 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -102,7 +102,7 @@ public: * @param parent original parent * @param g transform */ -void sp_item_group_ungroup_handle_clones(SPGroup *group,SPItem *parent, Geom::Affine const g); +void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g); void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 7d24a978e..1094b88a7 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -115,7 +115,7 @@ static gchar *sp_object_get_unique_id(SPObject *object, SPObject::SPObject() : cloned(0), uflags(0), mflags(0), hrefcount(0), _total_hrefcount(0), document(NULL), parent(NULL), children(NULL), _last_child(NULL), - next(NULL), id(NULL), repr(NULL), refCount(1), + next(NULL), id(NULL), repr(NULL), refCount(1),hrefList(std::list()), _successor(NULL), _collection_policy(SPObject::COLLECT_WITH_PARENT), _label(NULL), _default_label(NULL) { @@ -254,7 +254,7 @@ SPObject *sp_object_unref(SPObject *object, SPObject *owner) return NULL; } -SPObject *sp_object_href(SPObject *object, gpointer /*owner*/) +SPObject *sp_object_href(SPObject *object, SPObject* owner) { g_return_val_if_fail(object != NULL, NULL); g_return_val_if_fail(SP_IS_OBJECT(object), NULL); @@ -262,10 +262,13 @@ SPObject *sp_object_href(SPObject *object, gpointer /*owner*/) object->hrefcount++; object->_updateTotalHRefCount(1); + if(owner) + object->hrefList.push_front(owner); + return object; } -SPObject *sp_object_hunref(SPObject *object, gpointer /*owner*/) +SPObject *sp_object_hunref(SPObject *object, SPObject* owner) { g_return_val_if_fail(object != NULL, NULL); g_return_val_if_fail(SP_IS_OBJECT(object), NULL); @@ -274,6 +277,9 @@ SPObject *sp_object_hunref(SPObject *object, gpointer /*owner*/) object->hrefcount--; object->_updateTotalHRefCount(-1); + if(owner) + object->hrefList.remove(owner); + return NULL; } diff --git a/src/sp-object.h b/src/sp-object.h index ff80eaefc..ab0b444b6 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -157,7 +157,7 @@ SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL); * \pre object points to real object * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_href(SPObject *object, void* owner); +SPObject *sp_object_href(SPObject *object, SPObject* owner); /** * Decrease weak refcount. @@ -169,7 +169,7 @@ SPObject *sp_object_href(SPObject *object, void* owner); * \pre object points to real object and hrefcount>0 * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_hunref(SPObject *object, void* owner); +SPObject *sp_object_hunref(SPObject *object, SPObject* owner); /** * SPObject is an abstract base class of all of the document nodes at the @@ -218,6 +218,7 @@ private: Inkscape::XML::Node *repr; /* Our xml representation */ public: int refCount; + std::list hrefList; /** * Returns the objects current ID string. -- cgit v1.2.3