common: code refactoring

remove duplicated code among the Paint types.

Change-Id: Ia7c09f29531e6aef73d2ba1f951f8dfdf488deb8
This commit is contained in:
Hermet Park 2020-07-30 19:17:55 +09:00
parent ec6e5618e2
commit e9a4e2ccb6
7 changed files with 138 additions and 331 deletions

View file

@ -48,8 +48,10 @@ protected: \
A() = delete; \
~A() = delete
#define _TVG_DECLARE_ACCESSOR(A) \
friend A
#define _TVG_DECLARE_ACCESSOR() \
friend Canvas; \
friend Scene; \
friend Picture
#define _TVG_DECALRE_IDENTIFIER() \
auto id() const { return _id; } \
@ -61,6 +63,7 @@ namespace tvg
class RenderMethod;
class Scene;
class Picture;
class Canvas;
@ -105,9 +108,8 @@ public:
Result transform(const Matrix& m) noexcept;
Result bounds(float* x, float* y, float* w, float* h) const noexcept;
_TVG_DECLARE_ACCESSOR();
_TVG_DECLARE_PRIVATE(Paint);
_TVG_DECLARE_ACCESSOR(Canvas);
_TVG_DECLARE_ACCESSOR(Scene);
};
@ -166,7 +168,6 @@ public:
};
/**
* @class LinearGradient
*
@ -308,7 +309,6 @@ public:
static std::unique_ptr<Scene> gen() noexcept;
_TVG_DECLARE_PRIVATE(Scene);
_TVG_DECLARE_ACCESSOR(Picture);
};

View file

@ -56,7 +56,7 @@ struct Canvas::Impl
if (!renderer->clear()) return Result::InsufficientCondition;
for (auto paint : paints) {
paint->IMPL->method()->dispose(*renderer);
paint->IMPL->dispose(*renderer);
delete(paint);
}
paints.clear();
@ -70,13 +70,13 @@ struct Canvas::Impl
//Update single paint node
if (paint) {
if (!paint->IMPL->method()->update(*renderer, nullptr, RenderUpdateFlag::None)) {
if (!paint->IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) {
return Result::InsufficientCondition;
}
//Update retained all paint nodes
} else {
for(auto paint: paints) {
if (!paint->IMPL->method()->update(*renderer, nullptr, RenderUpdateFlag::None)) {
if (!paint->IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) {
return Result::InsufficientCondition;
}
}
@ -91,7 +91,7 @@ struct Canvas::Impl
if (!renderer->preRender()) return Result::InsufficientCondition;
for(auto paint: paints) {
if(!paint->IMPL->method()->render(*renderer)) return Result::InsufficientCondition;
if(!paint->IMPL->render(*renderer)) return Result::InsufficientCondition;
}
if (!renderer->postRender()) return Result::InsufficientCondition;

View file

@ -39,35 +39,35 @@ Paint :: ~Paint()
Result Paint::rotate(float degree) noexcept
{
if (IMPL->method()->rotate(degree)) return Result::Success;
if (IMPL->rotate(degree)) return Result::Success;
return Result::FailedAllocation;
}
Result Paint::scale(float factor) noexcept
{
if (IMPL->method()->scale(factor)) return Result::Success;
if (IMPL->scale(factor)) return Result::Success;
return Result::FailedAllocation;
}
Result Paint::translate(float x, float y) noexcept
{
if (IMPL->method()->translate(x, y)) return Result::Success;
if (IMPL->translate(x, y)) return Result::Success;
return Result::FailedAllocation;
}
Result Paint::transform(const Matrix& m) noexcept
{
if (IMPL->method()->transform(m)) return Result::Success;
if (IMPL->transform(m)) return Result::Success;
return Result::FailedAllocation;
}
Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept
{
if (IMPL->method()->bounds(x, y, w, h)) return Result::Success;
if (IMPL->bounds(x, y, w, h)) return Result::Success;
return Result::InsufficientCondition;
}

View file

@ -24,23 +24,20 @@ namespace tvg
virtual ~StrategyMethod(){}
virtual bool dispose(RenderMethod& renderer) = 0;
virtual bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag) = 0;
virtual bool update(RenderMethod& renderer, const RenderTransform* transform, RenderUpdateFlag pFlag) = 0;
virtual bool render(RenderMethod& renderer) = 0;
virtual bool rotate(float degree) = 0;
virtual bool scale(float factor) = 0;
virtual bool translate(float x, float y) = 0;
virtual bool transform(const Matrix& m) = 0;
virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
};
struct Paint::Impl
{
StrategyMethod* smethod = nullptr;
RenderTransform *rTransform = nullptr;
uint32_t flag = RenderUpdateFlag::None;
~Impl() {
if (smethod) delete(smethod);
if (rTransform) delete(rTransform);
}
void method(StrategyMethod* method)
@ -48,9 +45,99 @@ namespace tvg
smethod = method;
}
StrategyMethod* method()
bool rotate(float degree)
{
return smethod;
if (rTransform) {
if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
} else {
if (fabsf(degree) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->degree = degree;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool scale(float factor)
{
if (rTransform) {
if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
} else {
if (fabsf(factor) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->scale = factor;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool translate(float x, float y)
{
if (rTransform) {
if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
} else {
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->x = x;
rTransform->y = y;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool transform(const Matrix& m)
{
if (!rTransform) {
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->override(m);
flag |= RenderUpdateFlag::Transform;
return true;
}
bool bounds(float* x, float* y, float* w, float* h) const
{
return smethod->bounds(x, y, w, h);
}
bool dispose(RenderMethod& renderer)
{
return smethod->dispose(renderer);
}
bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag)
{
if (flag & RenderUpdateFlag::Transform) {
if (!rTransform) return false;
if (!rTransform->update()) {
delete(rTransform);
rTransform = nullptr;
}
}
auto newFlag = static_cast<RenderUpdateFlag>(pFlag | flag);
flag = RenderUpdateFlag::None;
if (rTransform && pTransform) {
RenderTransform outTransform(pTransform, rTransform);
return smethod->update(renderer, &outTransform, newFlag);
} else {
auto outTransform = pTransform ? pTransform : rTransform;
return smethod->update(renderer, outTransform, newFlag);
}
}
bool render(RenderMethod& renderer)
{
return smethod->render(renderer);
}
};
@ -63,26 +150,6 @@ namespace tvg
PaintMethod(T* _inst) : inst(_inst) {}
~PaintMethod(){}
bool rotate(float degree) override
{
return inst->rotate(degree);
}
bool scale(float factor) override
{
return inst->scale(factor);
}
bool translate(float x, float y) override
{
return inst->translate(x, y);
}
bool transform(const Matrix& m) override
{
return inst->transform(m);
}
bool bounds(float* x, float* y, float* w, float* h) const override
{
return inst->bounds(x, y, w, h);
@ -93,9 +160,9 @@ namespace tvg
return inst->dispose(renderer);
}
bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag)
bool update(RenderMethod& renderer, const RenderTransform* transform, RenderUpdateFlag flag)
{
return inst->update(renderer, pTransform, pFlag);
return inst->update(renderer, transform, flag);
}
bool render(RenderMethod& renderer)

View file

@ -18,7 +18,6 @@
#define _TVG_PICTURE_IMPL_H_
#include "tvgCommon.h"
#include "tvgSceneImpl.h"
/************************************************************************/
/* Internal Class Implementation */
@ -27,145 +26,54 @@
struct Picture::Impl
{
unique_ptr<Loader> loader = nullptr;
Scene* scene = nullptr;
RenderTransform *rTransform = nullptr;
uint32_t flag = RenderUpdateFlag::None;
~Impl()
{
if (rTransform) delete(rTransform);
}
Paint* paint = nullptr;
bool dispose(RenderMethod& renderer)
{
if (!scene) return false;
if (!paint) return false;
scene->IMPL->dispose(renderer);
delete(scene);
paint->IMPL->dispose(renderer);
delete(paint);
return true;
}
bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag)
bool update(RenderMethod &renderer, const RenderTransform* transform, RenderUpdateFlag flag)
{
if (loader) {
auto scene = loader->data();
if (scene) {
this->scene = scene.release();
if (!this->scene) return false;
this->paint = scene.release();
if (!this->paint) return false;
loader->close();
}
}
if (!scene) return false;
if (!paint) return false;
if (flag & RenderUpdateFlag::Transform) {
if (!rTransform) return false;
if (!rTransform->update()) {
delete(rTransform);
rTransform = nullptr;
}
}
auto ret = true;
if (rTransform && pTransform) {
RenderTransform outTransform(pTransform, rTransform);
ret = scene->IMPL->update(renderer, &outTransform, flag);
} else {
auto outTransform = pTransform ? pTransform : rTransform;
ret = scene->IMPL->update(renderer, outTransform, flag);
}
flag = RenderUpdateFlag::None;
return ret;
return paint->IMPL->update(renderer, transform, flag);
}
bool render(RenderMethod &renderer)
{
if (!scene) return false;
return scene->IMPL->render(renderer);
if (!paint) return false;
return paint->IMPL->render(renderer);
}
bool size(float* w, float* h)
{
if (loader) {
if (w) *w = loader->vw;
if (h) *h = loader->vh;
return true;
}
return false;
if (!loader) return false;
if (w) *w = loader->vw;
if (h) *h = loader->vh;
return true;
}
bool bounds(float* x, float* y, float* w, float* h)
{
if (!scene) return false;
return scene->IMPL->bounds(x, y, w, h);
if (!paint) return false;
return paint->IMPL->bounds(x, y, w, h);
}
bool scale(float factor)
{
if (rTransform) {
if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
} else {
if (fabsf(factor) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->scale = factor;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool rotate(float degree)
{
if (rTransform) {
if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
} else {
if (fabsf(degree) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->degree = degree;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool translate(float x, float y)
{
if (rTransform) {
if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
} else {
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->x = x;
rTransform->y = y;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool transform(const Matrix& m)
{
if (!rTransform) {
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->override(m);
flag |= RenderUpdateFlag::Transform;
return true;
}
Result load(const string& path)
{
if (loader) loader->close();

View file

@ -26,18 +26,11 @@
struct Scene::Impl
{
vector<Paint*> paints;
RenderTransform *rTransform = nullptr;
uint32_t flag = RenderUpdateFlag::None;
~Impl()
{
if (rTransform) delete(rTransform);
}
bool dispose(RenderMethod& renderer)
{
for (auto paint : paints) {
paint->IMPL->method()->dispose(renderer);
paint->IMPL->dispose(renderer);
delete(paint);
}
paints.clear();
@ -45,43 +38,18 @@ struct Scene::Impl
return true;
}
bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag)
bool update(RenderMethod &renderer, const RenderTransform* transform, RenderUpdateFlag flag)
{
for(auto paint: paints) {
if (!paint->IMPL->method()->update(renderer, transform, flag)) return false;
if (!paint->IMPL->update(renderer, transform, static_cast<uint32_t>(flag))) return false;
}
return true;
}
bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag)
{
if (flag & RenderUpdateFlag::Transform) {
if (!rTransform) return false;
if (!rTransform->update()) {
delete(rTransform);
rTransform = nullptr;
}
}
auto ret = true;
if (rTransform && pTransform) {
RenderTransform outTransform(pTransform, rTransform);
ret = updateInternal(renderer, &outTransform, pFlag | flag);
} else {
auto outTransform = pTransform ? pTransform : rTransform;
ret = updateInternal(renderer, outTransform, pFlag | flag);
}
flag = RenderUpdateFlag::None;
return ret;
}
bool render(RenderMethod &renderer)
{
for(auto paint: paints) {
if(!paint->IMPL->method()->render(renderer)) return false;
if(!paint->IMPL->render(renderer)) return false;
}
return true;
}
@ -99,7 +67,7 @@ struct Scene::Impl
auto w2 = 0.0f;
auto h2 = 0.0f;
if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false;
if (paint->IMPL->bounds(&x2, &y2, &w2, &h2)) return false;
//Merge regions
if (x2 < x) x = x2;
@ -115,65 +83,6 @@ struct Scene::Impl
return true;
}
bool scale(float factor)
{
if (rTransform) {
if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
} else {
if (fabsf(factor) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->scale = factor;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool rotate(float degree)
{
if (rTransform) {
if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
} else {
if (fabsf(degree) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->degree = degree;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool translate(float x, float y)
{
if (rTransform) {
if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
} else {
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->x = x;
rTransform->y = y;
flag |= RenderUpdateFlag::Transform;
return true;
}
bool transform(const Matrix& m)
{
if (!rTransform) {
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->override(m);
flag |= RenderUpdateFlag::Transform;
return true;
}
};
#endif //_TVG_SCENE_IMPL_H_

View file

@ -45,12 +45,10 @@ struct Shape::Impl
ShapePath *path = nullptr;
Fill *fill = nullptr;
ShapeStroke *stroke = nullptr;
RenderTransform *rTransform = nullptr;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
uint32_t flag = RenderUpdateFlag::None;
void *edata = nullptr; //engine data
Shape *shape = nullptr;
uint32_t flag = RenderUpdateFlag::None;
Impl(Shape* s) : path(new ShapePath), shape(s)
{
@ -61,7 +59,6 @@ struct Shape::Impl
if (path) delete(path);
if (fill) delete(fill);
if (stroke) delete(stroke);
if (rTransform) delete(rTransform);
}
bool dispose(RenderMethod& renderer)
@ -74,23 +71,9 @@ struct Shape::Impl
return renderer.render(*shape, edata);
}
bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag)
bool update(RenderMethod& renderer, const RenderTransform* transform, RenderUpdateFlag pFlag)
{
if (flag & RenderUpdateFlag::Transform) {
if (!rTransform) return false;
if (!rTransform->update()) {
delete(rTransform);
rTransform = nullptr;
}
}
if (rTransform && pTransform) {
RenderTransform outTransform(pTransform, rTransform);
edata = renderer.prepare(*shape, edata, &outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
} else {
auto outTransform = pTransform ? pTransform : rTransform;
edata = renderer.prepare(*shape, edata, outTransform, static_cast<RenderUpdateFlag>(pFlag | flag));
}
edata = renderer.prepare(*shape, edata, transform, static_cast<RenderUpdateFlag>(pFlag | flag));
flag = RenderUpdateFlag::None;
@ -104,66 +87,6 @@ struct Shape::Impl
return path->bounds(x, y, w, h);
}
bool scale(float factor)
{
if (rTransform) {
if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
} else {
if (fabsf(factor) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->scale = factor;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool rotate(float degree)
{
if (rTransform) {
if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
} else {
if (fabsf(degree) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->degree = degree;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool translate(float x, float y)
{
if (rTransform) {
if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
} else {
if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->x = x;
rTransform->y = y;
if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform;
return true;
}
bool transform(const Matrix& m)
{
if (!rTransform) {
rTransform = new RenderTransform();
if (!rTransform) return false;
}
rTransform->override(m);
flag |= RenderUpdateFlag::Transform;
return true;
}
bool strokeWidth(float width)
{
//TODO: Size Exception?