common: introducing basic iterators functionality

The introduced Iterator class enables to access the children nodes
of a given Paint.
This commit is contained in:
Mira Grudzinska 2021-07-19 10:28:14 +02:00 committed by GitHub
parent 9ea6962c5a
commit f23cba89f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 155 additions and 3 deletions

View file

@ -299,6 +299,51 @@ public:
*/ */
uint8_t opacity() const noexcept; uint8_t opacity() const noexcept;
/**
* @brief Const forward iterator-like class enabling the iteration over the children nodes of the given paint.
*
* For the Scene-type Paint the children nodes represent the paints pushed into the Scene - the order of the children nodes is the same as the order as they were pushed. For the Picture-type Paint the child node is the read image in one of the supported formats. The Shape-type Paint doesn't have any child nodes.
*
* @BETA_API
*/
class Iterator
{
const Paint* parent;
const Paint* child;
public:
Iterator (Paint* p = nullptr, Paint* c = nullptr);
const Paint& operator*() const;
Iterator& operator++();
Iterator operator++(int);
friend bool operator!=(const Iterator& it1, const Iterator& it2)
{
return it1.child != it2.child;
};
friend bool operator==(const Iterator& it1, const Iterator& it2)
{
return it1.child == it2.child;
};
};
/**
* @brief Gets the iterator to the first child node.
*
* @return The iterator pointing to the first element of the children nodes of the given paint object.
*
* @BETA_API
*/
Iterator begin() const noexcept;
/**
* @brief Gets the iterator to the past-the end child node.
*
* @return The iterator referring to the past-the-end element of the children nodes of the given paint object.
*
* @BETA_API
*/
Iterator end() const noexcept;
/** /**
* @brief Gets the composition target object and the composition method. * @brief Gets the composition target object and the composition method.
* *
@ -685,7 +730,7 @@ public:
* The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments. * The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments.
* The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners. * The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners.
* *
* The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments. * The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments.
* *
* The rectangle is treated as a new sub-path - it is not connected with the previous sub-path. * The rectangle is treated as a new sub-path - it is not connected with the previous sub-path.
* *
@ -973,7 +1018,7 @@ public:
* @class Picture * @class Picture
* *
* @brief A class representing an image read in one of the supported formats: raw, svg, png and etc. * @brief A class representing an image read in one of the supported formats: raw, svg, png and etc.
* Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas. * Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas.
* *
* @note Supported formats are depended on the available TVG loaders. * @note Supported formats are depended on the available TVG loaders.
*/ */

View file

@ -331,3 +331,44 @@ uint8_t Paint::opacity() const noexcept
{ {
return pImpl->opacity; return pImpl->opacity;
} }
Paint::Iterator Paint::begin() const noexcept
{
return pImpl->begin();
}
Paint::Iterator Paint::end() const noexcept
{
return Paint::Iterator();
}
Paint::Iterator::Iterator(Paint* p, Paint* c) : parent{p}, child{c}
{
}
const Paint& Paint::Iterator::operator*() const
{
return *child;
}
Paint::Iterator& Paint::Iterator::operator++() //prefix
{
const Paint* nextChild = nullptr;
if (parent) nextChild = parent->pImpl->next(child);
child = nextChild;
return *this;
}
Paint::Iterator Paint::Iterator::operator++(int) //postfix
{
Iterator tmp = *this;
++*this;
return tmp;
}

View file

@ -37,6 +37,8 @@ namespace tvg
virtual bool bounds(float* x, float* y, float* w, float* h) const = 0; virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
virtual RenderRegion bounds(RenderMethod& renderer) const = 0; virtual RenderRegion bounds(RenderMethod& renderer) const = 0;
virtual Paint* duplicate() = 0; virtual Paint* duplicate() = 0;
virtual Paint::Iterator begin() = 0;
virtual const Paint* next(const Paint* p) = 0;
}; };
struct Paint::Impl struct Paint::Impl
@ -111,6 +113,17 @@ namespace tvg
void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag); void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag);
bool render(RenderMethod& renderer); bool render(RenderMethod& renderer);
Paint* duplicate(); Paint* duplicate();
Paint::Iterator begin()
{
return smethod->begin();
}
const Paint* next(const Paint* p)
{
return smethod->next(p);
}
}; };
@ -151,6 +164,17 @@ namespace tvg
{ {
return inst->duplicate(); return inst->duplicate();
} }
Paint::Iterator begin() override
{
return inst->begin();
}
const Paint* next(const Paint* p) override
{
return inst->next(p);
}
}; };
} }

View file

@ -218,6 +218,16 @@ struct Picture::Impl
return ret.release(); return ret.release();
} }
Paint::Iterator begin()
{
return Paint::Iterator(picture, paint);
}
const Paint* next(const Paint* p)
{
return nullptr;
}
}; };
#endif //_TVG_PICTURE_IMPL_H_ #endif //_TVG_PICTURE_IMPL_H_

View file

@ -25,7 +25,7 @@
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
Scene::Scene() : pImpl(new Impl()) Scene::Scene() : pImpl(new Impl(this))
{ {
_id = PAINT_ID_SCENE; _id = PAINT_ID_SCENE;
Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl)); Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl));

View file

@ -32,6 +32,7 @@
struct Scene::Impl struct Scene::Impl
{ {
Array<Paint*> paints; Array<Paint*> paints;
Scene* scene = nullptr;
uint8_t opacity; //for composition uint8_t opacity; //for composition
RenderMethod* renderer = nullptr; //keep it for explicit clear RenderMethod* renderer = nullptr; //keep it for explicit clear
@ -42,6 +43,10 @@ struct Scene::Impl
} }
} }
Impl(Scene* s) : scene(s)
{
}
bool dispose(RenderMethod& renderer) bool dispose(RenderMethod& renderer)
{ {
for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
@ -181,6 +186,23 @@ struct Scene::Impl
paints.clear(); paints.clear();
renderer = nullptr; renderer = nullptr;
} }
Paint::Iterator begin()
{
if (paints.count > 0) return Paint::Iterator(scene, *(paints.data));
return Paint::Iterator();
}
const Paint* next(const Paint* p)
{
for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
auto tmp = paint;
if (*paint == p && ++tmp < (paints.data + paints.count)) {
return *tmp;
}
}
return nullptr;
}
}; };
#endif //_TVG_SCENE_IMPL_H_ #endif //_TVG_SCENE_IMPL_H_

View file

@ -390,6 +390,16 @@ struct Shape::Impl
return ret.release(); return ret.release();
} }
Paint::Iterator begin()
{
return Paint::Iterator();
}
const Paint* next(const Paint* p)
{
return nullptr;
}
}; };
#endif //_TVG_SHAPE_IMPL_H_ #endif //_TVG_SHAPE_IMPL_H_