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. //The callback function from lambda expression.
//This function will be called for every paint nodes of the picture tree. //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) { if (paint->type() == tvg::Type::Shape) {
auto shape = (tvg::Shape*) paint; auto shape = (tvg::Shape*) paint;
@ -58,7 +58,7 @@ struct UserExample : tvgexam::Example
return true; 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)); canvas->push(std::move(picture));

View file

@ -2119,17 +2119,20 @@ class TVG_API Accessor final
public: public:
~Accessor(); ~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. * @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] picture The picture node to traverse the internal scene-tree.
* @param[in] func The callback function calling for every paint nodes of the Picture. * @param[in] func The callback function calling for every paint nodes of the Picture.
* * @param[in] data Data passed to the @p func as its argument.
* @return Return the given @p picture instance.
* *
* @note The bitmap based picture might not have the scene-tree. * @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. * @brief Creates a new Accessor object.

View file

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

View file

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