[Marble-devel] Review Request 120004: Solve copy problems by adding missing detach() calls. Other minor fixes.
Calin Cruceru
calin at rosedu.org
Wed Sep 3 21:09:07 UTC 2014
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://git.reviewboard.kde.org/r/120004/
-----------------------------------------------------------
(Updated Sept. 4, 2014, 12:09 a.m.)
Review request for Marble.
Changes
-------
Added 2 tests to show what this patch actually fixes.
Also removed the detach() call from GeoDataFeature::abstractView() because it didn't make any sense since the GeoDataAbstractView pointer is simply assigned in GeoDataFeaturePrivate::operator= (when a new object should be created, and use setParent->this() and delete it in the destructor of the private class, just as GeoDataContainer does).
Repository: marble
Description
-------
So I witnessed some time ago that the copy of GeoDataGeometry based classes did not work as expected and I figured out that the main cause were some missing detach() calls in functions returning either non-const references or pointer to some non-const member, which made possible their modification without creating a new *Private instance.
* This patch adds those missing detach() calls on all GeoDataGeometry and GeoDataFeature based classes (shout me if we are using this technique in other classes so I can take a look there as well).
* There is also one important change I thought of in GeoDataPlacemark. Before, in the copy constructor, we used to do p()->m_geometry->setParent( this ) which broke the invariant m_geometry->parent() == this for other. However, there was one more problem: when detach() was called for the first time, the newly created geometry (in GeoDataPlacemarkPrivate) did not have a parent set (it was zeroed) so after a GeoDataPlacemark copy was done, the other geometry's parent would point to the old placemark and the newly created (not immediately, but after the first detach() call) placemark wouldn't have its parent set at all. So, as a workaround, I added p()->m_geometry->setParent(this) after each detach() call in GeoDataPlacemark and removed the call from the copy constructor, so that the invariant is only broken for this, but only until the first detach() call and then each geometry correctly points to its parent.
* I also added two new methods to GeoDataFeature. extendedData() and region() did not have both non-const and const getters, but they had a, in case of region, GeoDataRegion& region() const;, which didn't allow the call to detach() but at the same time returned a non-const reference - you don't do something like this usually, do you? The same as above applies here too - tell me if this had some hidden purpose. I can only tell it compiles and all existing tests pass, but I may miss something.
* One other minor fix is that the equality operators in GeoDataLink are now const, as they should (this is totally unrelated, but I got over this while testing something - I don't remember exactly what).
* I also removed the virtual void detach() method in GeoDataPoint(). It was only calling GeoDataGeometry::detach() - same as above, tell me if this should stay since it may have some purpose.
* GeoDataTourPrivate now inherits GeoDataFeaturePrivate so that GeoDataTour can use detach() when getting non-const pointer to m_playlist or setting playlist - before, there was no copy constructor in the Private class and the two object pointed to the same GeoDataPlaylist object after copying. I also removed the copy constructor in GeoDataTour and operator= which are no longer needed with the detach() approach.
There is one thing I did not find a solution for and may be a problem: the folderList(), placemarkList() and featureList() methods in GeoDataContainare are marked as const but return QVector<GeoDataFeature*> so it may be possible to modify some GeoDataFeature objects through those pointers immediately after a copy of GeoDataContainer, without calling detach() - so it would affect members of the copied object.
Diffs (updated)
-----
src/lib/marble/geodata/data/GeoDataContainer.cpp f0fae00
src/lib/marble/geodata/data/GeoDataFeature.cpp 9b354a2
src/lib/marble/geodata/data/GeoDataGeometry.cpp 8dfdd52
src/lib/marble/geodata/data/GeoDataMultiGeometry.cpp 7c6d148
src/lib/marble/geodata/data/GeoDataMultiGeometry_p.h df96074
src/lib/marble/geodata/data/GeoDataMultiTrack.cpp 9cc89bc
src/lib/marble/geodata/data/GeoDataPlacemark.cpp b2d0304
src/lib/marble/geodata/data/GeoDataPoint.h 401b25f
src/lib/marble/geodata/data/GeoDataPoint.cpp 8c5d9c9
src/lib/marble/geodata/data/GeoDataPoint_p.h a7c19e0
src/lib/marble/geodata/data/GeoDataPolygon.cpp b8e0f32
src/plugins/render/annotate/AnnotatePlugin.cpp b1c8072
tests/CMakeLists.txt 47b2c68
tests/TestFeatureDetach.cpp PRE-CREATION
tests/TestGeometryDetach.cpp PRE-CREATION
Diff: https://git.reviewboard.kde.org/r/120004/diff/
Testing
-------
Thanks,
Calin Cruceru
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/marble-devel/attachments/20140903/9998139e/attachment.html>
More information about the Marble-devel
mailing list