comparison src/redraw_man.c @ 159:b90abd31a281

Postponse free of coords, shapes, and paints when the rdman is dirty. - Life-cycle of shapes and paints are managed by rdman. - Add redraw_man_t::free_objs to collect objects their freeing are postonsed. Know Issue: - Bullet of tank are not removed from screen when it is go out the range of the map.
author Thinker K.F. Li <thinker@branda.to>
date Sun, 05 Oct 2008 23:32:58 +0800
parents c1cdd3fcd28f
children 147c93163ef0
comparison
equal deleted inserted replaced
158:c1cdd3fcd28f 159:b90abd31a281
72 STAILQ_INS_TAIL((coord)->members, geo_t, coord_next, (member)) 72 STAILQ_INS_TAIL((coord)->members, geo_t, coord_next, (member))
73 #define RM_MEMBER(coord, member) \ 73 #define RM_MEMBER(coord, member) \
74 STAILQ_REMOVE((coord)->members, geo_t, coord_next, (member)) 74 STAILQ_REMOVE((coord)->members, geo_t, coord_next, (member))
75 #define FIRST_MEMBER(coord) STAILQ_HEAD((coord)->members) 75 #define FIRST_MEMBER(coord) STAILQ_HEAD((coord)->members)
76 76
77 /* Functions for paint members. */
78 #define FORPAINTMEMBERS(paint, member) \
79 for((member) = STAILQ_HEAD((paint)->members); \
80 (member) != NULL; \
81 (member) = STAILQ_NEXT(paint_t, next, member))
82 #define RM_PAINTMEMBER(paint, member) \
83 STAILQ_REMOVE((paint)->members, shnode_t, next, member)
84 #define RM_PAINT(rdman, paint) \
85 STAILQ_REMOVE((rdman)->paints, paint_t, pnt_next, paint)
86
77 /*! \brief Sort a list of element by a unsigned integer. 87 /*! \brief Sort a list of element by a unsigned integer.
78 * 88 *
79 * The result is in ascend order. The unsigned integers is 89 * The result is in ascend order. The unsigned integers is
80 * at offset specified by 'off' from start address of elemnts. 90 * at offset specified by 'off' from start address of elemnts.
81 */ 91 */
120 130
121 static int add_dirty_area(redraw_man_t *rdman, area_t *area) { 131 static int add_dirty_area(redraw_man_t *rdman, area_t *area) {
122 ADD_DATA(areas, dirty_areas, area); 132 ADD_DATA(areas, dirty_areas, area);
123 } 133 }
124 134
125 static int add_free_coord(redraw_man_t *rdman, coord_t *coord) { 135 static int add_free_obj(redraw_man_t *rdman, void *obj,
126 ADD_DATA(coords, free_coords, coord); 136 free_func_t free_func) {
127 } 137 int max;
128 138 free_obj_t *new_objs, *free_obj;
129 static int add_free_geo(redraw_man_t *rdman, geo_t *geo) { 139
130 ADD_DATA(geos, free_geos, geo); 140 if(rdman->free_objs.num >= rdman->free_objs.max) {
141 max = rdman->free_objs.num + ARRAY_EXT_SZ;
142 new_objs = realloc(rdman->free_objs.objs,
143 max * sizeof(free_obj_t));
144 if(new_objs == NULL)
145 return ERR;
146 rdman->free_objs.max = max;
147 rdman->free_objs.objs = new_objs;
148 }
149
150 free_obj = rdman->free_objs.objs + rdman->free_objs.num++;
151 free_obj->obj = obj;
152 free_obj->free_func = free_func;
153
154 return OK;
155 }
156
157 static void free_free_objs(redraw_man_t *rdman) {
158 int i;
159 free_obj_t *free_obj;
160
161 for(i = 0; i < rdman->free_objs.num; i++) {
162 free_obj = &rdman->free_objs.objs[i];
163 free_obj->free_func(rdman, free_obj->obj);
164 }
165 rdman->free_objs.num = 0;
166 }
167
168 static void free_objs_destroy(redraw_man_t *rdman) {
169 if(rdman->free_objs.objs != NULL)
170 free(rdman->free_objs.objs);
131 } 171 }
132 172
133 static void area_to_positions(area_t *area, co_aix (*poses)[2]) { 173 static void area_to_positions(area_t *area, co_aix (*poses)[2]) {
134 poses[0][0] = area->x; 174 poses[0][0] = area->x;
135 poses[0][1] = area->y; 175 poses[0][1] = area->y;
267 rdman->root_coord->opacity = 1; 307 rdman->root_coord->opacity = 1;
268 308
269 rdman->cr = cr; 309 rdman->cr = cr;
270 rdman->backend = backend; 310 rdman->backend = backend;
271 311
312 STAILQ_INIT(rdman->shapes);
313 STAILQ_INIT(rdman->paints);
314
272 return OK; 315 return OK;
273 } 316 }
274 317
275 void redraw_man_destroy(redraw_man_t *rdman) { 318 void redraw_man_destroy(redraw_man_t *rdman) {
276 coord_t *coord, *saved_coord; 319 coord_t *coord, *saved_coord;
320 shape_t *shape, *saved_shape;
277 geo_t *member; 321 geo_t *member;
322
323 free_free_objs(rdman);
324 free_objs_destroy(rdman);
278 325
279 coord = postorder_coord_subtree(rdman->root_coord, NULL); 326 coord = postorder_coord_subtree(rdman->root_coord, NULL);
280 while(coord) { 327 while(coord) {
281 saved_coord = coord; 328 saved_coord = coord;
282 coord = postorder_coord_subtree(rdman->root_coord, coord); 329 coord = postorder_coord_subtree(rdman->root_coord, coord);
283 FORMEMBERS(saved_coord, member) { 330 FORMEMBERS(saved_coord, member) {
284 rdman_remove_shape(rdman, member->shape); 331 rdman_shape_free(rdman, member->shape);
285 } 332 }
286 rdman_coord_free(rdman, saved_coord); 333 rdman_coord_free(rdman, saved_coord);
287 } 334 }
288 FORMEMBERS(saved_coord, member) { 335 FORMEMBERS(saved_coord, member) {
289 rdman_remove_shape(rdman, member->shape); 336 rdman_shape_free(rdman, member->shape);
290 } 337 }
291 /* Resources of root_coord is free by elmpool_free() or 338 /* Resources of root_coord is free by elmpool_free() or
292 * caller; for canvas 339 * caller; for canvas
293 */ 340 */
341
342 shape = saved_shape = STAILQ_HEAD(rdman->shapes);
343 while(shape && (shape = STAILQ_NEXT(shape_t, sh_next, shape))) {
344 rdman_shape_free(rdman, saved_shape);
345 #if 0
346 STAILQ_REMOVE(rdman->shapes, shape_t, sh_next, saved_shape);
347 #endif
348 saved_shape = shape;
349 }
350 if(saved_shape != NULL)
351 rdman_shape_free(rdman, saved_shape);
294 352
295 elmpool_free(rdman->coord_pool); 353 elmpool_free(rdman->coord_pool);
296 elmpool_free(rdman->geo_pool); 354 elmpool_free(rdman->geo_pool);
297 elmpool_free(rdman->shnode_pool); 355 elmpool_free(rdman->shnode_pool);
298 elmpool_free(rdman->observer_pool); 356 elmpool_free(rdman->observer_pool);
301 359
302 DARRAY_DESTROY(&rdman->dirty_coords); 360 DARRAY_DESTROY(&rdman->dirty_coords);
303 DARRAY_DESTROY(&rdman->dirty_geos); 361 DARRAY_DESTROY(&rdman->dirty_geos);
304 DARRAY_DESTROY(&rdman->dirty_areas); 362 DARRAY_DESTROY(&rdman->dirty_areas);
305 DARRAY_DESTROY(&rdman->gen_geos); 363 DARRAY_DESTROY(&rdman->gen_geos);
306 DARRAY_DESTROY(&rdman->free_coords);
307 DARRAY_DESTROY(&rdman->free_geos);
308 } 364 }
309 365
310 366
311 #define ASSERT(x) 367 #define ASSERT(x)
312 /* 368 /*
360 * \note Shapes should be removed after redrawing or when rdman is in clean. 416 * \note Shapes should be removed after redrawing or when rdman is in clean.
361 * \note Removing shapes or coords when a rdman is dirty, removing 417 * \note Removing shapes or coords when a rdman is dirty, removing
362 * is postponsed. 418 * is postponsed.
363 * \todo redraw shape objects that overlaid with removed one. 419 * \todo redraw shape objects that overlaid with removed one.
364 */ 420 */
365 int rdman_remove_shape(redraw_man_t *rdman, shape_t *shape) { 421 int rdman_shape_free(redraw_man_t *rdman, shape_t *shape) {
366 geo_t *geo; 422 geo_t *geo;
367 coord_t *coord;
368 int r; 423 int r;
369 424
370 geo = shape->geo; 425 geo = shape->geo;
371 coord = shape->coord; 426
372 427 if(rdman_is_dirty(rdman) && geo != NULL) {
373 if(rdman_is_dirty(rdman)) { 428 if(geo->flags & GEF_FREE)
429 return ERR;
430
374 geo->flags |= GEF_FREE | GEF_HIDDEN; 431 geo->flags |= GEF_FREE | GEF_HIDDEN;
375 if(!(geo->flags & GEF_DIRTY)) { 432 if(!(geo->flags & GEF_DIRTY)) {
376 r = add_dirty_geo(rdman, geo); 433 r = add_dirty_geo(rdman, geo);
377 if(r != OK) 434 if(r != OK)
378 return ERR; 435 return ERR;
379 } 436 }
380 r = add_free_geo(rdman, geo); 437 r = add_free_obj(rdman, shape, (free_func_t)rdman_shape_free);
381 if(r != OK) 438 if(r != OK)
382 return ERR; 439 return ERR;
383 return OK; 440 return OK;
384 } 441 }
385 442
386 geo_detach_coord(geo, coord); 443 if(geo != NULL) {
387 subject_free(&rdman->ob_factory, geo->mouse_event); 444 geo_detach_coord(geo, shape->coord);
388 sh_detach_geo(shape); 445 sh_detach_coord(shape);
389 elmpool_elm_free(rdman->geo_pool, geo); 446 sh_detach_geo(shape);
390 sh_detach_coord(shape); 447 subject_free(&rdman->ob_factory, geo->mouse_event);
448 elmpool_elm_free(rdman->geo_pool, geo);
449 }
450 STAILQ_REMOVE(rdman->shapes, shape_t, sh_next, shape);
451 shape->free(shape);
391 return OK; 452 return OK;
453 }
454
455 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) {
456 shnode_t *node;
457
458 node = (shnode_t *)elmpool_elm_alloc(rdman->shnode_pool);
459 if(node) {
460 node->shape = shape;
461 node->next = NULL;
462 }
463 return node;
464 }
465
466 int rdman_paint_free(redraw_man_t *rdman, paint_t *paint) {
467 shnode_t *shnode, *saved_shnode;
468
469 if(rdman_is_dirty(rdman)) {
470 if(!(paint->flags & PNTF_FREE))
471 return ERR;
472 add_free_obj(rdman, paint, (free_func_t)rdman_paint_free);
473 paint->flags |= PNTF_FREE;
474 return OK;
475 }
476
477 /* Free member shapes that using this paint. */
478 saved_shnode = NULL;
479 FORPAINTMEMBERS(paint, shnode) {
480 if(saved_shnode) {
481 RM_PAINTMEMBER(paint, saved_shnode);
482 shnode_free(rdman, saved_shnode);
483 }
484 saved_shnode = shnode;
485 }
486 if(saved_shnode) {
487 RM_PAINTMEMBER(paint, saved_shnode);
488 shnode_free(rdman, saved_shnode);
489 }
490
491 RM_PAINT(rdman, paint);
492 paint->free(rdman, paint);
493 return OK;
494 }
495
496 void _rdman_paint_real_remove_child(redraw_man_t *rdman,
497 paint_t *paint,
498 shape_t *shape) {
499 shnode_t *shnode;
500
501 FORPAINTMEMBERS(paint, shnode) {
502 if(shnode->shape == shape) {
503 RM_PAINTMEMBER(paint, shnode);
504 shnode_free(rdman, shnode);
505 break;
506 }
507 }
392 } 508 }
393 509
394 coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent) { 510 coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent) {
395 coord_t *coord, *root_coord; 511 coord_t *coord, *root_coord;
396 coord_t *visit; 512 coord_t *visit;
446 parent = coord->parent; 562 parent = coord->parent;
447 if(parent == NULL) 563 if(parent == NULL)
448 return ERR; 564 return ERR;
449 565
450 if(rdman_is_dirty(rdman)) { 566 if(rdman_is_dirty(rdman)) {
567 if(coord->flags & COF_FREE)
568 return ERR;
569
451 FORCHILDREN(coord, child) { 570 FORCHILDREN(coord, child) {
452 if(!(child->flags & COF_FREE)) 571 if(!(child->flags & COF_FREE))
453 return ERR; 572 return ERR;
454 } 573 }
455 FORMEMBERS(coord, member) { 574 FORMEMBERS(coord, member) {
460 if(!(coord->flags & COF_DIRTY)) { 579 if(!(coord->flags & COF_DIRTY)) {
461 r = add_dirty_coord(rdman, coord); 580 r = add_dirty_coord(rdman, coord);
462 if(r != OK) 581 if(r != OK)
463 return ERR; 582 return ERR;
464 } 583 }
465 r = add_free_coord(rdman, coord); 584 r = add_free_obj(rdman, coord, (free_func_t)rdman_coord_free);
466 if(r != OK) 585 if(r != OK)
467 return ERR; 586 return ERR;
468 return OK; 587 return OK;
469 } 588 }
470 589
471 if(FIRST_MEMBER(coord) != NULL) 590 if(FIRST_MEMBER(coord) != NULL)
472 return ERR; 591 return ERR;
473 592
474 if(FIRST_CHILD(coord) != NULL) 593 if(FIRST_CHILD(coord) != NULL)
475 return ERR;
476
477 if(coord->flags & COF_FREE)
478 return ERR; 594 return ERR;
479 595
480 /* Free canvas (\ref redraw) */ 596 /* Free canvas (\ref redraw) */
481 if(coord->flags & COF_OWN_CANVAS) 597 if(coord->flags & COF_OWN_CANVAS)
482 free_canvas(coord->canvas); 598 free_canvas(coord->canvas);
498 614
499 prev_coord = postorder_coord_subtree(subtree, NULL); 615 prev_coord = postorder_coord_subtree(subtree, NULL);
500 for(coord = postorder_coord_subtree(subtree, prev_coord); 616 for(coord = postorder_coord_subtree(subtree, prev_coord);
501 coord != NULL; 617 coord != NULL;
502 coord = postorder_coord_subtree(subtree, coord)) { 618 coord = postorder_coord_subtree(subtree, coord)) {
619 if(!(prev_coord->flags & COF_FREE)) {
620 r = rdman_coord_free(rdman, prev_coord);
621 if(r != OK)
622 return ERR;
623 }
624 prev_coord = coord;
625 }
626 if(!(prev_coord->flags & COF_FREE)) {
503 r = rdman_coord_free(rdman, prev_coord); 627 r = rdman_coord_free(rdman, prev_coord);
504 if(r != OK) 628 if(r != OK)
505 return ERR; 629 return ERR;
506 prev_coord = coord; 630 }
507 }
508 r = rdman_coord_free(rdman, prev_coord);
509 if(r != OK)
510 return ERR;
511 631
512 return OK; 632 return OK;
513 } 633 }
514 634
515 /*! \brief Mark a coord is changed. 635 /*! \brief Mark a coord is changed.
564 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { 684 int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) {
565 return _rdman_shape_changed(rdman, shape); 685 return _rdman_shape_changed(rdman, shape);
566 } 686 }
567 687
568 int rdman_paint_changed(redraw_man_t *rdman, paint_t *paint) { 688 int rdman_paint_changed(redraw_man_t *rdman, paint_t *paint) {
569 shnode_t *node; 689 shnode_t *shnode;
570 int r; 690 int r;
571 691
572 for(node = STAILQ_HEAD(paint->members); 692 FORPAINTMEMBERS(paint, shnode) {
573 node != NULL; 693 r = _rdman_shape_changed(rdman, shnode->shape);
574 node = STAILQ_NEXT(shnode_t, next, node)) {
575 r = _rdman_shape_changed(rdman, node->shape);
576 if(r != OK) 694 if(r != OK)
577 return ERR; 695 return ERR;
578 } 696 }
579 return OK; 697 return OK;
580 } 698 }
984 int n_dirty_areas; 1102 int n_dirty_areas;
985 area_t **dirty_areas; 1103 area_t **dirty_areas;
986 event_t event; 1104 event_t event;
987 ob_factory_t *factory; 1105 ob_factory_t *factory;
988 subject_t *redraw; 1106 subject_t *redraw;
989 geo_t *geo;
990 coord_t *coord;
991 int i;
992 1107
993 r = clean_rdman_dirties(rdman); 1108 r = clean_rdman_dirties(rdman);
994 if(r != OK) 1109 if(r != OK)
995 return ERR; 1110 return ERR;
996 1111
1008 reset_clip(rdman); 1123 reset_clip(rdman);
1009 } 1124 }
1010 rdman->dirty_areas.num = 0; 1125 rdman->dirty_areas.num = 0;
1011 1126
1012 /* Free postponsed removing */ 1127 /* Free postponsed removing */
1013 for(i = 0; i < rdman->free_geos.num; i++) { 1128 free_free_objs(rdman);
1014 geo = rdman->free_geos.ds[i];
1015 rdman_remove_shape(rdman, geo->shape);
1016 }
1017 DARRAY_CLEAN(&rdman->free_geos);
1018
1019 for(i = 0; i < rdman->free_coords.num; i++) {
1020 coord = rdman->free_coords.ds[i];
1021 rdman_remove_shape(rdman, coord);
1022 }
1023 DARRAY_CLEAN(&rdman->free_coords);
1024 1129
1025 factory = rdman_get_ob_factory(rdman); 1130 factory = rdman_get_ob_factory(rdman);
1026 redraw = rdman_get_redraw_subject(rdman); 1131 redraw = rdman_get_redraw_subject(rdman);
1027 event.type = EVT_RDMAN_REDRAW; 1132 event.type = EVT_RDMAN_REDRAW;
1028 event.tgt = event.cur_tgt = redraw; 1133 event.tgt = event.cur_tgt = redraw;
1056 * - rdman_redraw_changed() 1161 * - rdman_redraw_changed()
1057 * - draw_shapes_in_areas() 1162 * - draw_shapes_in_areas()
1058 */ 1163 */
1059 1164
1060 int rdman_redraw_all(redraw_man_t *rdman) { 1165 int rdman_redraw_all(redraw_man_t *rdman) {
1166 area_t area;
1167 #ifndef UNITTEST
1061 cairo_surface_t *surface; 1168 cairo_surface_t *surface;
1062 area_t area; 1169 #endif
1063 int r; 1170 int r;
1064 1171
1065 area.x = area.y = 0; 1172 area.x = area.y = 0;
1066 #ifndef UNITTEST 1173 #ifndef UNITTEST
1067 surface = cairo_get_target(rdman->cr); 1174 surface = cairo_get_target(rdman->cr);
1124 int r; 1231 int r;
1125 1232
1126 r = clean_rdman_dirties(rdman); 1233 r = clean_rdman_dirties(rdman);
1127 1234
1128 return r; 1235 return r;
1129 }
1130
1131 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) {
1132 shnode_t *node;
1133
1134 node = (shnode_t *)elmpool_elm_alloc(rdman->shnode_pool);
1135 if(node) {
1136 node->shape = shape;
1137 node->next = NULL;
1138 }
1139 return node;
1140 } 1236 }
1141 1237
1142 /*! \page dirty Dirty geo, coord, and area. 1238 /*! \page dirty Dirty geo, coord, and area.
1143 * 1239 *
1144 * \section dirty_of_ego Dirty of geo 1240 * \section dirty_of_ego Dirty of geo
1172 * 1268 *
1173 * Clean coords should be performed before clean geos, since clean 1269 * Clean coords should be performed before clean geos, since clean
1174 * coords will also clean member geos. 1270 * coords will also clean member geos.
1175 */ 1271 */
1176 1272
1273 /*! \page man_obj Manage Objects.
1274 *
1275 * Shapes and paints should also be managed by redraw manager. Redraw
1276 * manager must know life-cycle of shapes and paints to avoid to use them
1277 * after being free. If a shape is released when it is dirty, redraw
1278 * manager will try to access them, after released, for redrawing.
1279 * We can make a copy information need by redraw manager to redraw them,
1280 * but it is more complicate, and induce runtime overhead.
1281 *
1282 * So, redraw manage had better also manage life-cycle of shapes and paints.
1283 * Shapes and paints should be created and freed through interfaces
1284 * provided by redraw manager. To reduce overhead of interfaces, they can
1285 * be implemented as C macros.
1286 *
1287 * To refactory redraw manage to manage life-cycle of shapes and paints,
1288 * following functions/macros are introduced.
1289 * - rdman_paint_*_new()
1290 * - rdman_paint_free()
1291 * - rdman_shape_*_new()
1292 * - rdman_shape_free()
1293 */
1294
1177 /* 1295 /*
1178 * When redraw an area, the affected elements may also extend to 1296 * When redraw an area, the affected elements may also extend to
1179 * outside of the area. Since the order of drawing will change 1297 * outside of the area. Since the order of drawing will change
1180 * the result, it will infect more and more elements to keep 1298 * the result, it will infect more and more elements to keep
1181 * drawing order althrough they are overlaid directly with 1299 * drawing order althrough they are overlaid directly with
1282 co_aix w, h; 1400 co_aix w, h;
1283 int trans_cnt; 1401 int trans_cnt;
1284 int draw_cnt; 1402 int draw_cnt;
1285 }; 1403 };
1286 1404
1287 shape_t *sh_dummy_new(co_aix x, co_aix y, co_aix w, co_aix h) { 1405 void sh_dummy_free(shape_t *sh) {
1406 free(sh);
1407 }
1408
1409 shape_t *sh_dummy_new(redraw_man_t *rdman,
1410 co_aix x, co_aix y, co_aix w, co_aix h) {
1288 sh_dummy_t *dummy; 1411 sh_dummy_t *dummy;
1289 1412
1290 dummy = (sh_dummy_t *)malloc(sizeof(sh_dummy_t)); 1413 dummy = (sh_dummy_t *)malloc(sizeof(sh_dummy_t));
1291 if(dummy == NULL) 1414 if(dummy == NULL)
1292 return NULL; 1415 return NULL;
1297 dummy->y = y; 1420 dummy->y = y;
1298 dummy->w = w; 1421 dummy->w = w;
1299 dummy->h = h; 1422 dummy->h = h;
1300 dummy->trans_cnt = 0; 1423 dummy->trans_cnt = 0;
1301 dummy->draw_cnt = 0; 1424 dummy->draw_cnt = 0;
1425 dummy->shape.free = sh_dummy_free;
1426
1427 rdman_shape_man(rdman, (shape_t *)dummy);
1302 1428
1303 return (shape_t *)dummy; 1429 return (shape_t *)dummy;
1304 }
1305
1306 void sh_dummy_free(shape_t *sh) {
1307 free(sh);
1308 } 1430 }
1309 1431
1310 void sh_dummy_transform(shape_t *shape) { 1432 void sh_dummy_transform(shape_t *shape) {
1311 sh_dummy_t *dummy = (sh_dummy_t *)shape; 1433 sh_dummy_t *dummy = (sh_dummy_t *)shape;
1312 co_aix poses[2][2]; 1434 co_aix poses[2][2];
1339 } 1461 }
1340 1462
1341 static void dummy_paint_prepare(paint_t *paint, cairo_t *cr) { 1463 static void dummy_paint_prepare(paint_t *paint, cairo_t *cr) {
1342 } 1464 }
1343 1465
1344 static void dummy_paint_free(paint_t *paint) { 1466 static void dummy_paint_free(redraw_man_t *rdman, paint_t *paint) {
1345 if(paint) 1467 if(paint)
1346 free(paint); 1468 free(paint);
1347 } 1469 }
1348 1470
1349 paint_t *dummy_paint_new(redraw_man_t *rdman) { 1471 paint_t *dummy_paint_new(redraw_man_t *rdman) {
1356 paint_init(paint, dummy_paint_prepare, dummy_paint_free); 1478 paint_init(paint, dummy_paint_prepare, dummy_paint_free);
1357 1479
1358 return paint; 1480 return paint;
1359 } 1481 }
1360 1482
1361 void test_rdman_redraw_changed(void) { 1483 static void test_rdman_redraw_changed(void) {
1362 coord_t *coords[3]; 1484 coord_t *coords[3];
1363 shape_t *shapes[3]; 1485 shape_t *shapes[3];
1364 sh_dummy_t **dummys; 1486 sh_dummy_t **dummys;
1365 paint_t *paint; 1487 paint_t *paint;
1366 redraw_man_t *rdman; 1488 redraw_man_t *rdman;
1371 1493
1372 rdman = &_rdman; 1494 rdman = &_rdman;
1373 redraw_man_init(rdman, NULL, NULL); 1495 redraw_man_init(rdman, NULL, NULL);
1374 paint = dummy_paint_new(rdman); 1496 paint = dummy_paint_new(rdman);
1375 for(i = 0; i < 3; i++) { 1497 for(i = 0; i < 3; i++) {
1376 shapes[i] = sh_dummy_new(0, 0, 50, 50); 1498 shapes[i] = sh_dummy_new(rdman, 0, 0, 50, 50);
1377 rdman_paint_fill(rdman, paint, shapes[i]); 1499 rdman_paint_fill(rdman, paint, shapes[i]);
1378 coords[i] = rdman_coord_new(rdman, rdman->root_coord); 1500 coords[i] = rdman_coord_new(rdman, rdman->root_coord);
1379 coords[i]->matrix[2] = 10 + i * 100; 1501 coords[i]->matrix[2] = 10 + i * 100;
1380 coords[i]->matrix[5] = 10 + i * 100; 1502 coords[i]->matrix[5] = 10 + i * 100;
1381 rdman_coord_changed(rdman, coords[i]); 1503 rdman_coord_changed(rdman, coords[i]);
1397 1519
1398 CU_ASSERT(dummys[0]->draw_cnt == 2); 1520 CU_ASSERT(dummys[0]->draw_cnt == 2);
1399 CU_ASSERT(dummys[1]->draw_cnt == 2); 1521 CU_ASSERT(dummys[1]->draw_cnt == 2);
1400 CU_ASSERT(dummys[2]->draw_cnt == 2); 1522 CU_ASSERT(dummys[2]->draw_cnt == 2);
1401 1523
1402 paint->free(paint); 1524 rdman_paint_free(rdman, paint);
1403 redraw_man_destroy(rdman); 1525 redraw_man_destroy(rdman);
1526 }
1527
1528 static int test_free_pass = 0;
1529
1530 static void test_free(redraw_man_t *rdman, void *obj) {
1531 test_free_pass++;
1532 }
1533
1534 static void test_rdman_free_objs(void) {
1535 redraw_man_t *rdman;
1536 redraw_man_t _rdman;
1537 int i;
1538
1539 redraw_man_init(&_rdman, NULL, NULL);
1540 rdman = &_rdman;
1541
1542 test_free_pass = 0;
1543
1544 for(i = 0; i < 4; i++)
1545 add_free_obj(rdman, NULL, test_free);
1546
1547 redraw_man_destroy(rdman);
1548 CU_ASSERT(test_free_pass == 4);
1404 } 1549 }
1405 1550
1406 CU_pSuite get_redraw_man_suite(void) { 1551 CU_pSuite get_redraw_man_suite(void) {
1407 CU_pSuite suite; 1552 CU_pSuite suite;
1408 1553
1409 suite = CU_add_suite("Suite_redraw_man", NULL, NULL); 1554 suite = CU_add_suite("Suite_redraw_man", NULL, NULL);
1410 CU_ADD_TEST(suite, test_rdman_redraw_changed); 1555 CU_ADD_TEST(suite, test_rdman_redraw_changed);
1556 CU_ADD_TEST(suite, test_rdman_free_objs);
1411 1557
1412 return suite; 1558 return suite;
1413 } 1559 }
1414 1560
1415 #endif /* UNITTEST */ 1561 #endif /* UNITTEST */