lottie: refactor model class to remove visitor 54/188554/3
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 6 Sep 2018 04:45:17 +0000 (13:45 +0900)
committerYoungbok Shin <youngb.shin@samsung.com>
Thu, 6 Sep 2018 11:35:10 +0000 (11:35 +0000)
now visitor class will use the lotnode->type to visit the tree
and all the model class don't have to pay the virtual pointer overhead.

Change-Id: Ie98d5e369c9f30c94222898849a6da5d0b82938c

src/lottie/lottieitem.cpp
src/lottie/lottiemodel.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp

index 56a4532..c113ea9 100644 (file)
@@ -318,11 +318,9 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel)
 {
     // 1. create layer item
     for (auto &i : mLayerData->mChildren) {
-        LOTLayerData *layerModel = dynamic_cast<LOTLayerData *>(i.get());
-        if (layerModel) {
-            auto layerItem = LOTCompItem::createLayerItem(layerModel);
-            if (layerItem) mLayers.push_back(std::move(layerItem));
-        }
+        LOTLayerData *layerModel = static_cast<LOTLayerData *>(i.get());
+        auto layerItem = LOTCompItem::createLayerItem(layerModel);
+        if (layerItem) mLayers.push_back(std::move(layerItem));
     }
 
     // 2. update parent layer
index bbbaba2..38179a9 100644 (file)
@@ -3,25 +3,12 @@
 #include <cassert>
 #include <stack>
 
-class LottieRepeaterProcesser : public LOTDataVisitor {
+class LottieRepeaterProcesser {
 public:
-    void visit(LOTCompositionData *) override {}
-    void visit(LOTLayerData *) override {}
-    void visit(LOTTransformData *) override {}
-    void visit(LOTShapeGroupData *) override {}
-    void visit(LOTShapeData *) override {}
-    void visit(LOTRectData *) override {}
-    void visit(LOTEllipseData *) override {}
-    void visit(LOTTrimData *) override {}
-    void visit(LOTRepeaterData *) override { mRepeaterFound = true; }
-    void visit(LOTFillData *) override {}
-    void visit(LOTStrokeData *) override {}
-    void visit(LOTPolystarData *) override {}
-    void visitChildren(LOTGroupData *obj) override
+    void visitChildren(LOTGroupData *obj)
     {
         for (const auto& child : obj->mChildren) {
-            child.get()->accept(this);
-            if (mRepeaterFound) {
+            if (child->mType == LOTData::Type::Repeater) {
                 LOTRepeaterData *repeater =
                     static_cast<LOTRepeaterData *>(child.get());
                 std::shared_ptr<LOTShapeGroupData> sharedShapeGroup =
@@ -33,26 +20,31 @@ public:
                 // the repeater object.
                 for (const auto& cpChild : obj->mChildren) {
                     if (cpChild == child) break;
-                    // there shouldn't be any trim object left in the child list
-                    if (cpChild.get()->type() == LOTData::Type::Trim) {
-                        assert(0);
-                    }
                     shapeGroup->mChildren.push_back(cpChild);
                 }
-                mRepeaterFound = false;
             }
         }
     }
 
-public:
-    bool mRepeaterFound{false};
+    void visit(LOTData *obj) {
+        switch (obj->mType) {
+        case LOTData::Type::Repeater:
+        case LOTData::Type::ShapeGroup:
+        case LOTData::Type::Layer:{
+            visitChildren(static_cast<LOTGroupData *>(obj));
+            break;
+        }
+        default:
+            break;
+        }
+    }
 };
 
 
 void LOTCompositionData::processRepeaterObjects()
 {
     LottieRepeaterProcesser visitor;
-    accept(&visitor);
+    visitor.visit(mRootLayer.get());
 }
 
 VMatrix LOTTransformData::matrix(int frameNo) const
index b4bbddf..26053f0 100644 (file)
@@ -32,27 +32,6 @@ class LottieShapeData;
 class LOTPolystarData;
 class LOTMaskData;
 
-class LOTDataVisitor
-{
-public:
-    virtual ~LOTDataVisitor() = default;
-    virtual void visit(LOTCompositionData *) = 0;
-    virtual void visit(LOTLayerData *) = 0;
-    virtual void visit(LOTTransformData *) = 0;
-    virtual void visit(LOTShapeGroupData *) = 0;
-    virtual void visit(LOTShapeData *) = 0;
-    virtual void visit(LOTRectData *) = 0;
-    virtual void visit(LOTEllipseData *) = 0;
-    virtual void visit(LOTPolystarData *) {};
-    virtual void visit(LOTTrimData *) = 0;
-    virtual void visit(LOTRepeaterData *) = 0;
-    virtual void visit(LOTFillData *) = 0;
-    virtual void visit(LOTStrokeData *) = 0;
-    virtual void visit(LOTGFillData *){};
-    virtual void visit(LOTGStrokeData *){};
-    virtual void visitChildren(LOTGroupData *) = 0;
-};
-
 enum class MatteType
 {
     None = 0,
@@ -265,14 +244,12 @@ public:
         Repeater
     };
     LOTData(LOTData::Type  type): mType(type){}
-    virtual ~LOTData()= default;
     inline LOTData::Type type() const {return mType;}
-    virtual void accept(LOTDataVisitor *){}
     bool isStatic() const{return mStatic;}
     void setStatic(bool value) {mStatic = value;}
 public:
     bool                mStatic{true};
-    LOTData::Type  mType;
+    LOTData::Type       mType;
 };
 
 class LOTGroupData: public LOTData
@@ -288,8 +265,6 @@ class LOTShapeGroupData : public LOTGroupData
 {
 public:
     LOTShapeGroupData():LOTGroupData(LOTData::Type::ShapeGroup){}
-    void accept(LOTDataVisitor *visitor) override
-    {visitor->visit(this); visitor->visitChildren(this);}
 };
 
 class LOTLayerData;
@@ -317,8 +292,6 @@ public:
     int solidWidth() const noexcept{return mSolidLayer.mWidth;}
     int solidHeight() const noexcept{return mSolidLayer.mHeight;}
     LottieColor solidColor() const noexcept{return mSolidLayer.mColor;}
-    void accept(LOTDataVisitor *visitor) override
-    {visitor->visit(this); visitor->visitChildren(this);}
 public:
     struct SolidLayer {
         int            mWidth{0};
@@ -357,8 +330,6 @@ public:
     long endFrame() const {return mEndFrame;}
     VSize size() const {return mSize;}
     void processRepeaterObjects();
-    void accept(LOTDataVisitor *visitor) override
-    {visitor->visit(this); mRootLayer->accept(visitor);}
 public:
     std::string          mVersion;
     VSize                mSize;
@@ -382,8 +353,6 @@ public:
     float    opacity(int frameNo) const;
     void cacheMatrix();
     bool staticMatrix() const {return mStaticMatrix;}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 private:
     VMatrix computeMatrix(int frameNo) const;
 public:
@@ -407,8 +376,6 @@ public:
     LOTFillData():LOTData(LOTData::Type::Fill){}
     float opacity(int frameNo) const {return mOpacity.value(frameNo)/100.0;}
     FillRule fillRule() const {return mFillRule;}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     FillRule                       mFillRule{FillRule::Winding}; /* "r" */
     LOTAnimatable<LottieColor>     mColor;   /* "c" */
@@ -434,8 +401,6 @@ public:
     float meterLimit() const{return mMeterLimit;}
     bool hasDashInfo() const { return !(mDash.mDashCount == 0);}
     int getDashInfo(int frameNo, float *array) const;
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     LOTAnimatable<LottieColor>        mColor;      /* "c" */
     LOTAnimatable<int>                mOpacity{100};    /* "o" */
@@ -529,8 +494,6 @@ class LOTGFillData : public LOTGradient
 public:
     LOTGFillData():LOTGradient(LOTData::Type::GFill){}
     FillRule fillRule() const {return mFillRule;}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     FillRule                       mFillRule{FillRule::Winding}; /* "r" */
 };
@@ -545,8 +508,6 @@ public:
     float meterLimit() const{return mMeterLimit;}
     bool hasDashInfo() const { return !(mDash.mDashCount == 0);}
     int getDashInfo(int frameNo, float *array) const;
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     LOTAnimatable<float>           mWidth;       /* "w" */
     CapStyle                       mCapStyle;    /* "lc" */
@@ -570,8 +531,6 @@ class LOTShapeData : public LOTPath
 public:
     LOTShapeData():LOTPath(LOTData::Type::Shape){}
     void process();
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     LOTAnimatable<LottieShapeData>    mShape;
 };
@@ -600,8 +559,6 @@ class LOTRectData : public LOTPath
 {
 public:
     LOTRectData():LOTPath(LOTData::Type::Rect){}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     LOTAnimatable<VPointF>    mPos;
     LOTAnimatable<VPointF>    mSize;
@@ -611,8 +568,6 @@ public:
 class LOTEllipseData : public LOTPath
 {
 public:
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
     LOTEllipseData():LOTPath(LOTData::Type::Ellipse){}
 public:
     LOTAnimatable<VPointF>   mPos;
@@ -627,8 +582,6 @@ public:
         Polygon = 2
     };
     LOTPolystarData():LOTPath(LOTData::Type::Polystar){}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
 public:
     LOTPolystarData::PolyType     mType{PolyType::Polygon};
     LOTAnimatable<VPointF>        mPos;
@@ -648,8 +601,6 @@ public:
         Individually
     };
     LOTTrimData():LOTData(LOTData::Type::Trim){}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this);}
     float start(int frameNo) const {return mStart.value(frameNo)/100.0f;}
     float end(int frameNo) const {return mEnd.value(frameNo)/100.0f;}
     float offset(int frameNo) const {return fmod(mOffset.value(frameNo), 360.0f)/ 360.0f;}
