common shape: refactored interfaces. 27/232427/2
authorHermet Park <chuneon.park@samsung.com>
Mon, 4 May 2020 12:10:04 +0000 (21:10 +0900)
committerHermet Park <chuneon.park@samsung.com>
Mon, 4 May 2020 12:12:29 +0000 (21:12 +0900)
hide engine() interface of shape that's not friendly one by users.
instead canvas would access shape internal data to update/draw it.

Now Paint cannot update itself but has to request to Canvas for it.

Change-Id: Ibafd0864a65c3c33238789d1a3e06c49c4378349

inc/tizenvg.h
src/lib/meson.build
src/lib/tvgCanvas.cpp
src/lib/tvgScene.cpp
src/lib/tvgShape.cpp
src/lib/tvgShapeImpl.h [new file with mode: 0644]
test/testDirectUpdate.cpp
test/testTransform.cpp

index 93e13fc..d7ed6ef 100644 (file)
@@ -43,6 +43,9 @@ private: \
     const A& operator=(const A&) = delete; \
     A()
 
+#define _TIZENVG_DECLARE_ACCESSOR(A) \
+    friend A
+
 #define _TIZENVG_DISABLE_CTOR(A) \
     A() = delete; \
     ~A() = delete
@@ -73,8 +76,6 @@ class TIZENVG_EXPORT Paint
 public:
     virtual ~Paint() {}
 
-    virtual int update(RenderMethod*) = 0;
-
     virtual int rotate(float degree) = 0;
     virtual int scale(float factor) = 0;
 
@@ -102,6 +103,7 @@ public:
     virtual int push(std::unique_ptr<Paint> paint) noexcept;
     virtual int clear() noexcept;
     virtual int update() noexcept;
+    virtual int update(Paint* paint) noexcept;
     virtual int draw(bool async = true) noexcept;
     virtual int sync() = 0;
 
@@ -124,7 +126,6 @@ class TIZENVG_EXPORT Shape final : public Paint
 public:
     ~Shape();
 
-    int update(RenderMethod* engine) noexcept override;
     int reset() noexcept;
 
     int moveTo(float x, float y) noexcept;
@@ -150,10 +151,8 @@ public:
 
     static std::unique_ptr<Shape> gen() noexcept;
 
-    //FIXME: Ugly... Better design?
-    void *engine() noexcept;
-
     _TIZENVG_DECLARE_PRIVATE(Shape);
+    _TIZENVG_DECLARE_ACCESSOR(Canvas);
 };
 
 
@@ -170,7 +169,6 @@ class TIZENVG_EXPORT Scene final : public Paint
 public:
     ~Scene();
 
-    int update(RenderMethod* engine) noexcept override;
     int push(std::unique_ptr<Shape> shape) noexcept;
 
     int rotate(float degree) noexcept override;
