From 21d3cc4eb98dc62b6d710b8b39a6c8556c27110d Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 4 Jul 2024 16:09:10 +0900 Subject: [PATCH] renderer/accessor: revise set() api for animation support before: unique_ptr Accessor::set(unique_ptr picture, function func) after: Result Accessor::set(const Picture* picture, std::function func, void* data) --- examples/Accessor.cpp | 4 ++-- inc/thorvg.h | 9 ++++++--- src/renderer/tvgAccessor.cpp | 34 ++++++++++++++++++++++++---------- test/testAccessor.cpp | 8 +++----- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/examples/Accessor.cpp b/examples/Accessor.cpp index 0a2f870f..30b91f74 100644 --- a/examples/Accessor.cpp +++ b/examples/Accessor.cpp @@ -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)); diff --git a/inc/thorvg.h b/inc/thorvg.h index 18f95ba8..8ac91248 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -2119,17 +2119,20 @@ class TVG_API Accessor final public: ~Accessor(); + TVG_DEPRECATED std::unique_ptr set(std::unique_ptr picture, std::function 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 set(std::unique_ptr picture, std::function func) noexcept; + Result set(const Picture* picture, std::function func, void* data) noexcept; /** * @brief Creates a new Accessor object. diff --git a/src/renderer/tvgAccessor.cpp b/src/renderer/tvgAccessor.cpp index 903437f2..213cf433 100644 --- a/src/renderer/tvgAccessor.cpp +++ b/src/renderer/tvgAccessor.cpp @@ -26,15 +26,15 @@ /* Internal Class Implementation */ /************************************************************************/ -static bool accessChildren(Iterator* it, function func) +static bool accessChildren(Iterator* it, function 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 func return true; } + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ -unique_ptr Accessor::set(unique_ptr picture, function func) noexcept +TVG_DEPRECATED unique_ptr Accessor::set(unique_ptr picture, function func) noexcept { - auto p = picture.get(); - if (!p || !func) return picture; + auto backward = [](const tvg::Paint* paint, void* data) -> bool + { + auto func = reinterpret_cast*>(data); + if (!(*func)(paint)) return false; + return true; + }; + + set(picture.get(), backward, reinterpret_cast(&func)); + return picture; +} + + +Result Accessor::set(const Picture* picture, function 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; } diff --git a/test/testAccessor.cpp b/test/testAccessor.cpp index 66729c3a..1fecbb35 100644 --- a/test/testAccessor.cpp +++ b/test/testAccessor.cpp @@ -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); }