rlottie: added support of lambda expression in setValue.
authorsubhransu mohanty <sub.mohanty@samsung.com>
Mon, 13 May 2019 00:30:56 +0000 (09:30 +0900)
committerHermet Park <hermetpark@gmail.com>
Wed, 22 May 2019 04:00:18 +0000 (13:00 +0900)
example/demo.cpp
inc/rlottie.h
src/lottie/lottieanimation.cpp
src/lottie/lottieitem.cpp
src/lottie/lottieitem.h
src/lottie/lottieproxymodel.h

index 48625c6..9970303 100644 (file)
@@ -50,7 +50,14 @@ main(void)
    LottieView *view = new LottieView(app->evas());
    view->setFilePath(filePath.c_str());
    if (view->player()) {
-       view->player()->setValue<rlottie::Property::FillColor>("**", rlottie::Color(0, 1, 0));
+       view->player()->setValue<rlottie::Property::FillColor>("**",
+           [](const rlottie::FrameInfo& info) {
+                if (info.curFrame() < 15 )
+                    return rlottie::Color(0, 1, 0);
+                else {
+                    return rlottie::Color(1, 0, 0);
+                }
+            });
    }
    view->setPos(0, 0);
    view->setSize(800, 800);
index d3a48a9..765698e 100644 (file)
@@ -52,22 +52,42 @@ struct LOTLayerNode;
 namespace rlottie {
 
 struct Color {
-    Color(){}
-    Color(float r, float g , float b):mr(r), mg(g), mb(b){}
-public:
-    float mr{0}, mg{0}, mb{0};
+    Color() = default;
+    Color(float r, float g , float b):_r(r), _g(g), _b(b){}
+    float r() const {return _r;}
+    float g() const {return _g;}
+    float b() const {return _b;}
+private:
+    float _r{0};
+    float _g{0};
+    float _b{0};
 };
 
 struct Size {
-    Size(float w, float h):mw(w), mh(h){}
+    Size() = default;
+    Size(float w, float h):_w(w), _h(h){}
+    float w() const {return _w;}
+    float h() const {return _h;}
 private:
-    float mw{0} , mh{0};
+    float _w{0};
+    float _h{0};
 };
 
 struct Point {
-    Point(float x, float y):mx(x), my(y){}
+    Point() = default;
+    Point(float x, float y):_x(x), _y(y){}
+    float x() const {return _x;}
+    float y() const {return _y;}
+private:
+    float _x{0};
+    float _y{0};
+};
+
+struct FrameInfo {
+    FrameInfo(uint32_t frame): _frameNo(frame){}
+    uint32_t curFrame() const {return _frameNo;}
 private:
-    float mx{0} , my{0};
+    uint32_t _frameNo;
 };
 
 enum class Property {
@@ -409,6 +429,11 @@ private:
     void setValue(Float_Type, Property, const std::string &, float);
     void setValue(Size_Type, Property, const std::string &, Size);
     void setValue(Point_Type, Property, const std::string &, Point);
+
+    void setValue(Color_Type, Property, const std::string &, std::function<Color(const FrameInfo &)> &&);
+    void setValue(Float_Type, Property, const std::string &, std::function<float(const FrameInfo &)> &&);
+    void setValue(Size_Type, Property, const std::string &, std::function<Size(const FrameInfo &)> &&);
+    void setValue(Point_Type, Property, const std::string &, std::function<Point(const FrameInfo &)> &&);
     /**
      *  @brief default constructor
      *
index 08ed5dc..7547ac8 100644 (file)
@@ -318,27 +318,55 @@ void Animation::setValue(Color_Type,Property prop,
                          const std::string &keypath,
                          Color value)
 {
-    d->setValue(keypath, LOTVariant(prop, value));
+    d->setValue(keypath, LOTVariant(prop, [value](const FrameInfo &){ return value;}));
 }
 
 void Animation::setValue(Float_Type, Property prop,
                          const std::string &keypath,
                          float value)
 {
-    d->setValue(keypath, LOTVariant(prop, value));
+    d->setValue(keypath, LOTVariant(prop, [value](const FrameInfo &){ return value;}));
 }
 
 void Animation::setValue(Size_Type,Property prop,
                          const std::string &keypath,
                          Size value)
 {
-    d->setValue(keypath, LOTVariant(prop, value));
+    d->setValue(keypath, LOTVariant(prop, [value](const FrameInfo &){ return value;}));
 }
 
 void Animation::setValue(Point_Type, Property prop,
                          const std::string &keypath,
                          Point value)
 {
+    d->setValue(keypath, LOTVariant(prop, [value](const FrameInfo &){ return value;}));
+}
+
+void Animation::setValue(Color_Type,Property prop,
+                         const std::string &keypath,
+                         std::function<Color(const FrameInfo &)> && value)
+{
+    d->setValue(keypath, LOTVariant(prop, value));
+}
+
+void Animation::setValue(Float_Type, Property prop,
+                         const std::string &keypath,
+                         std::function<float(const FrameInfo &)> && value)
+{
+    d->setValue(keypath, LOTVariant(prop, value));
+}
+
+void Animation::setValue(Size_Type,Property prop,
+                         const std::string &keypath,
+                         std::function<Size(const FrameInfo &)> && value)
+{
+    d->setValue(keypath, LOTVariant(prop, value));
+}
+
+void Animation::setValue(Point_Type, Property prop,
+                         const std::string &keypath,
+                         std::function<Point(const FrameInfo &)> && value)
+{
     d->setValue(keypath, LOTVariant(prop, value));
 }
 
index 93a1cd9..39d54ca 100644 (file)
@@ -73,7 +73,7 @@ bool strokeProp(rlottie::Property prop)
 }
 
 LOTCompItem::LOTCompItem(LOTModel *model)
-    : mRootModel(model), mUpdateViewBox(false), mCurFrameNo(-1)
+    : mUpdateViewBox(false), mCurFrameNo(-1)
 {
     mCompData = model->mRoot.get();
     mRootLayer = createLayerItem(mCompData->mRootLayer.get());
index 0e6c8db..bf59614 100644 (file)
@@ -62,7 +62,6 @@ public:
 private:
    VMatrix                                    mScaleMatrix;
    VSize                                      mViewSize;
-   LOTModel                                   *mRootModel;
    LOTCompositionData                         *mCompData;
    std::unique_ptr<LOTLayerItem>               mRootLayer;
    bool                                        mUpdateViewBox;
@@ -441,7 +440,6 @@ protected:
    bool resolveKeyPath(LOTKeyPath &keyPath, uint depth, LOTVariant &value) final;
 private:
    LOTProxyModel<LOTStrokeData> mModel;
-   LOTStrokeData               *mData{nullptr};
    VColor                       mColor;
    float                        mWidth{0};
    float                        mDashArray[6];
index 2137d61..8b5ad17 100644 (file)
@@ -21,6 +21,7 @@
 
 #include<bitset>
 #include<algorithm>
+#include<cassert>
 #include "lottiemodel.h"
 #include "rlottie.h"
 
 class LOTVariant
 {
 public:
-    enum Type {Color, Point, Size, Float};
-    LOTVariant(rlottie::Property prop, float  v):property_(prop),valueType_(Type::Float),value_(v){}
-    LOTVariant(rlottie::Property prop, rlottie::Color  col):property_(prop),valueType_(Type::Color),color_(col){}
-    LOTVariant(rlottie::Property prop, rlottie::Point  pt):property_(prop),valueType_(Type::Point),pos_(pt){}
-    LOTVariant(rlottie::Property prop, rlottie::Size  sz):property_(prop),valueType_(Type::Size),size_(sz){}
-    Type type() const {return valueType_;}
-    rlottie::Property property() const {return property_;}
-    float value() const {return value_;}
-    rlottie::Color color() const {return color_;}
-    rlottie::Point pos() const {return pos_;}
-    rlottie::Size  size() const {return size_;}
-public:
-    rlottie::Property property_;
-    Type  valueType_;
-    union {
-      float           value_;
-      rlottie::Color  color_;
-      rlottie::Point  pos_;
-      rlottie::Size   size_;
-    };
+    using ValueFunc = std::function<float(const rlottie::FrameInfo &)>;
+    using ColorFunc = std::function<rlottie::Color(const rlottie::FrameInfo &)>;
+    using PointFunc = std::function<rlottie::Point(const rlottie::FrameInfo &)>;
+    using SizeFunc = std::function<rlottie::Size(const rlottie::FrameInfo &)>;
+
+    LOTVariant(rlottie::Property prop, const ValueFunc &v):mPropery(prop), mTag(Value)
+    {
+        construct(impl.valueFunc, v);
+    }
+
+    LOTVariant(rlottie::Property prop, ValueFunc &&v):mPropery(prop), mTag(Value)
+    {
+        moveConstruct(impl.valueFunc, std::move(v));
+    }
+
+    LOTVariant(rlottie::Property prop, const ColorFunc &v):mPropery(prop), mTag(Color)
+    {
+        construct(impl.colorFunc, v);
+    }
+
+    LOTVariant(rlottie::Property prop, ColorFunc &&v):mPropery(prop), mTag(Color)
+    {
+        moveConstruct(impl.colorFunc, std::move(v));
+    }
+
+    LOTVariant(rlottie::Property prop, const PointFunc &v):mPropery(prop), mTag(Point)
+    {
+        construct(impl.pointFunc, v);
+    }
+
+    LOTVariant(rlottie::Property prop, PointFunc &&v):mPropery(prop), mTag(Point)
+    {
+        moveConstruct(impl.pointFunc, std::move(v));
+    }
+
+    LOTVariant(rlottie::Property prop, const SizeFunc &v):mPropery(prop), mTag(Size)
+    {
+        construct(impl.sizeFunc, v);
+    }
+
+    LOTVariant(rlottie::Property prop, SizeFunc &&v):mPropery(prop), mTag(Size)
+    {
+        moveConstruct(impl.sizeFunc, std::move(v));
+    }
+
+    rlottie::Property property() const { return mPropery; }
+
+    const ColorFunc& color() const
+    {
+        assert(mTag == Color);
+        return impl.colorFunc;
+    }
+
+    const ValueFunc& value() const
+    {
+        assert(mTag == Value);
+        return impl.valueFunc;
+    }
+
+    const PointFunc& point() const
+    {
+        assert(mTag == Point);
+        return impl.pointFunc;
+    }
+
+    const SizeFunc& size() const
+    {
+        assert(mTag == Size);
+        return impl.sizeFunc;
+    }
+
+    LOTVariant() = default;
+    ~LOTVariant() noexcept {Destroy();}
+    LOTVariant(const LOTVariant& other) { Copy(other);}
+    LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other));}
+    LOTVariant& operator=(LOTVariant&& other) { Destroy(); Move(std::move(other)); return *this;}
+    LOTVariant& operator=(const LOTVariant& other) { Destroy(); Copy(other); return *this;}
+private:
+    template <typename T>
+    void construct(T& member, const T& val)
+    {
+        new (&member) T(val);
+    }
+
+    template <typename T>
+    void moveConstruct(T& member, T&& val)
+    {
+        new (&member) T(std::move(val));
+    }
+
+    void Move(LOTVariant&& other)
+    {
+        switch (other.mTag) {
+        case Type::Value:
+            moveConstruct(impl.valueFunc, std::move(other.impl.valueFunc));
+            break;
+        case Type::Color:
+            moveConstruct(impl.colorFunc, std::move(other.impl.colorFunc));
+            break;
+        case Type::Point:
+            moveConstruct(impl.pointFunc, std::move(other.impl.pointFunc));
+            break;
+        case Type::Size:
+            moveConstruct(impl.sizeFunc, std::move(other.impl.sizeFunc));
+            break;
+        default:
+            break;
+        }
+        mTag = other.mTag;
+        mPropery = other.mPropery;
+        other.mTag = MonoState;
+    }
+
+    void Copy(const LOTVariant& other)
+    {
+        switch (other.mTag) {
+        case Type::Value:
+            construct(impl.valueFunc, other.impl.valueFunc);
+            break;
+        case Type::Color:
+            construct(impl.colorFunc, other.impl.colorFunc);
+            break;
+        case Type::Point:
+            construct(impl.pointFunc, other.impl.pointFunc);
+            break;
+        case Type::Size:
+            construct(impl.sizeFunc, other.impl.sizeFunc);
+            break;
+        default:
+            break;
+        }
+        mTag = other.mTag;
+        mPropery = other.mPropery;
+    }
+
+    void Destroy()
+    {
+        switch(mTag) {
+        case MonoState: {
+            break;
+        }
+        case Value: {
+            impl.valueFunc.~ValueFunc();
+            break;
+        }
+        case Color: {
+            impl.colorFunc.~ColorFunc();
+            break;
+        }
+        case Point: {
+            impl.pointFunc.~PointFunc();
+            break;
+        }
+        case Size: {
+            impl.sizeFunc.~SizeFunc();
+            break;
+        }
+        }
+    }
+
+    enum Type {MonoState, Value, Color, Point , Size};
+    rlottie::Property mPropery;
+    Type              mTag{MonoState};
+    union details{
+      ColorFunc   colorFunc;
+      ValueFunc   valueFunc;
+      PointFunc   pointFunc;
+      SizeFunc    sizeFunc;
+      details(){}
+      ~details(){}
+    }impl;
 };
 
 class LOTFilter
@@ -85,34 +237,33 @@ public:
     {
         return mBitset.test(static_cast<uint>(prop));
     }
-    LottieColor color(rlottie::Property prop) const
+    LottieColor color(rlottie::Property prop, int frame) const
     {
-        rlottie::Color col = data(prop).color();
-        return LottieColor(col.mr, col.mg, col.mb);
+        rlottie::FrameInfo info(frame);
+        rlottie::Color col = data(prop).color()(info);
+        return LottieColor(col.r(), col.g(), col.b());
     }
-    float opacity(rlottie::Property prop) const
+    float opacity(rlottie::Property prop, int frame) const
     {
-        float val = data(prop).value();
+        rlottie::FrameInfo info(frame);
+        float val = data(prop).value()(info);
         return val/100;
     }
-    float value(rlottie::Property prop) const
+    float value(rlottie::Property prop, int frame) const
     {
-        return data(prop).value();
+        rlottie::FrameInfo info(frame);
+        return data(prop).value()(info);
     }
 private:
-    LOTVariant data(rlottie::Property prop) const
+    const LOTVariant& data(rlottie::Property prop) const
     {
         auto result = std::find_if(mFilters.begin(),
                                    mFilters.end(),
                                    [prop](const LOTVariant &e){return e.property() == prop;});
-        if (result != mFilters.end()) {
-            return *result;
-        } else {
-            return LOTVariant(prop, 0);
-        }
+        return *result;
     }
-    std::vector<LOTVariant>    mFilters;
     std::bitset<32>            mBitset{0};
+    std::vector<LOTVariant>    mFilters;
 };
 
 template <typename T>
@@ -125,21 +276,21 @@ public:
     LottieColor color(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::StrokeColor)) {
-            return mFilter.color(rlottie::Property::StrokeColor);
+            return mFilter.color(rlottie::Property::StrokeColor, frame);
         }
         return _modelData->color(frame);
     }
     float opacity(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::StrokeOpacity)) {
-            return mFilter.opacity(rlottie::Property::StrokeOpacity);
+            return mFilter.opacity(rlottie::Property::StrokeOpacity, frame);
         }
         return _modelData->opacity(frame);
     }
     float strokeWidth(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::StrokeWidth)) {
-            return mFilter.value(rlottie::Property::StrokeWidth);
+            return mFilter.value(rlottie::Property::StrokeWidth, frame);
         }
         return _modelData->strokeWidth(frame);
     }
@@ -164,14 +315,14 @@ public:
     LottieColor color(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::FillColor)) {
-            return mFilter.color(rlottie::Property::FillColor);
+            return mFilter.color(rlottie::Property::FillColor, frame);
         }
         return _modelData->color(frame);
     }
     float opacity(int frame) const
     {
         if (mFilter.hasFilter(rlottie::Property::FillOpacity)) {
-            return mFilter.opacity(rlottie::Property::FillOpacity);
+            return mFilter.opacity(rlottie::Property::FillOpacity, frame);
         }
         return _modelData->opacity(frame);
     }