renderer/accessor: revise set() api for animation support

before:
unique_ptr<Picture> Accessor::set(unique_ptr<Picture> picture, function<bool(const Paint* paint)> func)

after:
Result Accessor::set(const Picture* picture, std::function<bool(const Paint* paint, void* data)> func, void* data)
This commit is contained in:
Hermet Park 2024-07-04 16:09:10 +09:00
parent 52a69b9a93
commit 21d3cc4eb9
4 changed files with 35 additions and 20 deletions

View file

@ -42,7 +42,7 @@ struct UserExample : tvgexam::Example
//The callback function from lambda expression.
//This function will be called for every paint nodes of the picture tree.
auto f = [](const tvg::Paint* paint) -> bool
auto f = [](const tvg::Paint* paint, void* data) -> bool
{
if (paint->type() == tvg::Type::Shape) {
auto shape = (tvg::Shape*) paint;
@ -58,7 +58,7 @@ struct UserExample : tvgexam::Example
return true;
};
picture = accessor->set(std::move(picture), f);
if (!tvgexam::verify(accessor->set(picture.get(), f, nullptr))) return false;
canvas->push(std::move(picture));

View file

@ -2119,17 +2119,20 @@ class TVG_API Accessor final
public:
~Accessor();
TVG_DEPRECATED std::unique_ptr<Picture> set(std::unique_ptr<Picture> picture, std::function<bool(const Paint* paint)> func) noexcept;
/**
* @brief Set the access function for traversing the Picture scene tree nodes.
*
* @param[in] picture The picture node to traverse the internal scene-tree.
* @param[in] func The callback function calling for every paint nodes of the Picture.
*
* @return Return the given @p picture instance.
* @param[in] data Data passed to the @p func as its argument.
*
* @note The bitmap based picture might not have the scene-tree.
*
* @note Experimental API
*/
std::unique_ptr<Picture> set(std::unique_ptr<Picture> picture, std::function<bool(const Paint* paint)> func) noexcept;
Result set(const Picture* picture, std::function<bool(const Paint* paint, void* data)> func, void* data) noexcept;
/**
* @brief Creates a new Accessor object.

View file

@ -26,15 +26,15 @@
/* Internal Class Implementation */
/************************************************************************/
static bool accessChildren(Iterator* it, function<bool(const Paint* paint)> func)
static bool accessChildren(Iterator* it, function<bool(const Paint* paint, void* data)> func, void* data)
{
while (auto child = it->next()) {
//Access the child
if (!func(child)) return false;
if (!func(child, data)) return false;
//Access the children of the child
if (auto it2 = IteratorAccessor::iterator(child)) {
if (!accessChildren(it2, func)) {
if (!accessChildren(it2, func, data)) {
delete(it2);
return false;
}
@ -44,26 +44,40 @@ static bool accessChildren(Iterator* it, function<bool(const Paint* paint)> func
return true;
}
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
unique_ptr<Picture> Accessor::set(unique_ptr<Picture> picture, function<bool(const Paint* paint)> func) noexcept
TVG_DEPRECATED unique_ptr<Picture> Accessor::set(unique_ptr<Picture> picture, function<bool(const Paint* paint)> func) noexcept
{
auto p = picture.get();
if (!p || !func) return picture;
auto backward = [](const tvg::Paint* paint, void* data) -> bool
{
auto func = reinterpret_cast<function<bool(const Paint* paint)>*>(data);
if (!(*func)(paint)) return false;
return true;
};
set(picture.get(), backward, reinterpret_cast<void*>(&func));
return picture;
}
Result Accessor::set(const Picture* picture, function<bool(const Paint* paint, void* data)> func, void* data) noexcept
{
if (!picture || !func) return Result::InvalidArguments;
//Use the Preorder Tree-Search
//Root
if (!func(p)) return picture;
if (!func(picture, data)) return Result::Success;
//Children
if (auto it = IteratorAccessor::iterator(p)) {
accessChildren(it, func);
if (auto it = IteratorAccessor::iterator(picture)) {
accessChildren(it, func, data);
delete(it);
}
return picture;
return Result::Success;
}

View file

@ -55,11 +55,10 @@ TEST_CASE("Set", "[tvgAccessor]")
REQUIRE(accessor);
//Case 1
picture = accessor->set(std::move(picture), nullptr);
REQUIRE(picture);
REQUIRE(accessor->set(picture.get(), nullptr, nullptr) == Result::InvalidArguments);
//Case 2
auto f = [](const tvg::Paint* paint) -> bool
auto f = [](const tvg::Paint* paint, void* data) -> bool
{
if (paint->type() == Type::Shape) {
auto shape = (tvg::Shape*) paint;
@ -71,8 +70,7 @@ TEST_CASE("Set", "[tvgAccessor]")
return true;
};
picture = accessor->set(std::move(picture), f);
REQUIRE(picture);
REQUIRE(accessor->set(picture.get(), f, nullptr) == Result::Success);
REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
}