Mercurial > MadButterfly
annotate include/mb_tools.h @ 221:ad4f8a956505
Implement a workaround for the button class. However, this won't solve all issues. We can use this as example to fix the mouse out event issue. When we move the curosr over the text inside the button. The upper layer group will receive MOUSE_OUT events. This is absolute incorrect.
author | wycc |
---|---|
date | Sun, 14 Dec 2008 12:35:13 +0800 |
parents | 530bb7728546 |
children | 65cabbdd5284 |
rev | line source |
---|---|
12 | 1 #ifndef __TOOLS_H_ |
2 #define __TOOLS_H_ | |
3 | |
4 typedef struct _elmpool elmpool_t; | |
5 | |
6 extern elmpool_t *elmpool_new(int elm_sz, int inc_num); | |
7 extern void *elmpool_elm_alloc(elmpool_t *pool); | |
8 extern void elmpool_elm_free(elmpool_t *pool, void *elm); | |
9 extern void elmpool_free(elmpool_t *pool); | |
10 | |
11 | |
12 #define STAILQ(type) \ | |
13 struct { \ | |
14 type *head; \ | |
15 type *tail; \ | |
16 } | |
17 #define STAILQ_INIT(q) \ | |
18 do { \ | |
19 (q).head = (q).tail = NULL; \ | |
20 } while(0) | |
13 | 21 #define STAILQ_CLEAN(q) STAILQ_INIT(q) |
12 | 22 #define STAILQ_HEAD(q) ((q).head) |
23 #define STAILQ_TAIL(q) ((q).tail) | |
24 #define STAILQ_NEXT(type, field, elm) ((elm)->field) | |
25 #define STAILQ_INS(q, type, field, elm) \ | |
26 do { \ | |
27 (elm)->field = (q).head; \ | |
28 (q).head = elm; \ | |
29 if((q).tail == NULL) \ | |
30 (q).tail = elm; \ | |
31 } while(0) | |
32 #define STAILQ_INS_TAIL(q, type, field, elm) \ | |
33 do { \ | |
34 (elm)->field = NULL; \ | |
35 if((q).tail != NULL) \ | |
36 (q).tail->field = elm; \ | |
37 (q).tail = elm; \ | |
38 if((q).head == NULL) \ | |
39 (q).head = elm; \ | |
40 } while(0) | |
39 | 41 #define STAILQ_INS_AFTER(type, field, follow, elm) \ |
42 do { \ | |
43 (follow)->field = (elm)->field; \ | |
44 (elm)->field = follow; \ | |
45 } while(0) | |
12 | 46 #define STAILQ_REMOVE(q, type, field, elm) \ |
96 | 47 do { \ |
12 | 48 if((elm) == (q).head) { \ |
49 (q).head = (elm)->field; \ | |
50 if((q).head == NULL) \ | |
51 (q).tail = NULL; \ | |
52 } else { \ | |
53 type *_stailq_cur = (q).head; \ | |
54 while(_stailq_cur != NULL && \ | |
55 _stailq_cur->field != (elm)) \ | |
56 _stailq_cur = _stailq_cur->field; \ | |
57 if(_stailq_cur != NULL) { \ | |
155
6749f6639924
Fix bug for STAILQ that fail to remove a node.
Thinker K.F. Li <thinker@branda.to>
parents:
131
diff
changeset
|
58 _stailq_cur->field = (elm)->field; \ |
12 | 59 if((q).tail == (elm)) \ |
60 (q).tail = _stailq_cur; \ | |
61 } \ | |
62 } \ | |
63 } while(0) | |
64 | |
158
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
65 /*! \defgroup darray Dynamic Array |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
66 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
67 * DARRAY is a dynamic sized array/list, it's length is a variable. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
68 * It is extended, automatically, if it is full and more elemnts are |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
69 * putted in. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
70 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
71 * Users of DARRAY must declare a new type to store data. The way to |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
72 * declear a new type is to invoke DARRAY() with paramters of name of |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
73 * type and type of data to be stored in. The new storage type is named |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
74 * with foo_t where foo is the name you pass in. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
75 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
76 * DARRAY_DEFINE() is inovked to define foo_add() function; foo is name |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
77 * of storage type. You can call foo_add() to add a data element |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
78 * into a storage object. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
79 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
80 * Get ith element in a storage object, use |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
81 * \code |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
82 * obj->ds[i] |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
83 * \endcode |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
84 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
85 * To loop over elements in a storage object, us |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
86 * \code |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
87 * for(i = 0; i < obj->num; i++) { |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
88 * v = obj->ds[i]; |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
89 * ...... |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
90 * } |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
91 * \endcode |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
92 * @{ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
93 */ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
94 /*! \brief Declare a DARRAY storage type. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
95 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
96 * \param name is name of storage type. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
97 * \param type is type of data elements that will be stored in. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
98 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
99 * Type of <name>_t is defined by the macro. It is used to define a |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
100 * storage object to contain data elements. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
101 */ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
102 #define DARRAY(name, type) \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
103 struct _ ## name { \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
104 int max, num; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
105 type *ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
106 }; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
107 typedef struct _ ## name name ## _t |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
108 #define DARRAY_DEFINE(name, type) \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
109 static int name ## _add(name ## _t *da, type v) { \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
110 type *new_ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
111 int max; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
112 if(da->num >= (da)->max) { \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
113 max = (da)->max + 32; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
114 new_ds = realloc(da->ds, \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
115 max * sizeof(type)); \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
116 if(new_ds == NULL) return -1; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
117 da->ds = new_ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
118 da->max = max; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
119 } \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
120 da->ds[da->num++] = v; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
121 return 0; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
122 } |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
123 #define DARRAY_CLEAN(da) do { (da)->num = 0; } while(0) |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
124 #define DARRAY_INIT(da) do { (da)->num = (da)->max = 0; (da)->ds = NULL; } |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
125 #define DARRAY_DESTROY(da) do { if((da)->ds) free((da)->ds); } while(0) |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
126 /* @} */ |
55 | 127 |
131
6a8588df68af
Tank can change direction and navigate on the mud area
Thinker K.F. Li <thinker@branda.to>
parents:
96
diff
changeset
|
128 #include <stdlib.h> |
6a8588df68af
Tank can change direction and navigate on the mud area
Thinker K.F. Li <thinker@branda.to>
parents:
96
diff
changeset
|
129 |
55 | 130 #define O_ALLOC(type) ((type *)malloc(sizeof(type))) |
131 | |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
55
diff
changeset
|
132 #define OFFSET(type, mem) (((void *)&((type *)NULL)->mem) - NULL) |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
55
diff
changeset
|
133 #define MEM2OBJ(var, type, mem) ((type *)((void *)var - OFFSET(type, mem))) |
93 | 134 #define OFF2TYPE(obj, off, type) (*(type *)((void *)(obj) + (off))) |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
55
diff
changeset
|
135 |
12 | 136 #endif /* __TOOLS_H_ */ |