mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
renderer: added parent scene query api
added 2 more APIs for user convenience to allow backtracking tree traversal. API Additions: - const Paint* Paint::scene() const - const Tvg_Paint* tvg_paint_get_scene(const Tvg_Paint* paint)
This commit is contained in:
parent
0f20a4a1a8
commit
563f8b2f78
11 changed files with 115 additions and 57 deletions
18
inc/thorvg.h
18
inc/thorvg.h
|
@ -309,6 +309,21 @@ class TVG_API Paint
|
||||||
public:
|
public:
|
||||||
virtual ~Paint();
|
virtual ~Paint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the parent paint object.
|
||||||
|
*
|
||||||
|
* This function returns a pointer to the parent object if the current paint
|
||||||
|
* belongs to one. Otherwise, it returns @c nullptr.
|
||||||
|
*
|
||||||
|
* @return A pointer to the parent object if available, otherwise @c nullptr.
|
||||||
|
*
|
||||||
|
* @see Scene::push()
|
||||||
|
* @see Canvas::push()
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
const Paint* parent() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the angle by which the object is rotated.
|
* @brief Sets the angle by which the object is rotated.
|
||||||
*
|
*
|
||||||
|
@ -381,6 +396,8 @@ public:
|
||||||
*
|
*
|
||||||
* @param[in] target The paint of the target object.
|
* @param[in] target The paint of the target object.
|
||||||
* @param[in] method The method used to mask the source object with the target.
|
* @param[in] method The method used to mask the source object with the target.
|
||||||
|
*
|
||||||
|
* @retval Result::InsufficientCondition if the target has already belonged to another paint.
|
||||||
*/
|
*/
|
||||||
Result mask(Paint* target, MaskMethod method) noexcept;
|
Result mask(Paint* target, MaskMethod method) noexcept;
|
||||||
|
|
||||||
|
@ -392,6 +409,7 @@ public:
|
||||||
* @param[in] clipper The shape object as the clipper.
|
* @param[in] clipper The shape object as the clipper.
|
||||||
*
|
*
|
||||||
* @retval Result::NonSupport If the @p clipper type is not Shape.
|
* @retval Result::NonSupport If the @p clipper type is not Shape.
|
||||||
|
* @retval Result::InsufficientCondition if the target has already belonged to another paint.
|
||||||
*
|
*
|
||||||
* @note @p clipper only supports the Shape type.
|
* @note @p clipper only supports the Shape type.
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
|
|
|
@ -715,7 +715,6 @@ TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_
|
||||||
|
|
||||||
/** \} */ // end defgroup ThorVGCapi_Canvas
|
/** \} */ // end defgroup ThorVGCapi_Canvas
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup ThorVGCapi_Paint Paint
|
* @defgroup ThorVGCapi_Paint Paint
|
||||||
* @brief A module for managing graphical elements. It enables duplication, transformation and composition.
|
* @brief A module for managing graphical elements. It enables duplication, transformation and composition.
|
||||||
|
@ -964,6 +963,8 @@ TVG_API Tvg_Result tvg_paint_get_obb(const Tvg_Paint* paint, Tvg_Point* pt4);
|
||||||
* @param[in] target The target object of the masking.
|
* @param[in] target The target object of the masking.
|
||||||
* @param[in] method The method used to mask the source object with the target.
|
* @param[in] method The method used to mask the source object with the target.
|
||||||
*
|
*
|
||||||
|
* @retval TVG_RESULT_INSUFFICIENT_CONDITION if the target has already belonged to another paint.
|
||||||
|
*
|
||||||
* @return Tvg_Result enumeration.
|
* @return Tvg_Result enumeration.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -993,6 +994,7 @@ TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_P
|
||||||
*
|
*
|
||||||
* @return Tvg_Result enumeration.
|
* @return Tvg_Result enumeration.
|
||||||
* @retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument.
|
* @retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument.
|
||||||
|
* @retval TVG_RESULT_INSUFFICIENT_CONDITION if the target has already belonged to another paint.
|
||||||
* @retval TVG_RESULT_NOT_SUPPORTED If the @p clipper type is not Shape.
|
* @retval TVG_RESULT_NOT_SUPPORTED If the @p clipper type is not Shape.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
|
@ -1000,6 +1002,24 @@ TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_P
|
||||||
TVG_API Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper);
|
TVG_API Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the parent paint object.
|
||||||
|
*
|
||||||
|
* This function returns a pointer to the parent object if the current paint
|
||||||
|
* belongs to one. Otherwise, it returns @c nullptr.
|
||||||
|
*
|
||||||
|
* @param[in] paint The Tvg_Paint object of which to get the scene.
|
||||||
|
*
|
||||||
|
* @return A pointer to the parent object if available, otherwise @c nullptr.
|
||||||
|
*
|
||||||
|
* @see tvg_scene_push()
|
||||||
|
* @see tvg_canvas_push()
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
TVG_API const Tvg_Paint* tvg_paint_get_parent(const Tvg_Paint* paint);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the unique value of the paint instance indicating the instance type.
|
* @brief Gets the unique value of the paint instance indicating the instance type.
|
||||||
*
|
*
|
||||||
|
|
|
@ -169,6 +169,12 @@ TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_
|
||||||
/* Paint API */
|
/* Paint API */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
TVG_API const Tvg_Paint* tvg_paint_get_parent(const Tvg_Paint* paint)
|
||||||
|
{
|
||||||
|
return (const Tvg_Paint*) reinterpret_cast<const Paint*>(paint)->parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint)
|
TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint)
|
||||||
{
|
{
|
||||||
if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
|
if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
|
||||||
|
|
|
@ -51,10 +51,7 @@ struct Canvas::Impl
|
||||||
Result push(Paint* target, Paint* at)
|
Result push(Paint* target, Paint* at)
|
||||||
{
|
{
|
||||||
//You cannot push paints during rendering.
|
//You cannot push paints during rendering.
|
||||||
if (status == Status::Drawing) {
|
if (status == Status::Drawing) return Result::InsufficientCondition;
|
||||||
TVG_DELETE(target);
|
|
||||||
return Result::InsufficientCondition;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ret = scene->push(target, at);
|
auto ret = scene->push(target, at);
|
||||||
if (ret != Result::Success) return ret;
|
if (ret != Result::Success) return ret;
|
||||||
|
|
|
@ -392,19 +392,15 @@ Result Paint::clip(Paint* clipper) noexcept
|
||||||
{
|
{
|
||||||
if (clipper && clipper->type() != Type::Shape) {
|
if (clipper && clipper->type() != Type::Shape) {
|
||||||
TVGERR("RENDERER", "Clipping only supports the Shape!");
|
TVGERR("RENDERER", "Clipping only supports the Shape!");
|
||||||
TVG_DELETE(clipper);
|
|
||||||
return Result::NonSupport;
|
return Result::NonSupport;
|
||||||
}
|
}
|
||||||
pImpl->clip(clipper);
|
return pImpl->clip(clipper);
|
||||||
return Result::Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result Paint::mask(Paint* target, MaskMethod method) noexcept
|
Result Paint::mask(Paint* target, MaskMethod method) noexcept
|
||||||
{
|
{
|
||||||
if (pImpl->mask(target, method)) return Result::Success;
|
return pImpl->mask(target, method);
|
||||||
if (target) TVG_DELETE(target);
|
|
||||||
return Result::InvalidArguments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,7 +444,7 @@ uint8_t Paint::ref() noexcept
|
||||||
|
|
||||||
uint8_t Paint::unref(bool free) noexcept
|
uint8_t Paint::unref(bool free) noexcept
|
||||||
{
|
{
|
||||||
return pImpl->unref(free);
|
return pImpl->unrefx(free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -456,3 +452,9 @@ uint8_t Paint::refCnt() const noexcept
|
||||||
{
|
{
|
||||||
return pImpl->refCnt;
|
return pImpl->refCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Paint* Paint::parent() const noexcept
|
||||||
|
{
|
||||||
|
return pImpl->parent;
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ namespace tvg
|
||||||
struct Paint::Impl
|
struct Paint::Impl
|
||||||
{
|
{
|
||||||
Paint* paint = nullptr;
|
Paint* paint = nullptr;
|
||||||
|
Paint* parent = nullptr;
|
||||||
Mask* maskData = nullptr;
|
Mask* maskData = nullptr;
|
||||||
Paint* clipper = nullptr;
|
Paint* clipper = nullptr;
|
||||||
RenderMethod* renderer = nullptr;
|
RenderMethod* renderer = nullptr;
|
||||||
|
@ -91,11 +92,11 @@ namespace tvg
|
||||||
virtual ~Impl()
|
virtual ~Impl()
|
||||||
{
|
{
|
||||||
if (maskData) {
|
if (maskData) {
|
||||||
maskData->target->unref();
|
PAINT(maskData->target)->unref();
|
||||||
tvg::free(maskData);
|
tvg::free(maskData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipper) clipper->unref();
|
if (clipper) PAINT(clipper)->unref();
|
||||||
|
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
if (rd) renderer->dispose(rd);
|
if (rd) renderer->dispose(rd);
|
||||||
|
@ -110,13 +111,18 @@ namespace tvg
|
||||||
return refCnt;
|
return refCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t unref(bool free)
|
uint8_t unref(bool free = true)
|
||||||
|
{
|
||||||
|
parent = nullptr;
|
||||||
|
return unrefx(free);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t unrefx(bool free)
|
||||||
{
|
{
|
||||||
if (refCnt > 0) --refCnt;
|
if (refCnt > 0) --refCnt;
|
||||||
else TVGERR("RENDERER", "Corrupted Reference Count!");
|
else TVGERR("RENDERER", "Corrupted Reference Count!");
|
||||||
|
|
||||||
if (free && refCnt == 0) {
|
if (free && refCnt == 0) {
|
||||||
//TODO: use the global dismiss function?
|
|
||||||
delete(paint);
|
delete(paint);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -146,37 +152,37 @@ namespace tvg
|
||||||
return tr.m;
|
return tr.m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clip(Paint* clp)
|
Result clip(Paint* clp)
|
||||||
{
|
{
|
||||||
if (clipper) clipper->unref(clipper != clp);
|
if (PAINT(clp)->parent) return Result::InsufficientCondition;
|
||||||
|
if (clipper) PAINT(clipper)->unref(clipper != clp);
|
||||||
clipper = clp;
|
clipper = clp;
|
||||||
if (!clp) return;
|
if (clp) {
|
||||||
|
clp->ref();
|
||||||
clipper->ref();
|
PAINT(clp)->parent = parent;
|
||||||
|
}
|
||||||
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mask(Paint* target, MaskMethod method)
|
Result mask(Paint* target, MaskMethod method)
|
||||||
{
|
{
|
||||||
//Invalid case
|
if (target && PAINT(target)->parent) return Result::InsufficientCondition;
|
||||||
if ((!target && method != MaskMethod::None) || (target && method == MaskMethod::None)) return false;
|
|
||||||
|
|
||||||
if (maskData) {
|
if (maskData) {
|
||||||
maskData->target->unref(maskData->target != target);
|
PAINT(maskData->target)->unref(maskData->target != target);
|
||||||
//Reset scenario
|
|
||||||
if (!target && method == MaskMethod::None) {
|
|
||||||
tvg::free(maskData);
|
tvg::free(maskData);
|
||||||
maskData = nullptr;
|
maskData = nullptr;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!target && method == MaskMethod::None) return true;
|
if (!target && method == MaskMethod::None) return Result::Success;
|
||||||
|
|
||||||
maskData = tvg::malloc<Mask*>(sizeof(Mask));
|
maskData = tvg::malloc<Mask*>(sizeof(Mask));
|
||||||
}
|
|
||||||
target->ref();
|
target->ref();
|
||||||
maskData->target = target;
|
maskData->target = target;
|
||||||
|
PAINT(target)->parent = parent;
|
||||||
maskData->source = paint;
|
maskData->source = paint;
|
||||||
maskData->method = method;
|
maskData->method = method;
|
||||||
return true;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaskMethod mask(const Paint** target) const
|
MaskMethod mask(const Paint** target) const
|
||||||
|
@ -193,12 +199,12 @@ namespace tvg
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
if (clipper) {
|
if (clipper) {
|
||||||
clipper->unref();
|
PAINT(clipper)->unref();
|
||||||
clipper = nullptr;
|
clipper = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maskData) {
|
if (maskData) {
|
||||||
maskData->target->unref();
|
PAINT(maskData->target)->unref();
|
||||||
tvg::free(maskData);
|
tvg::free(maskData);
|
||||||
maskData = nullptr;
|
maskData = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +214,7 @@ namespace tvg
|
||||||
tr.scale = 1.0f;
|
tr.scale = 1.0f;
|
||||||
tr.overriding = false;
|
tr.overriding = false;
|
||||||
|
|
||||||
|
parent = nullptr;
|
||||||
blendMethod = BlendMethod::Normal;
|
blendMethod = BlendMethod::Normal;
|
||||||
renderFlag = RenderUpdateFlag::None;
|
renderFlag = RenderUpdateFlag::None;
|
||||||
ctxFlag = ContextFlag::Default;
|
ctxFlag = ContextFlag::Default;
|
||||||
|
|
|
@ -165,7 +165,10 @@ struct Picture::Impl : Paint::Impl
|
||||||
auto picture = Picture::gen();
|
auto picture = Picture::gen();
|
||||||
auto dup = PICTURE(picture);
|
auto dup = PICTURE(picture);
|
||||||
|
|
||||||
if (vector) dup->vector = vector->duplicate();
|
if (vector) {
|
||||||
|
dup->vector = vector->duplicate();
|
||||||
|
PAINT(dup->vector)->parent = picture;
|
||||||
|
}
|
||||||
|
|
||||||
if (loader) {
|
if (loader) {
|
||||||
dup->loader = loader;
|
dup->loader = loader;
|
||||||
|
@ -211,6 +214,7 @@ struct Picture::Impl : Paint::Impl
|
||||||
} else {
|
} else {
|
||||||
vector = loader->paint();
|
vector = loader->paint();
|
||||||
if (vector) {
|
if (vector) {
|
||||||
|
PAINT(vector)->parent = paint;
|
||||||
if (w != loader->w || h != loader->h) {
|
if (w != loader->w || h != loader->h) {
|
||||||
if (!resizing) {
|
if (!resizing) {
|
||||||
w = loader->w;
|
w = loader->w;
|
||||||
|
|
|
@ -229,6 +229,7 @@ struct Scene::Impl : Paint::Impl
|
||||||
|
|
||||||
for (auto paint : paints) {
|
for (auto paint : paints) {
|
||||||
auto cdup = paint->duplicate();
|
auto cdup = paint->duplicate();
|
||||||
|
PAINT(cdup)->parent = scene;
|
||||||
cdup->ref();
|
cdup->ref();
|
||||||
dup->paints.push_back(cdup);
|
dup->paints.push_back(cdup);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +243,7 @@ struct Scene::Impl : Paint::Impl
|
||||||
{
|
{
|
||||||
auto itr = paints.begin();
|
auto itr = paints.begin();
|
||||||
while (itr != paints.end()) {
|
while (itr != paints.end()) {
|
||||||
(*itr)->unref();
|
PAINT((*itr))->unref();
|
||||||
paints.erase(itr++);
|
paints.erase(itr++);
|
||||||
}
|
}
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
|
@ -250,31 +251,24 @@ struct Scene::Impl : Paint::Impl
|
||||||
|
|
||||||
Result remove(Paint* paint)
|
Result remove(Paint* paint)
|
||||||
{
|
{
|
||||||
owned(paint);
|
if (PAINT(paint)->parent != this->paint) return Result::InsufficientCondition;
|
||||||
paint->unref();
|
PAINT(paint)->unref();
|
||||||
paints.remove(paint);
|
paints.remove(paint);
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void owned(Paint* paint)
|
|
||||||
{
|
|
||||||
#ifdef THORVG_LOG_ENABLED
|
|
||||||
for (auto p : paints) {
|
|
||||||
if (p == paint) return;
|
|
||||||
}
|
|
||||||
TVGERR("RENDERER", "The paint(%p) is not existed from the scene(%p)", paint, this->paint);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Result insert(Paint* target, Paint* at)
|
Result insert(Paint* target, Paint* at)
|
||||||
{
|
{
|
||||||
if (!target) return Result::InvalidArguments;
|
if (!target) return Result::InvalidArguments;
|
||||||
|
auto timpl = PAINT(target);
|
||||||
|
if (timpl->parent) return Result::InsufficientCondition;
|
||||||
|
|
||||||
target->ref();
|
target->ref();
|
||||||
|
|
||||||
//Relocated the paint to the current scene space
|
//Relocated the paint to the current scene space
|
||||||
PAINT(target)->renderFlag |= RenderUpdateFlag::Transform;
|
timpl->renderFlag |= RenderUpdateFlag::Transform;
|
||||||
|
|
||||||
if (at == nullptr) {
|
if (!at) {
|
||||||
paints.push_back(target);
|
paints.push_back(target);
|
||||||
} else {
|
} else {
|
||||||
//OPTIMIZE: Remove searching?
|
//OPTIMIZE: Remove searching?
|
||||||
|
@ -282,6 +276,9 @@ struct Scene::Impl : Paint::Impl
|
||||||
if (itr == paints.end()) return Result::InvalidArguments;
|
if (itr == paints.end()) return Result::InvalidArguments;
|
||||||
paints.insert(itr, target);
|
paints.insert(itr, target);
|
||||||
}
|
}
|
||||||
|
timpl->parent = paint;
|
||||||
|
if (timpl->clipper) PAINT(timpl->clipper)->parent = paint;
|
||||||
|
if (timpl->maskData) PAINT(timpl->maskData->target)->parent = paint;
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct Text::Impl : Paint::Impl
|
||||||
|
|
||||||
Impl(Text* p) : Paint::Impl(p), shape(Shape::gen())
|
Impl(Text* p) : Paint::Impl(p), shape(Shape::gen())
|
||||||
{
|
{
|
||||||
|
PAINT(shape)->parent = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl()
|
~Impl()
|
||||||
|
@ -149,6 +150,8 @@ struct Text::Impl : Paint::Impl
|
||||||
|
|
||||||
auto text = Text::gen();
|
auto text = Text::gen();
|
||||||
auto dup = TEXT(text);
|
auto dup = TEXT(text);
|
||||||
|
dup->parent = text;
|
||||||
|
|
||||||
SHAPE(shape)->duplicate(dup->shape);
|
SHAPE(shape)->duplicate(dup->shape);
|
||||||
|
|
||||||
if (loader) {
|
if (loader) {
|
||||||
|
|
|
@ -218,11 +218,8 @@ TEST_CASE("Composition", "[tvgPaint]")
|
||||||
//Negative
|
//Negative
|
||||||
REQUIRE(shape->mask(nullptr) == MaskMethod::None);
|
REQUIRE(shape->mask(nullptr) == MaskMethod::None);
|
||||||
|
|
||||||
auto comp = Shape::gen();
|
|
||||||
REQUIRE(shape->mask(comp, MaskMethod::None) == Result::InvalidArguments);
|
|
||||||
|
|
||||||
//Clipping
|
//Clipping
|
||||||
comp = Shape::gen();
|
auto comp = Shape::gen();
|
||||||
REQUIRE(shape->clip(comp) == Result::Success);
|
REQUIRE(shape->clip(comp) == Result::Success);
|
||||||
|
|
||||||
//AlphaMask
|
//AlphaMask
|
||||||
|
|
|
@ -39,18 +39,25 @@ TEST_CASE("Pushing Paints Into Scene", "[tvgScene]")
|
||||||
{
|
{
|
||||||
auto scene = unique_ptr<Scene>(Scene::gen());
|
auto scene = unique_ptr<Scene>(Scene::gen());
|
||||||
REQUIRE(scene);
|
REQUIRE(scene);
|
||||||
|
REQUIRE(scene->parent() == nullptr);
|
||||||
|
|
||||||
Paint* paints[3];
|
Paint* paints[3];
|
||||||
|
|
||||||
//Pushing Paints
|
//Pushing Paints
|
||||||
paints[0] = Shape::gen();
|
paints[0] = Shape::gen();
|
||||||
|
REQUIRE(paints[0]->parent() == nullptr);
|
||||||
REQUIRE(scene->push(paints[0]) == Result::Success);
|
REQUIRE(scene->push(paints[0]) == Result::Success);
|
||||||
|
REQUIRE(paints[0]->parent() == scene.get());
|
||||||
|
|
||||||
paints[1] = Picture::gen();
|
paints[1] = Picture::gen();
|
||||||
|
REQUIRE(paints[1]->parent() == nullptr);
|
||||||
REQUIRE(scene->push(paints[1]) == Result::Success);
|
REQUIRE(scene->push(paints[1]) == Result::Success);
|
||||||
|
REQUIRE(paints[1]->parent() == scene.get());
|
||||||
|
|
||||||
paints[2] = Picture::gen();
|
paints[2] = Picture::gen();
|
||||||
|
REQUIRE(paints[2]->parent() == nullptr);
|
||||||
REQUIRE(scene->push(paints[2]) == Result::Success);
|
REQUIRE(scene->push(paints[2]) == Result::Success);
|
||||||
|
REQUIRE(paints[2]->parent() == scene.get());
|
||||||
|
|
||||||
//Pushing Null Pointer
|
//Pushing Null Pointer
|
||||||
REQUIRE(scene->push(nullptr) == Result::InvalidArguments);
|
REQUIRE(scene->push(nullptr) == Result::InvalidArguments);
|
||||||
|
|
Loading…
Add table
Reference in a new issue