diff options
| author | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-07-11 12:24:52 +0000 |
|---|---|---|
| committer | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-07-11 12:24:52 +0000 |
| commit | 058e95a59ccb2ab1748392acdfdbbffd516c9c81 (patch) | |
| tree | 86e3958aaad129307f45e590269924b14bca303d /src | |
| parent | Added simple test for SPObject (diff) | |
| download | inkscape-058e95a59ccb2ab1748392acdfdbbffd516c9c81.tar.gz inkscape-058e95a59ccb2ab1748392acdfdbbffd516c9c81.zip | |
First part of new SPObject children list
(bzr r14954.1.17)
Diffstat (limited to 'src')
| -rw-r--r-- | src/layer-fns.cpp | 36 | ||||
| -rw-r--r-- | src/object-set.cpp | 18 | ||||
| -rw-r--r-- | src/selection-chemistry.cpp | 6 | ||||
| -rw-r--r-- | src/sp-item-group.cpp | 5 | ||||
| -rw-r--r-- | src/sp-item.cpp | 41 | ||||
| -rw-r--r-- | src/sp-mask.cpp | 15 | ||||
| -rw-r--r-- | src/sp-object.cpp | 124 | ||||
| -rw-r--r-- | src/sp-object.h | 29 | ||||
| -rw-r--r-- | src/ui/widget/layer-selector.cpp | 20 | ||||
| -rw-r--r-- | src/uri-references.cpp | 2 |
10 files changed, 139 insertions, 157 deletions
diff --git a/src/layer-fns.cpp b/src/layer-fns.cpp index 3e794a0a4..d149089db 100644 --- a/src/layer-fns.cpp +++ b/src/layer-fns.cpp @@ -36,11 +36,9 @@ bool is_layer(SPObject &object) { * @returns NULL if there are no further layers under a parent */ SPObject *next_sibling_layer(SPObject *layer) { - using std::find_if; - - return find_if<SPObject::SiblingIterator>( - layer->getNext(), NULL, &is_layer - ); + SPObject::ChildrenList &list = layer->parent->_children; + auto l = std::find_if(++list.iterator_to(*layer), list.end(), &is_layer); + return l != list.end() ? &*l : nullptr; } /** Finds the previous sibling layer for a \a layer @@ -50,11 +48,9 @@ SPObject *next_sibling_layer(SPObject *layer) { SPObject *previous_sibling_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; - SPObject *sibling(find_last_if<SPObject::SiblingIterator>( - layer->parent->firstChild(), layer, &is_layer - )); - - return ( sibling != layer ) ? sibling : NULL; + SPObject::ChildrenList &list = layer->parent->_children; + auto l = find_last_if(list.begin(), list.iterator_to(*layer), &is_layer); + return l != list.iterator_to(*layer) ? &*(l) : nullptr; } /** Finds the first child of a \a layer @@ -62,16 +58,15 @@ SPObject *previous_sibling_layer(SPObject *layer) { * @returns NULL if layer has no sublayers */ SPObject *first_descendant_layer(SPObject *layer) { - using std::find_if; - - SPObject *first_descendant=NULL; - while (layer) { - layer = find_if<SPObject::SiblingIterator>( - layer->firstChild(), NULL, &is_layer - ); - if (layer) { + SPObject *first_descendant = nullptr; + while (true) { + auto tmp = std::find_if(layer->_children.begin(), layer->_children.end(), &is_layer); + if (tmp != layer->_children.end()) { first_descendant = layer; + } else { + break; } + layer = &*tmp; } return first_descendant; @@ -84,9 +79,8 @@ SPObject *first_descendant_layer(SPObject *layer) { SPObject *last_child_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; - return find_last_if<SPObject::SiblingIterator>( - layer->firstChild(), NULL, &is_layer - ); + auto l = find_last_if(layer->_children.begin(), layer->_children.end(), &is_layer); + return l != layer->_children.end() ? &*l : nullptr; } SPObject *last_elder_layer(SPObject *root, SPObject *layer) { diff --git a/src/object-set.cpp b/src/object-set.cpp index 07f9ea0c8..b7b84e163 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -93,14 +93,14 @@ bool ObjectSet::_anyAncestorIsInSet(SPObject *object) { } void ObjectSet::_removeDescendantsFromSet(SPObject *object) { - for (auto& child: object->childList(false)) { - if (includes(child)) { - _remove(child); + for (auto& child: object->_children) { + if (includes(&child)) { + _remove(&child); // there is certainly no children of this child in the set continue; } - _removeDescendantsFromSet(child); + _removeDescendantsFromSet(&child); } } @@ -130,8 +130,8 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { bool flag = true; while (o->parent != nullptr) { - for (auto &child: o->parent->childList(false)) { - if(child != o && !includes(child)) { + for (auto &child: o->parent->_children) { + if(&child != o && !includes(&child)) { flag = false; break; } @@ -147,9 +147,9 @@ SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { void ObjectSet::_removeAncestorsFromSet(SPObject *object) { SPObject* o = object; while (o->parent != nullptr) { - for (auto &child: o->parent->childList(false)) { - if (child != o) { - _add(child); + for (auto &child: o->parent->_children) { + if (&child != o) { + _add(&child); } } if (includes(o->parent)) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 4b5c3f921..1f34f798d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -4261,11 +4261,11 @@ static void itemtree_map(void (*f)(SPItem *, SPDesktop *), SPObject *root, SPDes f(item, desktop); } } - for ( SPObject::SiblingIterator iter = root->firstChild() ; iter ; ++iter ) { + for (auto& child: root->_children) { //don't recurse into locked layers - SPItem *item = dynamic_cast<SPItem *>(&*iter); + SPItem *item = dynamic_cast<SPItem *>(&child); if (!(item && desktop->isLayer(item) && item->isLocked())) { - itemtree_map(f, iter, desktop); + itemtree_map(f, &child, desktop); } } } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 70d2bc732..d775e306f 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -297,9 +297,8 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox } void SPGroup::print(SPPrintContext *ctx) { - std::vector<SPObject*> l=this->childList(false); - for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){ - SPObject *o = *i; + for(auto& child: _children){ + SPObject *o = &child; SPItem *item = dynamic_cast<SPItem *>(o); if (item) { item->invoke_print(ctx); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 9fd6e8ecc..258a5cd14 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -308,50 +308,35 @@ bool is_item(SPObject const &object) { void SPItem::raiseToTop() { using Inkscape::Algorithms::find_last_if; - SPObject *topmost=find_last_if<SPObject::SiblingIterator>( - next, NULL, &is_item - ); - if (topmost) { + auto topmost = find_last_if(++parent->_children.iterator_to(*this), parent->_children.end(), &is_item); + if (topmost != parent->_children.end()) { getRepr()->parent()->changeOrder( getRepr(), topmost->getRepr() ); } } void SPItem::raiseOne() { - SPObject *next_higher=std::find_if<SPObject::SiblingIterator>( - next, NULL, &is_item - ); - if (next_higher) { + auto next_higher = std::find_if(++parent->_children.iterator_to(*this), parent->_children.end(), &is_item); + if (next_higher != parent->_children.end()) { Inkscape::XML::Node *ref = next_higher->getRepr(); getRepr()->parent()->changeOrder(getRepr(), ref); } } void SPItem::lowerOne() { - using Inkscape::Util::MutableList; - using Inkscape::Util::reverse_list; - - MutableList<SPObject &> next_lower=std::find_if( - reverse_list<SPObject::SiblingIterator>( - parent->firstChild(), this - ), - MutableList<SPObject &>(), - &is_item - ); - if (next_lower) { - ++next_lower; - Inkscape::XML::Node *ref = ( next_lower ? next_lower->getRepr() : NULL ); + using Inkscape::Algorithms::find_last_if; + + auto next_lower = find_last_if(parent->_children.begin(), parent->_children.iterator_to(*this), &is_item); + if (next_lower != parent->_children.iterator_to(*this)) { + next_lower--; + Inkscape::XML::Node *ref = next_lower->getRepr(); getRepr()->parent()->changeOrder(getRepr(), ref); } } void SPItem::lowerToBottom() { - using Inkscape::Algorithms::find_last_if; - using Inkscape::Util::MutableList; - using Inkscape::Util::reverse_list; - - SPObject * bottom=parent->firstChild(); - while(dynamic_cast<SPObject*>(bottom) && dynamic_cast<SPObject*>(bottom->next) && bottom!=this && !is_item(*(bottom->next))) bottom=bottom->next; - if (bottom && bottom != this) { + auto bottom = std::find_if(parent->_children.begin(), parent->_children.iterator_to(*this), &is_item); + if (bottom != parent->_children.iterator_to(*this)) { + bottom--; Inkscape::XML::Node *ref = bottom->getRepr() ; parent->getRepr()->changeOrder(getRepr(), ref); } diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 3537c7bac..a36d8ef29 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -138,12 +138,8 @@ void SPMask::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPObject *> children = this->childList(false); - for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { - sp_object_ref(*child); - } - - + std::vector<SPObject *> children = this->childList(true); + for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->updateDisplay(ctx, flags); @@ -172,11 +168,8 @@ void SPMask::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPObject *> children = this->childList(false); - for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { - sp_object_ref(*child); - } - + std::vector<SPObject *> children = this->childList(true); + for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->emitModified(flags); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index d1659eedc..36957ab49 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -7,8 +7,9 @@ * Stephen Silver <sasilver@users.sourceforge.net> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 1999-2008 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -16,6 +17,7 @@ #include <cstring> #include <string> +#include <boost/range/adaptor/transformed.hpp> #include "helper/sp-marshal.h" #include "xml/node-event-vector.h" @@ -398,13 +400,12 @@ void SPObject::changeCSS(SPCSSAttr *css, gchar const *attr) } std::vector<SPObject*> SPObject::childList(bool add_ref, Action) { - std::vector<SPObject*> l; - for ( SPObject *child = firstChild() ; child; child = child->getNext() ) { + std::vector<SPObject*> l; + for (auto& child: _children) { if (add_ref) { - sp_object_ref (child); + sp_object_ref(&child); } - - l.push_back(child); + l.push_back(&child); } return l; @@ -467,9 +468,9 @@ void SPObject::requestOrphanCollection() { } void SPObject::_sendDeleteSignalRecursive() { - for (SPObject *child = firstChild(); child; child = child->getNext()) { - child->_delete_signal.emit(child); - child->_sendDeleteSignalRecursive(); + for (auto& child: _children) { + child._delete_signal.emit(&child); + child._sendDeleteSignalRecursive(); } } @@ -497,12 +498,12 @@ void SPObject::deleteObject(bool propagate, bool propagate_descendants) void SPObject::cropToObject(SPObject *except) { std::vector<SPObject*> toDelete; - for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - if (child->isAncestorOf(except)) { - child->cropToObject(except); - } else if(child != except) { - toDelete.push_back(child); + for (auto& child: _children) { + if (SP_IS_ITEM(&child)) { + if (child.isAncestorOf(except)) { + child.cropToObject(except); + } else if(&child != except) { + toDelete.push_back(&child); } } } @@ -525,6 +526,12 @@ void SPObject::attach(SPObject *object, SPObject *prev) object->parent = this; this->_updateTotalHRefCount(object->_total_hrefcount); + auto it = _children.begin(); + if (prev != nullptr) { + it = ++_children.iterator_to(*prev); + } + _children.insert(it, *object); + SPObject *next; if (prev) { next = prev->next; @@ -541,43 +548,47 @@ void SPObject::attach(SPObject *object, SPObject *prev) object->xml_space.value = this->xml_space.value; } -void SPObject::reorder(SPObject *prev) -{ - //g_return_if_fail(object != NULL); - //g_return_if_fail(SP_IS_OBJECT(object)); - g_return_if_fail(this->parent != NULL); - g_return_if_fail(this != prev); - g_return_if_fail(!prev || SP_IS_OBJECT(prev)); - g_return_if_fail(!prev || prev->parent == this->parent); +void SPObject::reorder(SPObject* obj, SPObject* prev) { + g_return_if_fail(obj != nullptr); + g_return_if_fail(obj->parent); + g_return_if_fail(obj->parent == this); + g_return_if_fail(obj != prev); + g_return_if_fail(!prev || prev->parent == obj->parent); + + auto it = _children.begin(); + if (prev != nullptr) { + it = ++_children.iterator_to(*prev); + } + + _children.splice(it, _children, _children.iterator_to(*obj)); - SPObject *const parent=this->parent; SPObject *old_prev=NULL; - for ( SPObject *child = parent->children ; child && child != this ; + for ( SPObject *child = children ; child && child != obj ; child = child->next ) { old_prev = child; } - SPObject *next=this->next; + SPObject *next=obj->next; if (old_prev) { old_prev->next = next; } else { - parent->children = next; + children = next; } if (!next) { - parent->_last_child = old_prev; + _last_child = old_prev; } if (prev) { next = prev->next; - prev->next = this; + prev->next = obj; } else { - next = parent->children; - parent->children = this; + next = children; + children = obj; } - this->next = next; + obj->next = next; if (!next) { - parent->_last_child = this; + _last_child = obj; } } @@ -589,6 +600,7 @@ void SPObject::detach(SPObject *object) g_return_if_fail(SP_IS_OBJECT(object)); g_return_if_fail(object->parent == this); + _children.erase(_children.iterator_to(*object)); object->releaseReferences(); SPObject *prev=NULL; @@ -618,14 +630,14 @@ void SPObject::detach(SPObject *object) SPObject *SPObject::get_child_by_repr(Inkscape::XML::Node *repr) { g_return_val_if_fail(repr != NULL, NULL); - SPObject *result = 0; + SPObject *result = nullptr; - if ( _last_child && (_last_child->getRepr() == repr) ) { - result = _last_child; // optimization for common scenario + if (_children.size() > 0 && _children.back().getRepr() == repr) { + result = &_children.back(); // optimization for common scenario } else { - for ( SPObject *child = children ; child ; child = child->next ) { - if ( child->getRepr() == repr ) { - result = child; + for (auto& child: _children) { + if (child.getRepr() == repr) { + result = &child; break; } } @@ -656,10 +668,12 @@ void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) void SPObject::release() { SPObject* object = this; - debug("id=%p, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); - while (object->children) { - object->detach(object->children); + auto tmp = _children | boost::adaptors::transformed([](SPObject& obj){return &obj;}); + std::vector<SPObject *> toRelease(tmp.begin(), tmp.end()); + + for (auto& p: toRelease) { + object->detach(p); } } @@ -680,7 +694,7 @@ void SPObject::order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node * / SPObject *ochild = object->get_child_by_repr(child); g_return_if_fail(ochild != NULL); SPObject *prev = new_ref ? object->get_child_by_repr(new_ref) : NULL; - ochild->reorder(prev); + object->reorder(ochild, prev); ochild->_position_changed_signal.emit(ochild); } @@ -1523,33 +1537,33 @@ bool SPObject::setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool return true; } -SPObject * SPObject::findFirstChild(gchar const *tagname) const +SPObject* SPObject::findFirstChild(gchar const *tagname) const { - for (SPObject *child = children; child; child = child->next) + for (auto& child: const_cast<SPObject*>(this)->_children) { - if (child->repr->type() == Inkscape::XML::ELEMENT_NODE && - !strcmp(child->repr->name(), tagname)) { - return child; + if (child.repr->type() == Inkscape::XML::ELEMENT_NODE && + !strcmp(child.repr->name(), tagname)) { + return &child; } } - return NULL; + return nullptr; } char* SPObject::textualContent() const { GString* text = g_string_new(""); - for (const SPObject *child = firstChild(); child; child = child->next) + for (auto& child: _children) { - Inkscape::XML::NodeType child_type = child->repr->type(); + Inkscape::XML::NodeType child_type = child.repr->type(); if (child_type == Inkscape::XML::ELEMENT_NODE) { - char* new_string = child->textualContent(); + char* new_string = child.textualContent(); g_string_append(text, new_string); g_free(new_string); } else if (child_type == Inkscape::XML::TEXT_NODE) { - g_string_append(text, child->repr->content()); + g_string_append(text, child.repr->content()); } } return g_string_free(text, FALSE); @@ -1566,8 +1580,8 @@ void SPObject::recursivePrintTree( unsigned level ) std::cout << " "; } std::cout << (getId()?getId():"No object id") << std::endl; - for (SPObject *child = children; child; child = child->next) { - child->recursivePrintTree( level+1 ); + for (auto& child: _children) { + child.recursivePrintTree(level + 1); } } diff --git a/src/sp-object.h b/src/sp-object.h index 70d3e5df5..6aa006283 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -6,8 +6,9 @@ * Lauris Kaplinski <lauris@kaplinski.com> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 1999-2002 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -53,6 +54,7 @@ class SPObject; #include <sigc++/functors/slot.h> #include <sigc++/signal.h> #include <vector> +#include <boost/intrusive/list.hpp> #include "version.h" #include "util/forward-pointer-iterator.h" @@ -216,6 +218,7 @@ private: char *id; /* Our very own unique id */ Inkscape::XML::Node *repr; /* Our xml representation */ + public: int refCount; std::list<SPObject*> hrefList; @@ -279,17 +282,9 @@ public: return object->parent; } }; - /// Switch containing next() method. - struct SiblingIteratorStrategy { - static SPObject const *next(SPObject const *object) { - return object->next; - } - }; typedef Inkscape::Util::ForwardPointerIterator<SPObject, ParentIteratorStrategy> ParentIterator; typedef Inkscape::Util::ForwardPointerIterator<SPObject const, ParentIteratorStrategy> ConstParentIterator; - typedef Inkscape::Util::ForwardPointerIterator<SPObject, SiblingIteratorStrategy> SiblingIterator; - typedef Inkscape::Util::ForwardPointerIterator<SPObject const, SiblingIteratorStrategy> ConstSiblingIterator; bool isSiblingOf(SPObject const *object) const { if (object == NULL) return false; @@ -317,7 +312,7 @@ public: */ SPObject *getPrev(); - bool hasChildren() const { return ( children != NULL ); } + bool hasChildren() const { return ( _children.size() > 0 ); } SPObject *firstChild() { return children; } SPObject const *firstChild() const { return children; } @@ -681,9 +676,9 @@ public: void attach(SPObject *object, SPObject *prev); /** - * In list of object's siblings, move object behind prev. + * In list of object's children, move object behind prev. */ - void reorder(SPObject *prev); + void reorder(SPObject* obj, SPObject *prev); /** * Remove object from parent's children, release and unref it. @@ -858,7 +853,17 @@ protected: virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); + typedef boost::intrusive::list_member_hook<> ListHook; + ListHook _child_hook; public: + typedef boost::intrusive::list< + SPObject, + boost::intrusive::member_hook< + SPObject, + ListHook, + &SPObject::_child_hook + >> ChildrenList; + ChildrenList _children; virtual void read_content(); void recursivePrintTree(unsigned level = 0); // For debugging diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index 1a9ce617f..46a0b3547 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -19,6 +19,8 @@ #include "ui/dialog/layer-properties.h" #include <glibmm/i18n.h> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/adaptor/reversed.hpp> #include "desktop.h" @@ -348,27 +350,17 @@ void LayerSelector::_buildSiblingEntries( unsigned depth, SPObject &parent, Inkscape::Util::List<SPObject &> hierarchy ) { - using Inkscape::Util::List; using Inkscape::Util::rest; - using Inkscape::Util::reverse_list_in_place; - using Inkscape::Util::filter_list; - Inkscape::Util::List<SPObject &> siblings( - reverse_list_in_place( - filter_list<SPObject::SiblingIterator>( - is_layer(_desktop), parent.firstChild(), NULL - ) - ) - ); + auto siblings = parent._children | boost::adaptors::filtered(is_layer(_desktop)) | boost::adaptors::reversed; SPObject *layer( hierarchy ? &*hierarchy : NULL ); - while (siblings) { - _buildEntry(depth, *siblings); - if ( &*siblings == layer ) { + for (auto& sib: siblings) { + _buildEntry(depth, sib); + if ( &sib == layer ) { _buildSiblingEntries(depth+1, *layer, rest(hierarchy)); } - ++siblings; } } diff --git a/src/uri-references.cpp b/src/uri-references.cpp index db46a156f..078834131 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -92,7 +92,7 @@ bool URIReference::_acceptObject(SPObject *obj) const g_warning("cloned object with no known type\n"); return false; } - for (int i = positions.size() - 2; i >= 0; i--) + for (int i = (int) (positions.size() - 2); i >= 0; i--) owner = owner->childList(false)[positions[i]]; } // once we have the "original" object (hopefully) we look at who is referencing it |
