From 3611e1cc516864e34a59dc16d80004d0d05c9c70 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Thu, 6 Sep 2018 13:45:17 +0900 Subject: [PATCH] lottie: refactor model class to remove visitor 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 | 8 +- src/lottie/lottiemodel.cpp | 40 ++++------ src/lottie/lottiemodel.h | 53 +------------ src/lottie/lottieparser.cpp | 149 +++++++++++++++++++----------------- 4 files changed, 100 insertions(+), 150 deletions(-) diff --git a/src/lottie/lottieitem.cpp b/src/lottie/lottieitem.cpp index 56a4532..c113ea9 100644 --- a/src/lottie/lottieitem.cpp +++ b/src/lottie/lottieitem.cpp @@ -318,11 +318,9 @@ LOTCompLayerItem::LOTCompLayerItem(LOTLayerData *layerModel) { // 1. create layer item for (auto &i : mLayerData->mChildren) { - LOTLayerData *layerModel = dynamic_cast(i.get()); - if (layerModel) { - auto layerItem = LOTCompItem::createLayerItem(layerModel); - if (layerItem) mLayers.push_back(std::move(layerItem)); - } + LOTLayerData *layerModel = static_cast(i.get()); + auto layerItem = LOTCompItem::createLayerItem(layerModel); + if (layerItem) mLayers.push_back(std::move(layerItem)); } // 2. update parent layer diff --git a/src/lottie/lottiemodel.cpp b/src/lottie/lottiemodel.cpp index bbbaba2..38179a9 100644 --- a/src/lottie/lottiemodel.cpp +++ b/src/lottie/lottiemodel.cpp @@ -3,25 +3,12 @@ #include #include -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(child.get()); std::shared_ptr 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(obj)); + break; + } + default: + break; + } + } }; void LOTCompositionData::processRepeaterObjects() { LottieRepeaterProcesser visitor; - accept(&visitor); + visitor.visit(mRootLayer.get()); } VMatrix LOTTransformData::matrix(int frameNo) const diff --git a/src/lottie/lottiemodel.h b/src/lottie/lottiemodel.h index b4bbddf..26053f0 100644 --- a/src/lottie/lottiemodel.h +++ b/src/lottie/lottiemodel.h @@ -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 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 mColor; /* "c" */ LOTAnimatable 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 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 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 mPos; LOTAnimatable 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 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 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 mCopies{0}; LOTAnimatable mOffset{0}; diff --git a/src/lottie/lottieparser.cpp b/src/lottie/lottieparser.cpp index 90be955..21d4503 100644 --- a/src/lottie/lottieparser.cpp +++ b/src/lottie/lottieparser.cpp @@ -947,9 +947,11 @@ std::shared_ptr LottieParserImpl::parseGroupObject() RAPIDJSON_ASSERT(PeekType() == kObjectType); parseObject(group); } - group->mTransform = std::dynamic_pointer_cast( - group->mChildren.back()); - group->mChildren.pop_back(); + if (group->mChildren.back()->mType == LOTData::Type::Transform) { + group->mTransform = std::static_pointer_cast( + group->mChildren.back()); + group->mChildren.pop_back(); + } } else { Skip(key); } @@ -1854,15 +1856,19 @@ void LottieParserImpl::parseProperty(LOTAnimatable &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(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(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(obj)); + vDebug << "[REPEATER_END]"; break; } - case LOTData::Type::ShapeGroup: + case LOTData::Type::ShapeGroup: { + vDebug << "[GROUP_START:: static:" << obj->isStatic() << "]"; + visitChildren(static_cast(obj)); vDebug << "[GROUP_END]"; break; - case LOTData::Type::Composition: - vDebug << "[COMP End ]\n"; + } + case LOTData::Type::Layer:{ + visit(static_cast(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(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 LottieParser::model() #ifdef DEBUG_PARSER LOTDataInspector inspector; - model->mRoot->accept(&inspector); + inspector.visit(model->mRoot.get()); #endif return model; -- 2.34.1