changeset 151:d11aa8fc06c7

Fix bug of tanks do not show at right places. Since we avoid to dirty a subtree if root of a subtree have been dirty or hidden, it make children that was added into coord tree after a coord be dirty do not be marked with COF_DIRTY flag. To fix it, when a new coord is created, the parent is checked and mark new coord with COF_DIRTY flag if the parent is dirty. It forces new coords to be cleaned and transformed to right places.
author Thinker K.F. Li <thinker@branda.to>
date Fri, 26 Sep 2008 17:42:16 +0800
parents 0824f4804ee0
children 2b316b5d65f9
files src/coord.c src/mb_types.h src/redraw_man.c
diffstat 3 files changed, 39 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/coord.c	Thu Sep 25 23:44:38 2008 +0800
+++ b/src/coord.c	Fri Sep 26 17:42:16 2008 +0800
@@ -120,22 +120,33 @@
     return sqrt(x * x + y * y);
 }
 
+/*!
+ * \note Coords, marked with COF_SKIP_TRIVAL (for temporary), and
+ * descendants of them will not be trivaled and the flag with be removed
+ * after skipping them.
+ */
 coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) {
-    coord_t *next;
+    coord_t *next = NULL;
 
     ASSERT(last != NULL);
     
-    if(STAILQ_HEAD(last->children))
+    if((!(last->flags & COF_SKIP_TRIVAL)) &&
+       STAILQ_HEAD(last->children)) {
 	next = STAILQ_HEAD(last->children);
-    else {
+	if(!(next->flags & COF_SKIP_TRIVAL))
+	    return next;
+    } else {
 	next = last;
+    }
+
+    do {
+	next->flags &= ~COF_SKIP_TRIVAL;
 	while(next != root && STAILQ_NEXT(coord_t, sibling, next) == NULL)
 	    next = next->parent;
 	if(next == root)
-	    next = NULL;
-	if(next)
-	    next = STAILQ_NEXT(coord_t, sibling, next);
-    }
+	    return NULL;
+	next = STAILQ_NEXT(coord_t, sibling, next);
+    } while(next->flags & COF_SKIP_TRIVAL);
 
     return next;
 }
--- a/src/mb_types.h	Thu Sep 25 23:44:38 2008 +0800
+++ b/src/mb_types.h	Fri Sep 26 17:42:16 2008 +0800
@@ -117,6 +117,9 @@
 #define COF_OWN_CANVAS 0x4	/*!< A coord owns a canvas or inherit it
 				 * from an ancestor.
 				 */
+#define COF_SKIP_TRIVAL 0x8	/*!< Temporary skip descendants
+				 * when trivaling.
+				 */
 
 extern void coord_init(coord_t *co, coord_t *parent);
 extern void coord_trans_pos(coord_t *co, co_aix *x, co_aix *y);
@@ -125,6 +128,9 @@
 extern void update_aggr_matrix(coord_t *start);
 extern coord_t *preorder_coord_subtree(coord_t *root, coord_t *last);
 extern coord_t *postorder_coord_subtree(coord_t *root, coord_t *last);
+extern void preorder_coord_skip_subtree(coord_t *subroot);
+#define preorder_coord_skip_subtree(sub)		\
+    do { (sub)->flags |= COF_SKIP_TRIVAL; } while(0)
 #define coord_hide(co) do { co->flags |= COF_HIDDEN; } while(0)
 #define coord_show(co) do { co->flags &= ~COF_HIDDEN; } while(0)
 #define coord_get_mouse_event(coord) ((coord)->mouse_event)
--- a/src/redraw_man.c	Thu Sep 25 23:44:38 2008 +0800
+++ b/src/redraw_man.c	Fri Sep 26 17:42:16 2008 +0800
@@ -391,6 +391,10 @@
 
     coord->before_pmem = parent->num_members;
 
+    /* If parent is dirty, children should be dirty. */
+    if(parent && (parent->flags & COF_DIRTY))
+	rdman_coord_changed(rdman, coord);
+
     return coord;
 }
 
@@ -449,15 +453,21 @@
 
     if(coord->flags & COF_DIRTY)
 	return OK;
-    
-    /* Make the coord and child coords dirty. */
-    for(child = coord;
+
+    make_sure_dirty_coords(rdman);
+    rdman->dirty_coords[rdman->n_dirty_coords++] = coord;
+    coord->flags |= COF_DIRTY;
+
+    /* Make child coords dirty. */
+    for(child = preorder_coord_subtree(coord, coord);
 	child != NULL;
 	child = preorder_coord_subtree(coord, child)) {
-	if(child->flags & COF_DIRTY)
+	if(child->flags & (COF_DIRTY | COF_HIDDEN)) {
+	    preorder_coord_skip_subtree(child);
 	    continue;
+	}
+
 	make_sure_dirty_coords(rdman);
- 
 	rdman->dirty_coords[rdman->n_dirty_coords++] = child;
 	child->flags |= COF_DIRTY;
     }