Mercurial > molko
comparison tests/test-action.c @ 136:30b68089ae70
core: rework actions and a bit of drawables, closes #2492
In the effort of having as less as possible memory allocation in libcore, the
usage of actions and drawable no longer copy the original source parameter to
let user pass a heap allocated variable or a static storage one.
Update predefined drawable and actions to match these new needs.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 13 Oct 2020 09:38:44 +0200 |
parents | |
children | fea0cc899931 |
comparison
equal
deleted
inserted
replaced
135:eadfed7674ac | 136:30b68089ae70 |
---|---|
1 /* | |
2 * test-action.c -- test actions | |
3 * | |
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #define GREATEST_USE_ABBREVS 0 | |
20 #include <greatest.h> | |
21 | |
22 #include <core/action.h> | |
23 #include <core/event.h> | |
24 | |
25 struct invokes { | |
26 bool handle; | |
27 bool update; | |
28 bool draw; | |
29 bool end; | |
30 bool finish; | |
31 }; | |
32 | |
33 static union event dummy; | |
34 | |
35 #define INIT(dat, up) { \ | |
36 .data = (dat), \ | |
37 .handle = my_handle, \ | |
38 .update = (up), \ | |
39 .draw = my_draw, \ | |
40 .end = my_end, \ | |
41 .finish = my_finish \ | |
42 } | |
43 | |
44 static void | |
45 my_handle(struct action *act, const union event *ev) | |
46 { | |
47 (void)ev; | |
48 | |
49 ((struct invokes *)act->data)->handle = true; | |
50 } | |
51 | |
52 static bool | |
53 my_update_false(struct action *act, unsigned int ticks) | |
54 { | |
55 (void)ticks; | |
56 | |
57 ((struct invokes *)act->data)->update = true; | |
58 | |
59 return false; | |
60 } | |
61 | |
62 static bool | |
63 my_update_true(struct action *act, unsigned int ticks) | |
64 { | |
65 (void)ticks; | |
66 | |
67 ((struct invokes *)act->data)->update = true; | |
68 | |
69 return true; | |
70 } | |
71 | |
72 static void | |
73 my_draw(struct action *act) | |
74 { | |
75 ((struct invokes *)act->data)->draw = true; | |
76 } | |
77 | |
78 static void | |
79 my_end(struct action *act) | |
80 { | |
81 ((struct invokes *)act->data)->end = true; | |
82 } | |
83 | |
84 static void | |
85 my_finish(struct action *act) | |
86 { | |
87 ((struct invokes *)act->data)->finish = true; | |
88 } | |
89 | |
90 GREATEST_TEST | |
91 basics_handle(void) | |
92 { | |
93 struct invokes inv = {0}; | |
94 struct action act = INIT(&inv, my_update_true); | |
95 | |
96 action_handle(&act, &dummy); | |
97 | |
98 GREATEST_ASSERT(inv.handle); | |
99 GREATEST_ASSERT(!inv.update); | |
100 GREATEST_ASSERT(!inv.draw); | |
101 GREATEST_ASSERT(!inv.end); | |
102 GREATEST_ASSERT(!inv.finish); | |
103 GREATEST_PASS(); | |
104 } | |
105 | |
106 GREATEST_TEST | |
107 basics_update(void) | |
108 { | |
109 struct { | |
110 struct invokes inv; | |
111 struct action act; | |
112 } table[] = { | |
113 { .act = INIT(&table[0], my_update_true) }, | |
114 { .act = INIT(&table[1], my_update_false) } | |
115 }; | |
116 | |
117 /* True version. */ | |
118 GREATEST_ASSERT(action_update(&table[0].act, 0)); | |
119 GREATEST_ASSERT(!table[0].inv.handle); | |
120 GREATEST_ASSERT(table[0].inv.update); | |
121 GREATEST_ASSERT(!table[0].inv.draw); | |
122 GREATEST_ASSERT(!table[0].inv.end); | |
123 GREATEST_ASSERT(!table[0].inv.finish); | |
124 | |
125 /* False version. */ | |
126 GREATEST_ASSERT(!action_update(&table[1].act, 0)); | |
127 GREATEST_ASSERT(!table[1].inv.handle); | |
128 GREATEST_ASSERT(table[1].inv.update); | |
129 GREATEST_ASSERT(!table[1].inv.draw); | |
130 GREATEST_ASSERT(!table[1].inv.end); | |
131 GREATEST_ASSERT(!table[1].inv.finish); | |
132 | |
133 GREATEST_PASS(); | |
134 } | |
135 | |
136 GREATEST_TEST | |
137 basics_draw(void) | |
138 { | |
139 struct invokes inv; | |
140 struct action act = INIT(&inv, my_update_true); | |
141 | |
142 action_draw(&act); | |
143 | |
144 GREATEST_ASSERT(!inv.handle); | |
145 GREATEST_ASSERT(!inv.update); | |
146 GREATEST_ASSERT(inv.draw); | |
147 GREATEST_ASSERT(!inv.end); | |
148 GREATEST_ASSERT(!inv.finish); | |
149 GREATEST_PASS(); | |
150 } | |
151 | |
152 GREATEST_TEST | |
153 basics_end(void) | |
154 { | |
155 struct invokes inv; | |
156 struct action act = INIT(&inv, my_update_true); | |
157 | |
158 action_end(&act); | |
159 | |
160 GREATEST_ASSERT(!inv.handle); | |
161 GREATEST_ASSERT(!inv.update); | |
162 GREATEST_ASSERT(!inv.draw); | |
163 GREATEST_ASSERT(inv.end); | |
164 GREATEST_ASSERT(!inv.finish); | |
165 GREATEST_PASS(); | |
166 } | |
167 | |
168 GREATEST_TEST | |
169 basics_finish(void) | |
170 { | |
171 struct invokes inv; | |
172 struct action act = INIT(&inv, my_update_true); | |
173 | |
174 action_finish(&act); | |
175 | |
176 GREATEST_ASSERT(!inv.handle); | |
177 GREATEST_ASSERT(!inv.update); | |
178 GREATEST_ASSERT(!inv.draw); | |
179 GREATEST_ASSERT(!inv.end); | |
180 GREATEST_ASSERT(inv.finish); | |
181 GREATEST_PASS(); | |
182 } | |
183 | |
184 GREATEST_SUITE(suite_basics) | |
185 { | |
186 GREATEST_RUN_TEST(basics_handle); | |
187 GREATEST_RUN_TEST(basics_update); | |
188 GREATEST_RUN_TEST(basics_draw); | |
189 GREATEST_RUN_TEST(basics_end); | |
190 GREATEST_RUN_TEST(basics_finish); | |
191 } | |
192 | |
193 GREATEST_TEST | |
194 stack_add(void) | |
195 { | |
196 struct action_stack st = {0}; | |
197 struct action act = {0}; | |
198 | |
199 GREATEST_ASSERT(action_stack_add(&st, &act)); | |
200 | |
201 /* Now fill up. */ | |
202 for (int i = 0; i < ACTION_STACK_MAX - 1; ++i) | |
203 GREATEST_ASSERT(action_stack_add(&st, &act)); | |
204 | |
205 /* This one should not fit in. */ | |
206 GREATEST_ASSERT(!action_stack_add(&st, &act)); | |
207 | |
208 GREATEST_PASS(); | |
209 } | |
210 | |
211 GREATEST_TEST | |
212 stack_handle(void) | |
213 { | |
214 struct { | |
215 bool called; | |
216 struct action act; | |
217 } table[] = { | |
218 { false, { .data = &table[0].called, .handle = my_handle } }, | |
219 { false, { .data = &table[1].called, .handle = my_handle } }, | |
220 { false, { .data = &table[2].called, .handle = my_handle } }, | |
221 }; | |
222 | |
223 struct action_stack st = {0}; | |
224 | |
225 action_stack_add(&st, &table[0].act); | |
226 action_stack_add(&st, &table[1].act); | |
227 action_stack_add(&st, &table[2].act); | |
228 action_stack_handle(&st, &dummy); | |
229 | |
230 GREATEST_ASSERT(table[0].called); | |
231 GREATEST_ASSERT(table[1].called); | |
232 GREATEST_ASSERT(table[2].called); | |
233 GREATEST_PASS(); | |
234 } | |
235 | |
236 GREATEST_TEST | |
237 stack_update(void) | |
238 { | |
239 struct { | |
240 struct invokes inv; | |
241 struct action act; | |
242 } table[] = { | |
243 { .act = INIT(&table[0], my_update_false) }, | |
244 { .act = INIT(&table[1], my_update_true) }, | |
245 { .act = INIT(&table[2], my_update_false) }, | |
246 { .act = INIT(&table[3], my_update_false) }, | |
247 { .act = INIT(&table[4], my_update_true) }, | |
248 { .act = INIT(&table[5], my_update_true) }, | |
249 { .act = INIT(&table[6], my_update_false) }, | |
250 }; | |
251 | |
252 struct action_stack st = {0}; | |
253 | |
254 action_stack_add(&st, &table[0].act); | |
255 action_stack_add(&st, &table[1].act); | |
256 action_stack_add(&st, &table[2].act); | |
257 action_stack_add(&st, &table[3].act); | |
258 action_stack_add(&st, &table[4].act); | |
259 action_stack_add(&st, &table[5].act); | |
260 action_stack_add(&st, &table[6].act); | |
261 | |
262 GREATEST_ASSERT(!action_stack_update(&st, 0)); | |
263 | |
264 GREATEST_ASSERT(!table[0].inv.handle); | |
265 GREATEST_ASSERT(!table[1].inv.handle); | |
266 GREATEST_ASSERT(!table[2].inv.handle); | |
267 GREATEST_ASSERT(!table[3].inv.handle); | |
268 GREATEST_ASSERT(!table[4].inv.handle); | |
269 GREATEST_ASSERT(!table[5].inv.handle); | |
270 GREATEST_ASSERT(!table[6].inv.handle); | |
271 | |
272 GREATEST_ASSERT(table[0].inv.update); | |
273 GREATEST_ASSERT(table[1].inv.update); | |
274 GREATEST_ASSERT(table[2].inv.update); | |
275 GREATEST_ASSERT(table[3].inv.update); | |
276 GREATEST_ASSERT(table[4].inv.update); | |
277 GREATEST_ASSERT(table[5].inv.update); | |
278 GREATEST_ASSERT(table[6].inv.update); | |
279 | |
280 GREATEST_ASSERT(!table[0].inv.draw); | |
281 GREATEST_ASSERT(!table[1].inv.draw); | |
282 GREATEST_ASSERT(!table[2].inv.draw); | |
283 GREATEST_ASSERT(!table[3].inv.draw); | |
284 GREATEST_ASSERT(!table[4].inv.draw); | |
285 GREATEST_ASSERT(!table[5].inv.draw); | |
286 GREATEST_ASSERT(!table[6].inv.draw); | |
287 | |
288 GREATEST_ASSERT(!table[0].inv.end); | |
289 GREATEST_ASSERT(table[1].inv.end); | |
290 GREATEST_ASSERT(!table[2].inv.end); | |
291 GREATEST_ASSERT(!table[3].inv.end); | |
292 GREATEST_ASSERT(table[4].inv.end); | |
293 GREATEST_ASSERT(table[5].inv.end); | |
294 GREATEST_ASSERT(!table[6].inv.end); | |
295 | |
296 GREATEST_ASSERT(!table[0].inv.finish); | |
297 GREATEST_ASSERT(table[1].inv.finish); | |
298 GREATEST_ASSERT(!table[2].inv.finish); | |
299 GREATEST_ASSERT(!table[3].inv.finish); | |
300 GREATEST_ASSERT(table[4].inv.finish); | |
301 GREATEST_ASSERT(table[5].inv.finish); | |
302 GREATEST_ASSERT(!table[6].inv.finish); | |
303 | |
304 /* The following must still be there. */ | |
305 GREATEST_ASSERT_EQ(st.actions[0], &table[0].act); | |
306 GREATEST_ASSERT_EQ(st.actions[2], &table[2].act); | |
307 GREATEST_ASSERT_EQ(st.actions[3], &table[3].act); | |
308 GREATEST_ASSERT_EQ(st.actions[6], &table[6].act); | |
309 | |
310 /* The following must have been NULL-ed. */ | |
311 GREATEST_ASSERT_EQ(st.actions[1], NULL); | |
312 GREATEST_ASSERT_EQ(st.actions[4], NULL); | |
313 GREATEST_ASSERT_EQ(st.actions[5], NULL); | |
314 | |
315 /* | |
316 * Now make all actions to return true and check if it cleans the stack. | |
317 */ | |
318 table[0].act.update = | |
319 table[2].act.update = | |
320 table[3].act.update = | |
321 table[6].act.update = my_update_true; | |
322 | |
323 GREATEST_ASSERT(action_stack_update(&st, 0)); | |
324 GREATEST_ASSERT_EQ(st.actions[0], NULL); | |
325 GREATEST_ASSERT_EQ(st.actions[1], NULL); | |
326 GREATEST_ASSERT_EQ(st.actions[2], NULL); | |
327 GREATEST_ASSERT_EQ(st.actions[3], NULL); | |
328 GREATEST_ASSERT_EQ(st.actions[4], NULL); | |
329 GREATEST_ASSERT_EQ(st.actions[5], NULL); | |
330 GREATEST_ASSERT_EQ(st.actions[6], NULL); | |
331 | |
332 GREATEST_PASS(); | |
333 } | |
334 | |
335 GREATEST_TEST | |
336 stack_finish(void) | |
337 { | |
338 struct { | |
339 struct invokes inv; | |
340 struct action act; | |
341 } table[] = { | |
342 { .act = INIT(&table[0], my_update_true) }, | |
343 { .act = INIT(&table[0], my_update_false) }, | |
344 }; | |
345 struct action_stack st = {0}; | |
346 | |
347 action_stack_add(&st, &table[0].act); | |
348 action_stack_add(&st, &table[1].act); | |
349 action_stack_finish(&st); | |
350 | |
351 GREATEST_ASSERT(!table[0].inv.handle); | |
352 GREATEST_ASSERT(!table[0].inv.update); | |
353 GREATEST_ASSERT(!table[0].inv.draw); | |
354 GREATEST_ASSERT(table[0].inv.end); | |
355 GREATEST_ASSERT(table[0].inv.finish); | |
356 | |
357 GREATEST_ASSERT(!table[0].inv.handle); | |
358 GREATEST_ASSERT(!table[0].inv.update); | |
359 GREATEST_ASSERT(!table[0].inv.draw); | |
360 GREATEST_ASSERT(table[0].inv.end); | |
361 GREATEST_ASSERT(table[0].inv.finish); | |
362 | |
363 /* They should also be NULL'ed. */ | |
364 GREATEST_ASSERT_EQ(st.actions[0], NULL); | |
365 GREATEST_ASSERT_EQ(st.actions[1], NULL); | |
366 | |
367 GREATEST_PASS(); | |
368 } | |
369 | |
370 GREATEST_SUITE(suite_stack) | |
371 { | |
372 GREATEST_RUN_TEST(stack_add); | |
373 GREATEST_RUN_TEST(stack_handle); | |
374 GREATEST_RUN_TEST(stack_update); | |
375 GREATEST_RUN_TEST(stack_finish); | |
376 } | |
377 | |
378 GREATEST_MAIN_DEFS(); | |
379 | |
380 int | |
381 main(int argc, char **argv) | |
382 { | |
383 GREATEST_MAIN_BEGIN(); | |
384 GREATEST_RUN_SUITE(suite_basics); | |
385 GREATEST_RUN_SUITE(suite_stack); | |
386 GREATEST_MAIN_END(); | |
387 | |
388 return 0; | |
389 } |