EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / tests / eina_test_quadtree.c
1 /* EINA - EFL data type library
2  * Copyright (C) 2010 Cedric Bail
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include <assert.h>
24 #include <stdio.h>
25
26 #include "eina_suite.h"
27 #include "Eina.h"
28
29 static Eina_Quad_Direction
30 _eina_quadtree_rectangle_vert(const void *object, size_t middle)
31 {
32    const Eina_Rectangle *r = object;
33
34    if (r->y + r->h < (int)middle)
35       return EINA_QUAD_LEFT;
36
37    if (r->y > (int)middle)
38       return EINA_QUAD_RIGHT;
39
40    return EINA_QUAD_BOTH;
41 }
42
43 static Eina_Quad_Direction
44 _eina_quadtree_rectangle_hort(const void *object, size_t middle)
45 {
46    const Eina_Rectangle *r = object;
47
48    if (r->x + r->w < (int)middle)
49       return EINA_QUAD_LEFT;
50
51    if (r->x > (int)middle)
52       return EINA_QUAD_RIGHT;
53
54    return EINA_QUAD_BOTH;
55 }
56
57 START_TEST(eina_quadtree_collision)
58 {
59    struct
60    {
61       Eina_Rectangle r;
62       Eina_QuadTree_Item *item;
63    } objects[] = {
64       { { 10, 10, 30, 30 }, NULL },
65       { { 20, 20, 30, 30 }, NULL },
66       { { 5, 30, 30, 30 }, NULL },
67       { { 70, 130, 100, 100 }, NULL },
68       { { 10, 220, 50, 40 }, NULL },
69       { { 310, 20, 50, 30 }, NULL },
70       { { 300, 220, 40, 40 }, NULL },
71       { { 500, 150, 40, 40 }, NULL },
72       { { 500, 220, 40, 40 }, NULL },
73       { { 330, 250, 40, 40 }, NULL },
74       { { 300, 400, 40, 40 }, NULL },
75       { { 10, 400, 40, 40 }, NULL },
76       { { 0, 0, 0, 0 }, NULL }
77    };
78    struct
79    {
80       Eina_Rectangle r;
81       int count;
82       int result[20];
83    } tests [] = {
84       { { 600, 400, 40, 40 }, 4, { 4, 6, 8, 10 } },
85       { { 20, 30, 10, 10 }, 7, { 0, 1, 2, 4, 5, 6, 8 } },
86       { { 0, 0, 0, 0 }, -1, {} },
87    };
88    int hidden[] = { 4, 5, 6, 8, 10 };
89    int show[] = { 0, 1, 2 };
90    Eina_QuadTree *q;
91    Eina_Inlist *head;
92    Eina_Rectangle *r;
93    int count;
94    int i;
95
96         fail_if(!eina_init());
97
98    q = eina_quadtree_new(640, 480,
99                          _eina_quadtree_rectangle_vert,
100                          _eina_quadtree_rectangle_hort);
101
102         fail_if(!q);
103
104    for (i = 0; objects[i].r.w != 0 && objects[i].r.h != 0; ++i)
105      {
106         objects[i].item = eina_quadtree_add(q, &objects[i].r);
107         fail_if(!objects[i].item);
108         fail_if(!eina_quadtree_show(objects[i].item));
109      }
110
111         eina_quadtree_resize(q, 640, 480);
112
113    for (i = 0; tests[i].count != -1; ++i)
114      {
115         head = eina_quadtree_collide(q,
116                                      tests[i].r.x, tests[i].r.y,
117                                      tests[i].r.w, tests[i].r.h);
118
119         count = 0;
120         while (head)
121           {
122              int k;
123
124              r = eina_quadtree_object(head);
125
126              for (k = 0; k < tests[i].count; ++k)
127                {
128                   if (&objects[tests[i].result[k]].r == r)
129                      break;
130                }
131              fail_if(k == tests[i].count);
132
133              head = head->next;
134              count++;
135           }
136              fail_if(count != tests[i].count);
137      }
138
139    for (i = 0; i < (int)(sizeof (hidden) / sizeof (int)); ++i)
140       eina_quadtree_hide(objects[hidden[i]].item);
141    for (i = 0; i < (int)(sizeof (show) / sizeof (int)); ++i)
142       eina_quadtree_show(objects[show[i]].item);
143
144    head = eina_quadtree_collide(q,
145                                 tests[1].r.x, tests[1].r.y,
146                                 tests[1].r.w, tests[1].r.h);
147
148    count = 0;
149    while (head)
150      {
151         r = eina_quadtree_object(head);
152
153         fail_if(r != &objects[tests[1].result[show[count]]].r);
154
155         head = head->next;
156         count++;
157      }
158         fail_if(count != 3);
159
160         eina_quadtree_cycle(q);
161    eina_quadtree_show(objects[4].item);
162    eina_quadtree_increase(objects[4].item);
163    eina_quadtree_show(objects[5].item);
164    eina_quadtree_increase(objects[5].item);
165    eina_quadtree_del(objects[5].item);
166    eina_quadtree_change(objects[10].item);
167    eina_quadtree_increase(objects[10].item);
168
169    eina_quadtree_resize(q, 641, 480);
170
171    head = eina_quadtree_collide(q,
172                                 tests[0].r.x, tests[0].r.y,
173                                 tests[0].r.w, tests[0].r.h);
174
175    count = 0;
176    while (head)
177      {
178         r = eina_quadtree_object(head);
179
180         head = head->next;
181         count++;
182      }
183    fail_if(count != 1);
184
185    eina_quadtree_free(q);
186
187    eina_shutdown();
188 }
189 END_TEST
190
191 void
192 eina_test_quadtree(TCase *tc)
193 {
194    tcase_add_test(tc, eina_quadtree_collision);
195 }