lottie/vector: make the pathmesure class thread safe. 80/184680/1
authorsubhransu mohanty <sub.mohanty@samsung.com>
Fri, 20 Jul 2018 06:44:58 +0000 (15:44 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Fri, 20 Jul 2018 06:44:58 +0000 (15:44 +0900)
Change-Id: I10dc4e0a0c6c050bc573c792f819cf91c2982f03

src/vector/vpathmesure.cpp
src/vector/vpathmesure.h

index 52e93e823b9a9d23eac3d333077d75100ad000ab..9e92b04590097ce5b07f3caa280a28d03b7fac9f 100644 (file)
@@ -5,30 +5,80 @@ V_BEGIN_NAMESPACE
 
 struct VPathMesureData
 {
+   VPathMesureData():ref(-1){}
    void        setPath(const VPath &path) { mPath = path; }
-   VPath&      getPath() { return mPath; }
+   VPath&       getPath() { return mPath; }
    VPath       mPath;
+   RefCount    ref;
 };
 
-V_END_NAMESPACE
+static const struct VPathMesureData shared_empty;
+
+inline void VPathMesure::cleanUp(VPathMesureData *d)
+{
+    delete d;
+}
 
-static const struct VPathMesureData shared_empty = {VPath()};
+void VPathMesure::detach()
+{
+    if (d->ref.isShared())
+        *this = copy();
+}
+
+VPathMesure VPathMesure::copy() const
+{
+    VPathMesure other;
+
+    other.d = new VPathMesureData;
+    other.d->mPath = d->mPath;
+    other.d->ref.setOwned();
+    return other;
+}
 
 VPathMesure::~VPathMesure()
 {
+    if (!d->ref.deref())
+        cleanUp(d);
 }
 
 VPathMesure::VPathMesure()
-   : d(const_cast<VPathMesureData*>(&shared_empty))
+    : d(const_cast<VPathMesureData*>(&shared_empty))
+{
+}
+
+VPathMesure::VPathMesure(const VPathMesure &other)
+{
+    d = other.d;
+    d->ref.ref();
+}
+
+VPathMesure::VPathMesure(VPathMesure &&other): d(other.d)
 {
+    other.d = const_cast<VPathMesureData*>(&shared_empty);
 }
 
-VPathMesure::VPathMesure(const VPath *p, bool foceClose)
+VPathMesure &VPathMesure::operator=(const VPathMesure &other)
 {
+    other.d->ref.ref();
+    if (!d->ref.deref())
+        cleanUp(d);
+
+    d = other.d;
+    return *this;
+}
+
+inline VPathMesure &VPathMesure::operator=(VPathMesure &&other)
+{
+    if (!d->ref.deref())
+        cleanUp(d);
+    d = other.d;
+    other.d = const_cast<VPathMesureData*>(&shared_empty);
+    return *this;
 }
 
 void VPathMesure::setStart(float pos)
 {
+   detach();
    VPath &path = d->getPath();
    const std::vector<VPath::Element> &elm = path.elements();
    const std::vector<VPointF> &pts  = path.points();
@@ -168,6 +218,7 @@ void VPathMesure::setStart(float pos)
 
 void VPathMesure::setEnd(float pos)
 {
+   detach();
    VPath &path = d->getPath();
    const std::vector<VPath::Element> &elm = path.elements();
    const std::vector<VPointF> &pts  = path.points();
@@ -299,6 +350,7 @@ void VPathMesure::setEnd(float pos)
 
 void VPathMesure::setPath(const VPath &path)
 {
+   detach();
    d->setPath(path);
 }
 
@@ -306,3 +358,5 @@ VPath VPathMesure::getPath()
 {
    return d->getPath();
 }
+
+V_END_NAMESPACE
index 88fc9fd827823f77f74cd0bb2c0dbde4394414fe..e95c966e73aa39d8be0a033689d4c69c5949ec8e 100644 (file)
@@ -11,13 +11,19 @@ class VPathMesure
 public:
     ~VPathMesure();
     VPathMesure();
-    VPathMesure(const VPath *path, bool foceClose);
+    VPathMesure(const VPathMesure &other);
+    VPathMesure(VPathMesure &&other);
+    VPathMesure &operator=(const VPathMesure &);
+    VPathMesure &operator=(VPathMesure &&other);
     int getLength() const;
     void setPath(const VPath &path);
     VPath getPath();
     void setStart(float pos);
     void setEnd(float pos);
 private:
+    VPathMesure copy() const;
+    void detach();
+    void cleanUp(VPathMesureData *x);
     VPathMesureData *d;
 };