@@ -665,8 +616,6 @@ class LOTRepeaterData : public LOTGroupData
 {
 public:
     LOTRepeaterData():LOTGroupData(LOTData::Type::Repeater){}
-    void accept(LOTDataVisitor *visitor) final
-    {visitor->visit(this); visitor->visitChildren(this);}
 public:
     LOTAnimatable<float>             mCopies{0};
     LOTAnimatable<float>             mOffset{0};
index 90be955..21d4503 100644 (file)
@@ -947,9 +947,11 @@ std::shared_ptr<LOTData> LottieParserImpl::parseGroupObject()
                 RAPIDJSON_ASSERT(PeekType() == kObjectType);
                 parseObject(group);
             }
-            group->mTransform = std::dynamic_pointer_cast<LOTTransformData>(
-                group->mChildren.back());
-            group->mChildren.pop_back();
+            if (group->mChildren.back()->mType == LOTData::Type::Transform) {
+                group->mTransform = std::static_pointer_cast<LOTTransformData>(
+                    group->mChildren.back());
+                group->mChildren.pop_back();
+            }
         } else {
             Skip(key);
         }
@@ -1854,15 +1856,19 @@ void LottieParserImpl::parseProperty(LOTAnimatable<T> &obj)
     }
 }
 
-class LOTDataInspector : public LOTDataVisitor {
+#ifdef DEBUG_PARSER
+
+class LOTDataInspector {
 public:
-    void visit(LOTCompositionData *obj) override
+    void visit(LOTCompositionData *obj)
     {
         vDebug << "[COMP_START:: static:" << obj->isStatic()
                << " v:" << obj->mVersion << " [{ stFm endFm fmRate } { "
                << obj->mStartFrame << " " << obj->mEndFrame << " }]\n";
+        visit(obj->mRootLayer.get());
+        vDebug << "[COMP End ]\n";
     }
-    void visit(LOTLayerData *obj) override
+    void visit(LOTLayerData *obj)
     {
         vDebug << "[LAYER_START:: type:" << layerType(obj->mLayerType)
                << " id:" << obj->mId << " Pid:" << obj->mParentId
@@ -1870,81 +1876,84 @@ public:
                << "[{ stFm endFm stTm tmStrch } { " << obj->mInFrame << " "
                << obj->mOutFrame << " " << obj->mStartFrame << " "
                << obj->mTimeStreatch << " }]";
+
+        visitChildren(static_cast<LOTGroupData *>(obj));
+
+        vDebug << "[LAYER_END:: type:"
+               << layerType(obj->mLayerType).c_str()
+               << " id:" << obj->mId << "\n";
     }
-    void visit(LOTTransformData *t) override
-    {
-        vDebug << "[TRANSFORM: static: " << t->isStatic() << " ]";
-    }
-    void visit(LOTShapeGroupData *o) override
-    {
-        vDebug << "[GROUP_START:: static:" << o->isStatic() << "]";
-    }
-    void visit(LOTShapeData *s) override
-    {
-        vDebug << "[SHAPE: static:" << s->isStatic() << "]";
-    }
-    void visit(LOTRectData *r) override
-    {
-        vDebug << "[RECT: static:" << r->isStatic() << "]";
-    }
-    void visit(LOTEllipseData *e) override
-    {
-        vDebug << "[ELLIPSE: static:" << e->isStatic() << "]";
-    }
-    void visit(LOTPolystarData *e) override
-    {
-        vDebug << "[POLYSTAR: static:" << e->isStatic() << "]";
-    }
-    void visit(LOTTrimData *t) override
-    {
-        vDebug << "[TRIM: static: " << t->isStatic() << " ]";
-    }
-    void visit(LOTRepeaterData *r) override
-    {
-        vDebug << "[REPEATER: static:" << r->isStatic() << "]";
-    }
-    void visit(LOTFillData *f) override
-    {
-        vDebug << "[FILL: static:" << f->isStatic() << "]";
-    }
-    void visit(LOTGFillData *f) override
-    {
-        vDebug << "[GFILL: static:" << f->isStatic()
-               << " ty:" << f->mGradientType << " s:" << f->mStartPoint.value(0)
-               << " e:" << f->mEndPoint.value(0) << "]";
-    }
-    void visit(LOTGStrokeData *f) override
-    {
-        vDebug << "[GSTROKE: static:" << f->isStatic() << "]";
-    }
-    void visit(LOTStrokeData *s) override
+    void visitChildren(LOTGroupData *obj)
     {
-        vDebug << "[STROKE: static:" << s->isStatic() << "]";
+        for (const auto& child : obj->mChildren) visit(child.get());
     }
-    void visitChildren(LOTGroupData *obj) override
-    {
-        for (const auto& child : obj->mChildren) child.get()->accept(this);
-        switch (obj->type()) {
-        case LOTData::Type::Layer: {
-            LOTLayerData *layer = static_cast<LOTLayerData *>(obj);
-            vDebug << "[LAYER_END:: type:"
-                   << layerType(layer->mLayerType).c_str()
-                   << " id:" << layer->mId << "\n";
+
+    void visit(LOTData *obj) {
+        switch (obj->mType) {
+        case LOTData::Type::Repeater: {
+            vDebug << "[REPEATER_START]";
+            visitChildren(static_cast<LOTGroupData *>(obj));
+            vDebug << "[REPEATER_END]";
             break;
         }
-        case LOTData::Type::ShapeGroup:
+        case LOTData::Type::ShapeGroup: {
+            vDebug << "[GROUP_START:: static:" << obj->isStatic() << "]";
+            visitChildren(static_cast<LOTGroupData *>(obj));
             vDebug << "[GROUP_END]";
             break;
-        case LOTData::Type::Composition:
-            vDebug << "[COMP End ]\n";
+        }
+        case LOTData::Type::Layer:{
+            visit(static_cast<LOTLayerData *>(obj));
+            break;
+        }
+        case LOTData::Type::Trim:{
+            vDebug << "[TRIM: static: " << obj->isStatic() << " ]";
+            break;
+        }
+        case LOTData::Type::Rect:{
+            vDebug << "[RECT: static:" << obj->isStatic() << "]";
+            break;
+        }
+        case LOTData::Type::Ellipse:{
+            vDebug << "[RECT: static:" << obj->isStatic() << "]";
+            break;
+        }
+        case LOTData::Type::Shape:{
+            vDebug << "[SHAPE: static:" << obj->isStatic() << "]";
+            break;
+        }
+        case LOTData::Type::Polystar:{
+            vDebug << "[POLYSTAR: static:" << obj->isStatic() << "]";
+            break;
+        }
+        case LOTData::Type::Transform:{
+            vDebug << "[TRANSFORM: static: " << obj->isStatic() << " ]";
+            break;
+        }
+        case LOTData::Type::Stroke:{
+            vDebug << "[SHAPE: static:" << obj->isStatic() << "]";
             break;
-        case LOTData::Type::Repeater:
-            vDebug << "[REPEATER End ]";
+        }
+        case LOTData::Type::GStroke:{
+            vDebug << "[TRANSFORM: static: " << obj->isStatic() << " ]";
+            break;
+        }
+        case LOTData::Type::Fill:{
+            vDebug << "[FILL: static:" << obj->isStatic() << "]";
             break;
+        }
+        case LOTData::Type::GFill:{
+            auto f = static_cast<LOTGFillData *>(obj);
+            vDebug << "[GFILL: static:" << f->isStatic()
+                   << " ty:" << f->mGradientType << " s:" << f->mStartPoint.value(0)
+                   << " e:" << f->mEndPoint.value(0) << "]";
+            break;
+        }
         default:
             break;
         }
     }
+
     std::string layerType(LayerType type)
     {
         switch (type) {
@@ -1973,6 +1982,8 @@ public:
     }
 };
 
+#endif
+
 LottieParser::~LottieParser()
 {
     delete d;
@@ -1991,7 +2002,7 @@ std::shared_ptr<LOTModel> LottieParser::model()
 
 #ifdef DEBUG_PARSER
     LOTDataInspector inspector;
-    model->mRoot->accept(&inspector);
+    inspector.visit(model->mRoot.get());
 #endif
 
     return model;