Mercurial > MadButterfly
changeset 194:45d9a1e2764d
Add mb_subtree_free animate action and fix bugs.
- Free members of a coord in rdman_coord_subtree_free().
- Fix core dump issue of subject_notify() that can not free subjects well.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 19 Nov 2008 20:53:40 +0800 |
parents | 923d91dfb6af |
children | 5235aded379c |
files | examples/tank/tank_main.c include/mb_animate.h src/Makefile.am src/animate.c src/observer.c src/redraw_man.c src/shift.c src/subtree_free.c |
diffstat | 8 files changed, 97 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/tank/tank_main.c Wed Nov 19 11:26:01 2008 +0800 +++ b/examples/tank/tank_main.c Wed Nov 19 20:53:40 2008 +0800 @@ -396,6 +396,8 @@ word = mb_progm_next_word(progm, &start, &playing); mb_visibility_new(VIS_HIDDEN, bang->root_coord, word); + mb_subtree_free_new(bang->root_coord, word); + mb_progm_free_completed(progm); /*! \todo Remove bang when program is completed.
--- a/include/mb_animate.h Wed Nov 19 11:26:01 2008 +0800 +++ b/include/mb_animate.h Wed Nov 19 20:53:40 2008 +0800 @@ -56,6 +56,8 @@ paint_t *paint, mb_word_t *word); extern mb_action_t *mb_rotate_new(float angle1, float angle2, coord_t *coord, mb_word_t *word); +extern mb_action_t *mb_subtree_free_new(coord_t *coord, + mb_word_t *word); enum { VIS_VISIBLE, VIS_HIDDEN }; extern mb_action_t *mb_visibility_new(int visib, coord_t *coord,
--- a/src/Makefile.am Wed Nov 19 11:26:01 2008 +0800 +++ b/src/Makefile.am Wed Nov 19 20:53:40 2008 +0800 @@ -4,7 +4,10 @@ noinst_PROGRAMS = X_main -libmbfly_la_SOURCES = animate.c chgcolor.c coord.c event.c geo.c observer.c paint.c redraw_man.c rotate.c shape_path.c shape_rect.c shape_text.c shift.c timer.c timertool.c tools.c visibility.c X_supp.c +libmbfly_la_SOURCES = animate.c chgcolor.c coord.c event.c geo.c \ + observer.c paint.c redraw_man.c rotate.c shape_path.c \ + shape_rect.c shape_text.c shift.c subtree_free.c timer.c \ + timertool.c tools.c visibility.c X_supp.c libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ libmbfly_la_LDFLAGS = @cairo_LIBS@
--- a/src/animate.c Wed Nov 19 11:26:01 2008 +0800 +++ b/src/animate.c Wed Nov 19 20:53:40 2008 +0800 @@ -127,6 +127,10 @@ #ifndef UNITTEST factory = rdman_get_ob_factory(rdman); progm->complete = subject_new(factory, progm, OBJT_PROGM); + if(progm->complete == NULL) { + free(progm); + return NULL; + } #endif /* UNITTEST */ progm->n_words = 0;
--- a/src/observer.c Wed Nov 19 11:26:01 2008 +0800 +++ b/src/observer.c Wed Nov 19 20:53:40 2008 +0800 @@ -51,6 +51,7 @@ void subject_notify(subject_t *subject, event_t *evt) { ob_factory_t *factory = subject->factory; observer_t *observer; + subject_t *old_subject; evt->tgt = subject; while(subject) { @@ -69,15 +70,16 @@ } subject->flags &= ~SUBF_BUSY; - if(subject->flags & SUBF_FREE) - subject_free(subject); + + old_subject = subject; + subject = factory->get_parent_subject(factory, subject); - if(subject->flags & SUBF_STOP_PROPAGATE) + if(old_subject->flags & SUBF_FREE) + subject_free(old_subject); + + if(old_subject->flags & SUBF_STOP_PROPAGATE) break; - - subject = factory->get_parent_subject(factory, subject); } - } observer_t *subject_add_observer(subject_t *subject,
--- a/src/redraw_man.c Wed Nov 19 11:26:01 2008 +0800 +++ b/src/redraw_man.c Wed Nov 19 20:53:40 2008 +0800 @@ -613,6 +613,24 @@ return OK; } +static _rdman_coord_free_members(redraw_man_t *rdman, coord_t *coord) { + geo_t *member; + shape_t *shape; + int r; + + FORMEMBERS(coord, member) { + shape = geo_get_shape(member); + r = rdman_shape_free(rdman, shape); + if(r != OK) + return ERR; + } + return OK; +} + +/*! \brief Free descendant coords and shapes of a coord. + * + * The specified coord is also freed. + */ int rdman_coord_subtree_free(redraw_man_t *rdman, coord_t *subtree) { coord_t *coord, *prev_coord; int r; @@ -625,6 +643,10 @@ coord != NULL; coord = postorder_coord_subtree(subtree, coord)) { if(!(prev_coord->flags & COF_FREE)) { + r = _rdman_coord_free_members(rdman, prev_coord); + if(r != OK) + return ERR; + r = rdman_coord_free(rdman, prev_coord); if(r != OK) return ERR; @@ -632,6 +654,10 @@ prev_coord = coord; } if(!(prev_coord->flags & COF_FREE)) { + r = _rdman_coord_free_members(rdman, prev_coord); + if(r != OK) + return ERR; + r = rdman_coord_free(rdman, prev_coord); if(r != OK) return ERR;
--- a/src/shift.c Wed Nov 19 11:26:01 2008 +0800 +++ b/src/shift.c Wed Nov 19 20:53:40 2008 +0800 @@ -80,7 +80,7 @@ shift = (mb_shift_t *)malloc(sizeof(mb_shift_t)); if(shift == NULL) - return (mb_action_t *)shift; + return NULL; shift->x = x; shift->y = y;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/subtree_free.c Wed Nov 19 20:53:40 2008 +0800 @@ -0,0 +1,50 @@ +#include "mb_redraw_man.h" +#include "mb_animate.h" + +struct _subtree_free { + mb_action_t action; + + coord_t *coord; +}; + +typedef struct _subtree_free subtree_free_t; + +void mb_subtree_free_start(mb_action_t *action, + const mb_timeval_t *now, + const mb_timeval_t *playing_time, + redraw_man_t *rdman) { + subtree_free_t *sfree = (subtree_free_t *)action; + + rdman_coord_subtree_free(rdman, sfree->coord); +} + +void mb_subtree_free_step(mb_action_t *act, const mb_timeval_t *now, + redraw_man_t *rdman) { +} + +void mb_subtree_free_stop(mb_action_t *act, const mb_timeval_t *now, + redraw_man_t *rdman) { +} + +void mb_subtree_free_free(mb_action_t *act) { + free(act); +} + +mb_action_t *mb_subtree_free_new(coord_t *coord, + mb_word_t *word) { + subtree_free_t *sfree; + + sfree = (subtree_free_t *)malloc(sizeof(subtree_free_t)); + if(sfree == NULL) + return NULL; + + sfree->action.start = mb_subtree_free_start; + sfree->action.step = mb_subtree_free_step; + sfree->action.stop = mb_subtree_free_stop; + sfree->action.free = mb_subtree_free_free; + sfree->coord = coord; + + mb_word_add_action(word, (mb_action_t *)sfree); + + return (mb_action_t *)sfree; +}