solstice-anim

Geometry animation library of the solstice app
git clone git://git.meso-star.com/solstice-anim.git
Log | Files | Refs | README | LICENSE

commit 43586db89f5b69a8463a76c54106e3616ff660ef
parent 0cbd04e7dd94dee74ffe7458f0ae4f9ff817699e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 17 Nov 2016 14:08:27 +0100

Add node_search_tree API and test.

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/sanim.h | 10++++++++++
Msrc/sanim_node.c | 26++++++++++++++++++++++++++
Asrc/test_sanim_search.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 126 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -98,6 +98,7 @@ if(NOT NO_TEST) new_test(test_sanim_node) new_test(test_sanim_node_transform) new_test(test_sanim_node_pivot) + new_test(test_sanim_search) new_test(test_sanim_visit) endif() diff --git a/src/sanim.h b/src/sanim.h @@ -178,6 +178,16 @@ sanim_node_visit_tree res_T (*visitor)( const struct sanim_node* n, const double transform[12], void* data)); +/* Visit the (sub)tree starting at node and call cmp on the nodes + * Stop if found is set to non-zero or if a call to cmp return is not RES_OK */ +SANIM_API res_T +sanim_node_search_tree + (const struct sanim_node* node, + void* data, + res_T(*cmp)( + const struct sanim_node* n, void* data, int* found), + int* found); + SANIM_API res_T sanim_node_track_me (const struct sanim_node* node, diff --git a/src/sanim_node.c b/src/sanim_node.c @@ -1055,6 +1055,32 @@ sanim_node_visit_tree } res_T +sanim_node_search_tree + (const struct sanim_node* node, + void* data, + res_T(*cmp)( + const struct sanim_node* n, void* data, int* found), + int* found) +{ + size_t count, i; + struct sanim_node* const* children; + res_T res = RES_OK; + if (!node || !node->data || !cmp || !found) return RES_BAD_ARG; + + res = cmp(node, data, found); + if (*found || res != RES_OK) return res; + + count = darray_children_size_get(&node->data->children); + children = darray_children_data_get(&node->data->children); + for (i = 0; i < count; i++) { + struct sanim_node* child = children[i]; + res = sanim_node_search_tree(child, data, cmp, found); + if (*found || res != RES_OK) return res; + } + return RES_OK; +} + +res_T sanim_node_track_me (const struct sanim_node* node, struct sanim_tracking* tracking) diff --git a/src/test_sanim_search.c b/src/test_sanim_search.c @@ -0,0 +1,89 @@ + +/* Copyright (C) CNRS 2016 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "sanim.h" +#include "test_sanim_utils.h" + +#include <rsys/double33.h> + +struct data { + struct my_type * result; +}; + +static res_T +search(const struct sanim_node* n, void* data_, int* found) +{ + int pivot; + ASSERT(n && found); + if (!data_) return RES_BAD_ARG; + SANIM(node_is_pivot(n, &pivot)); + if (pivot) { + struct my_type* node; + struct data* data = data_; + node = CONTAINER_OF(n, struct my_type, node); + data->result = node; + *found = 1; + } + return RES_OK; +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct my_type *t1, *t2, *t3; + struct sanim_pivot pivot = SANIM_PIVOT_NULL; + struct sanim_tracking tracking = SANIM_TRACKING_NULL; + struct data data; + int found = 0; + (void) argc, (void) argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + + tracking.policy = TRACKING_SUN; + pivot.type = PIVOT_SINGLE_AXIS; + d3(pivot.data.pivot1.ref_normal, 0, 0, 1); + + /* ref_normal not in the YZ plane */ + CHECK(my_type_create(&allocator, &t1), RES_OK); + CHECK(my_type_pivot_create(&allocator, &pivot, &tracking, &t2), RES_OK); + CHECK(my_type_create(&allocator, &t3), RES_OK); + + CHECK(my_type_add_child(t1, t2), RES_OK); + CHECK(my_type_add_child(t2, t3), RES_OK); + + data.result = NULL; + + CHECK(sanim_node_search_tree(NULL, &data, search, &found), RES_BAD_ARG); + CHECK(sanim_node_search_tree(&t1->node, NULL, search, &found), RES_BAD_ARG); + CHECK(sanim_node_search_tree(&t1->node, &data, NULL, &found), RES_BAD_ARG); + CHECK(sanim_node_search_tree(&t1->node, &data, search, NULL), RES_BAD_ARG); + CHECK(sanim_node_search_tree(&t1->node, &data, search, &found), RES_OK); + CHECK(data.result, t2); + + data.result = NULL; + CHECK(sanim_node_search_tree(&t3->node, &data, search, &found), RES_OK); + CHECK(data.result, NULL); + + /* release memory */ + CHECK(my_type_ref_put(t1), RES_OK); + CHECK(my_type_ref_put(t2), RES_OK); + CHECK(my_type_ref_put(t3), RES_OK); + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + return 0; +}