index 5b47bcf..1087bb8 100644 (file)
@@ -4,8 +4,9 @@ subdir('gl_engine')
 source_file = [
    'tvgCommon.h',
    'tvgRenderCommon.h',
-   'tvgEngine.cpp',
    'tvgShapePath.h',
+   'tvgShapeImpl.h',
+   'tvgEngine.cpp',
    'tvgCanvas.cpp',
    'tvgSwCanvas.cpp',
    'tvgGlCanvas.cpp',
index 84a1327..49df7e1 100644 (file)
@@ -18,7 +18,7 @@
 #define _TVG_CANVAS_CPP_
 
 #include "tvgCommon.h"
-
+#include "tvgShapeImpl.h"
 
 /************************************************************************/
 /* Internal Class Implementation                                        */
@@ -26,8 +26,8 @@
 
 struct Canvas::Impl
 {
-    vector<Paint*> nodes;
-    RenderMethod*      renderer;
+    vector<Paint*> paints;
+    RenderMethod*  renderer;
 
     Impl(RenderMethod* pRenderer):renderer(pRenderer)
     {
@@ -40,44 +40,61 @@ struct Canvas::Impl
         renderer->unref();
     }
 
-    int reserve(size_t n)
+    int push(unique_ptr<Paint> paint)
     {
-        nodes.reserve(n);
+        Paint* pPaint = paint.release();
+        assert(pPaint);
+        paints.push_back(pPaint);
 
-        return 0;
+        return update(pPaint);
     }
 
-    int push(unique_ptr<Paint> paint)
+    int clear()
     {
-        Paint* node = paint.release();
-        assert(node);
-        nodes.push_back(node);
-        return node->update(renderer);
+        assert(renderer);
+
+        for (auto paint : paints) {
+            if (auto scene = dynamic_cast<Scene*>(paint)) {
+                cout << "TODO: " <<  scene << endl;
+            } else if (auto shape = dynamic_cast<Shape*>(paint)) {
+                auto p = shape->pImpl.get();
+                assert(p);
+                if (!p->dispose(*shape, *renderer)) return -1;
+            }
+            delete(paint);
+        }
+        paints.clear();
+
+        return 0;
     }
 
-    int clear()
+    int update()
     {
         assert(renderer);
 
-        for (auto node : nodes) {
-            if (Scene* scene = dynamic_cast<Scene*>(node)) {
+        for(auto paint: paints) {
+            if (auto scene = dynamic_cast<Scene*>(paint)) {
                 cout << "TODO: " <<  scene << endl;
-            } else if (Shape *shape = dynamic_cast<Shape*>(node)) {
-                if (!renderer->dispose(*shape, shape->engine())) return -1;
+            } else if (auto shape = dynamic_cast<Shape*>(paint)) {
+                auto p = shape->pImpl.get();
+                assert(p);
+                if (!p->update(*shape, *renderer)) return -1;
             }
-            delete(node);
         }
-        nodes.clear();
 
         return 0;
     }
 
-    int update()
+    int update(Paint* paint)
     {
         assert(renderer);
 
-        for(auto node: nodes) {
-            if (!node->update(renderer)) return -1;
+        if (auto scene = dynamic_cast<Scene*>(paint)) {
+            cout << "TODO: " <<  scene << endl;
+        } else if (auto shape = dynamic_cast<Shape*>(paint)) {
+            auto p = shape->pImpl.get();
+            assert(p);
+            if (!p->update(*shape, *renderer)) return -1;
         }
 
         return 0;
@@ -90,11 +107,13 @@ struct Canvas::Impl
         //Clear render target before drawing
         if (!renderer->clear()) return -1;
 
-        for(auto node: nodes) {
-            if (Scene* scene = dynamic_cast<Scene*>(node)) {
+        for(auto paint: paints) {
+            if (auto scene = dynamic_cast<Scene*>(paint)) {
                 cout << "TODO: " <<  scene << endl;
-            } else if (Shape *shape = dynamic_cast<Shape*>(node)) {
-                if (!renderer->render(*shape, shape->engine())) return -1;
+            } else if (auto shape = dynamic_cast<Shape*>(paint)) {
+                auto p = shape->pImpl.get();
+                assert(p);
+                if(!p->render(*shape, *renderer)) return -1;
             }
         }
         return 0;
@@ -121,7 +140,8 @@ int Canvas::reserve(size_t n) noexcept
 {
     auto impl = pImpl.get();
     assert(impl);
-    return impl->reserve(n);
+    impl->paints.reserve(n);
+    return 0;
 }
 
 
@@ -158,11 +178,11 @@ int Canvas::update() noexcept
 }
 
 
-RenderMethod* Canvas::engine() noexcept
+int Canvas::update(Paint* paint) noexcept
 {
     auto impl = pImpl.get();
     assert(impl);
-    return impl->renderer;
+    return impl->update(paint);
 }
 
 #endif /* _TVG_CANVAS_CPP_ */
index 0be6f4d..bc26a99 100644 (file)
@@ -58,13 +58,6 @@ int Scene::push(unique_ptr<Shape> shape) noexcept
 }
 
 
-int Scene::update(RenderMethod* engine) noexcept
-{
-
-    return 0;
-}
-
-
 int Scene::scale(float scaleFacator) noexcept
 {
     return 0;
index 17e3a27..1e5545d 100644 (file)
 #define _TVG_SHAPE_CPP_
 
 #include "tvgCommon.h"
-#include "tvgShapePath.h"
+#include "tvgShapeImpl.h"
 
 /************************************************************************/
 /* Internal Class Implementation                                        */
 /************************************************************************/
 constexpr auto PATH_KAPPA = 0.552284f;
 
-struct ShapeFill
-{
-};
-
-
-struct ShapeStroke
-{
-};
-
-
-struct Shape::Impl
-{
-    ShapeFill *fill = nullptr;
-    ShapeStroke *stroke = nullptr;
-    ShapePath *path = nullptr;
-    uint8_t color[4] = {0, 0, 0, 0};    //r, g, b, a
-    float scale = 1;
-    float rotate = 0;
-    void *edata = nullptr;              //engine data
-    size_t flag = RenderUpdateFlag::None;
-
-    Impl() : path(new ShapePath)
-    {
-    }
-
-    ~Impl()
-    {
-        if (path) delete(path);
-        if (stroke) delete(stroke);
-        if (fill) delete(fill);
-    }
-};
-
 
 /************************************************************************/
 /* External Class Implementation                                        */
@@ -79,26 +46,6 @@ unique_ptr<Shape> Shape::gen() noexcept
 }
 
 
-void* Shape::engine() noexcept
-{
-    auto impl = pImpl.get();
-    assert(impl);
-    return impl->edata;
-}
-
-
-int Shape::update(RenderMethod* engine) noexcept
-{
-    auto impl = pImpl.get();
-    assert(impl);
-
-    impl->edata = engine->prepare(*this, impl->edata, static_cast<RenderUpdateFlag>(impl->flag));
-    impl->flag = RenderUpdateFlag::None;
-    if (impl->edata) return 0;
-    return -1;
-}
-
-
 int Shape::reset() noexcept
 {
     auto impl = pImpl.get();
diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h
new file mode 100644 (file)
index 0000000..f1bb1eb
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_SHAPE_IMPL_H_
+#define _TVG_SHAPE_IMPL_H_
+
+#include "tvgCommon.h"
+#include "tvgShapePath.h"
+
+/************************************************************************/
+/* Internal Class Implementation                                        */
+/************************************************************************/
+
+struct ShapeFill
+{
+};
+
+
+struct ShapeStroke
+{
+};
+
+
+struct Shape::Impl
+{
+    ShapeFill *fill = nullptr;
+    ShapeStroke *stroke = nullptr;
+    ShapePath *path = nullptr;
+    uint8_t color[4] = {0, 0, 0, 0};    //r, g, b, a
+    float scale = 1;
+    float rotate = 0;
+    void *edata = nullptr;              //engine data
+    size_t flag = RenderUpdateFlag::None;
+
+    Impl() : path(new ShapePath)
+    {
+    }
+
+    ~Impl()
+    {
+        if (path) delete(path);
+        if (stroke) delete(stroke);
+        if (fill) delete(fill);
+    }
+
+    bool dispose(Shape& shape, RenderMethod& renderer)
+    {
+        return renderer.dispose(shape, edata);
+    }
+
+    bool render(Shape& shape, RenderMethod& renderer)
+    {
+        return renderer.render(shape, edata);
+    }
+
+    bool update(Shape& shape, RenderMethod& renderer)
+    {
+        edata = renderer.prepare(shape, edata, static_cast<RenderUpdateFlag>(flag));
+        flag = RenderUpdateFlag::None;
+        if (edata) return true;
+        return false;
+    }
+};
+
+#endif //_TVG_SHAPE_IMPL_H_
\ No newline at end of file
index 723222b..735231a 100644 (file)
@@ -46,7 +46,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres
     pShape->appendRect(-100 + (800 * progress), -100 + (800 * progress), 200, 200, (100 * progress));
 
     //Update shape for drawing (this may work asynchronously)
-    pShape->update(canvas->engine());
+    canvas->update(pShape);
 
     //Draw Next frames
     canvas->draw();
index 9cf5e37..1224299 100644 (file)
@@ -46,7 +46,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres
     pShape->rotate(360 * progress);
 
     //Update shape for drawing (this may work asynchronously)
-    pShape->update(canvas->engine());
+    canvas->update(pShape);
 
     //Draw Next frames
     canvas->draw();