common: code refactoring for simplicity.

Introduce internal PaintMethod since there more derived paint classes are coming.

This PaintMethod is a sort of Strategy Pattern method.

Change-Id: I29c49f5d4ddbfb9e429d4976636b20b39914ee20
This commit is contained in:
Hermet Park 2020-07-30 14:47:04 +09:00
parent 07e5c233a7
commit 8dca270a30
9 changed files with 54 additions and 95 deletions

View file

@ -105,8 +105,9 @@ public:
Result transform(const Matrix& m) noexcept;
Result bounds(float* x, float* y, float* w, float* h) const noexcept;
_TVG_DECALRE_IDENTIFIER();
_TVG_DECLARE_PRIVATE(Paint);
_TVG_DECLARE_ACCESSOR(Canvas);
_TVG_DECLARE_ACCESSOR(Scene);
};
@ -161,7 +162,6 @@ public:
virtual Result draw() noexcept;
virtual Result sync() noexcept;
_TVG_DECLARE_ACCESSOR(Scene);
_TVG_DECLARE_PRIVATE(Canvas);
};
@ -264,8 +264,6 @@ public:
static std::unique_ptr<Shape> gen() noexcept;
_TVG_DECLARE_PRIVATE(Shape);
_TVG_DECLARE_ACCESSOR(Canvas);
_TVG_DECLARE_ACCESSOR(Scene);
};
@ -288,7 +286,6 @@ public:
static std::unique_ptr<Scene> gen() noexcept;
_TVG_DECLARE_ACCESSOR(Canvas);
_TVG_DECLARE_PRIVATE(Scene);
};

View file

@ -56,14 +56,7 @@ struct Canvas::Impl
if (!renderer->clear()) return Result::InsufficientCondition;
for (auto paint : paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->dispose(*renderer)) return Result::InsufficientCondition;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->dispose(*renderer)) return Result::InsufficientCondition;
}
paint->IMPL->method->dispose(*renderer);
delete(paint);
}
paints.clear();
@ -77,24 +70,14 @@ struct Canvas::Impl
//Update single paint node
if (paint) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition;
if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) {
return Result::InsufficientCondition;
}
//Update retained all paint nodes
} else {
for(auto paint: paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition;
if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) {
return Result::InsufficientCondition;
}
}
}
@ -108,14 +91,7 @@ struct Canvas::Impl
if (!renderer->preRender()) return Result::InsufficientCondition;
for(auto paint: paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition;
} else {
auto shape = static_cast<Shape*>(paint);
if(!SHAPE_IMPL->render(*renderer)) return Result::InsufficientCondition;
}
if(!paint->IMPL->method->render(*renderer)) return Result::InsufficientCondition;
}
if (!renderer->postRender()) return Result::InsufficientCondition;

View file

@ -34,9 +34,6 @@ using namespace tvg;
#define SCENE_IMPL scene->pImpl.get()
#define SHAPE_IMPL shape->pImpl.get()
#define PAINT_ID_SHAPE 0
#define PAINT_ID_SCENE 1
#define FILL_ID_LINEAR 0
#define FILL_ID_RADIAL 1

View file

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

View file

@ -19,57 +19,78 @@
namespace tvg
{
struct ITransformMethod
struct PaintMethod
{
virtual ~ITransformMethod(){}
virtual ~PaintMethod(){}
virtual bool dispose(RenderMethod& renderer) = 0;
virtual bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t 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
{
ITransformMethod* ts = nullptr;
PaintMethod* method = nullptr;
~Impl() {
if (ts) delete(ts);
if (method) delete(method);
}
};
template<class T>
struct TransformMethod : ITransformMethod
struct TransformMethod : PaintMethod
{
T* _inst = nullptr;
T* inst = nullptr;
TransformMethod(T* inst) : _inst(inst) {}
TransformMethod(T* inst) : inst(_inst) {}
~TransformMethod(){}
bool rotate(float degree) override
{
return _inst->rotate(degree);
return inst->rotate(degree);
}
bool scale(float factor) override
{
return _inst->scale(factor);
return inst->scale(factor);
}
bool translate(float x, float y) override
{
return _inst->translate(x, y);
return inst->translate(x, y);
}
bool transform(const Matrix& m) override
{
return _inst->transform(m);
return inst->transform(m);
}
bool bounds(float* x, float* y, float* w, float* h) const override
{
return _inst->bounds(x, y, w, h);
return inst->bounds(x, y, w, h);
}
bool dispose(RenderMethod& renderer)
{
return inst->dispose(renderer);
}
bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag)
{
return inst->update(renderer, pTransform, pFlag);
}
bool render(RenderMethod& renderer)
{
return inst->render(renderer);
}
};
}

View file

@ -25,9 +25,7 @@
Scene::Scene() : pImpl(make_unique<Impl>())
{
_id = PAINT_ID_SCENE;
Paint::pImpl.get()->ts = pImpl.get()->transformMethod();
Paint::IMPL->method = IMPL->transformMethod();
}

View file

@ -40,14 +40,7 @@ struct Scene::Impl
bool dispose(RenderMethod& renderer)
{
for (auto paint : paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->dispose(renderer)) return false;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->dispose(renderer)) return false;
}
paint->IMPL->method->dispose(renderer);
delete(paint);
}
paints.clear();
@ -58,14 +51,7 @@ struct Scene::Impl
bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag)
{
for(auto paint: paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->update(renderer, transform, flag)) return false;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->update(renderer, transform, flag)) return false;
}
if (!paint->IMPL->method->update(renderer, transform, flag)) return false;
}
return true;
}
@ -108,14 +94,7 @@ struct Scene::Impl
bool render(RenderMethod &renderer)
{
for(auto paint: paints) {
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if(!SCENE_IMPL->render(renderer)) return false;
} else {
auto shape = static_cast<Shape*>(paint);
if(!SHAPE_IMPL->render(renderer)) return false;
}
if(!paint->IMPL->method->render(renderer)) return false;
}
return true;
}
@ -139,14 +118,7 @@ struct Scene::Impl
auto w2 = 0.0f;
auto h2 = 0.0f;
if (paint->id() == PAINT_ID_SCENE) {
//We know renderer type, avoid dynamic_cast for performance.
auto scene = static_cast<Scene*>(paint);
if (!SCENE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false;
} else {
auto shape = static_cast<Shape*>(paint);
if (!SHAPE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false;
}
if (paint->IMPL->method->bounds(&x2, &y2, &w2, &h2)) return false;
//Merge regions
if (x2 < x) x = x2;
@ -232,7 +204,7 @@ struct Scene::Impl
return Result::Success;
}
ITransformMethod* transformMethod()
PaintMethod* transformMethod()
{
return new TransformMethod<Scene::Impl>(this);
}

View file

@ -31,9 +31,7 @@ constexpr auto PATH_KAPPA = 0.552284f;
Shape :: Shape() : pImpl(make_unique<Impl>(this))
{
_id = PAINT_ID_SHAPE;
Paint::pImpl.get()->ts = pImpl.get()->transformMethod();
Paint::IMPL->method = IMPL->transformMethod();
}

View file

@ -238,7 +238,7 @@ struct Shape::Impl
}
ITransformMethod* transformMethod()
PaintMethod* transformMethod()
{
return new TransformMethod<Shape::Impl>(this);
}