Mercurial > MadButterfly
annotate include/mb_tools.h @ 1493:b0e113605382
Add comment
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 02 May 2011 23:26:32 +0800 |
parents | 586e50f82c1f |
children |
rev | line source |
---|---|
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
422
diff
changeset
|
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- |
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
422
diff
changeset
|
2 // vim: sw=4:ts=8:sts=4 |
12 | 3 #ifndef __TOOLS_H_ |
4 #define __TOOLS_H_ | |
5 | |
6 typedef struct _elmpool elmpool_t; | |
7 | |
8 extern elmpool_t *elmpool_new(int elm_sz, int inc_num); | |
9 extern void *elmpool_elm_alloc(elmpool_t *pool); | |
10 extern void elmpool_elm_free(elmpool_t *pool, void *elm); | |
11 extern void elmpool_free(elmpool_t *pool); | |
12 | |
13 | |
14 #define STAILQ(type) \ | |
15 struct { \ | |
16 type *head; \ | |
17 type *tail; \ | |
18 } | |
19 #define STAILQ_INIT(q) \ | |
20 do { \ | |
21 (q).head = (q).tail = NULL; \ | |
22 } while(0) | |
13 | 23 #define STAILQ_CLEAN(q) STAILQ_INIT(q) |
12 | 24 #define STAILQ_HEAD(q) ((q).head) |
25 #define STAILQ_TAIL(q) ((q).tail) | |
26 #define STAILQ_NEXT(type, field, elm) ((elm)->field) | |
27 #define STAILQ_INS(q, type, field, elm) \ | |
28 do { \ | |
29 (elm)->field = (q).head; \ | |
30 (q).head = elm; \ | |
31 if((q).tail == NULL) \ | |
32 (q).tail = elm; \ | |
33 } while(0) | |
34 #define STAILQ_INS_TAIL(q, type, field, elm) \ | |
35 do { \ | |
36 (elm)->field = NULL; \ | |
37 if((q).tail != NULL) \ | |
38 (q).tail->field = elm; \ | |
39 (q).tail = elm; \ | |
40 if((q).head == NULL) \ | |
41 (q).head = elm; \ | |
42 } while(0) | |
39 | 43 #define STAILQ_INS_AFTER(type, field, follow, elm) \ |
44 do { \ | |
45 (follow)->field = (elm)->field; \ | |
46 (elm)->field = follow; \ | |
47 } while(0) | |
12 | 48 #define STAILQ_REMOVE(q, type, field, elm) \ |
96 | 49 do { \ |
12 | 50 if((elm) == (q).head) { \ |
51 (q).head = (elm)->field; \ | |
52 if((q).head == NULL) \ | |
53 (q).tail = NULL; \ | |
54 } else { \ | |
55 type *_stailq_cur = (q).head; \ | |
56 while(_stailq_cur != NULL && \ | |
57 _stailq_cur->field != (elm)) \ | |
58 _stailq_cur = _stailq_cur->field; \ | |
59 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
|
60 _stailq_cur->field = (elm)->field; \ |
12 | 61 if((q).tail == (elm)) \ |
62 (q).tail = _stailq_cur; \ | |
63 } \ | |
64 } \ | |
65 } while(0) | |
250
bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
Thinker K.F. Li <thinker@branda.to>
parents:
235
diff
changeset
|
66 #define STAILQ_FOR_EACH(q, type, field, elm) \ |
bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
Thinker K.F. Li <thinker@branda.to>
parents:
235
diff
changeset
|
67 for((elm) = (q).head; \ |
bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
Thinker K.F. Li <thinker@branda.to>
parents:
235
diff
changeset
|
68 (elm) != NULL; \ |
bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
Thinker K.F. Li <thinker@branda.to>
parents:
235
diff
changeset
|
69 (elm) = (elm)->field) |
12 | 70 |
158
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
71 /*! \defgroup darray Dynamic Array |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
72 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
73 * 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
|
74 * 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
|
75 * putted in. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
76 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
77 * 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
|
78 * 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
|
79 * 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
|
80 * 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
|
81 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
82 * 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
|
83 * 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
|
84 * into a storage object. |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
85 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
86 * 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
|
87 * \code |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
88 * obj->ds[i] |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
89 * \endcode |
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 * 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
|
92 * \code |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
93 * 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
|
94 * v = obj->ds[i]; |
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 * } |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
97 * \endcode |
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 */ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
100 /*! \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
|
101 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
102 * \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
|
103 * \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
|
104 * |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
105 * 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
|
106 * 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
|
107 */ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
108 #define DARRAY(name, type) \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
109 struct _ ## name { \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
110 int max, num; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
111 type *ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
112 }; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
113 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
|
114 #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
|
115 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
|
116 type *new_ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
117 int max; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
118 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
|
119 max = (da)->max + 32; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
120 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
|
121 max * sizeof(type)); \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
122 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
|
123 da->ds = new_ds; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
124 da->max = max; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
125 } \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
126 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
|
127 return 0; \ |
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
128 } |
422
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
129 #define DARRAY_DEFINE_ADV(name, type) \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
130 static int name ## _adv(name ## _t *da, int n) { \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
131 type *new_ds; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
132 int max; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
133 if((da->num + n) > (da)->max) { \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
134 max = ((da)->num + n + 31) & ~0x1f; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
135 new_ds = realloc(da->ds, \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
136 max * sizeof(type)); \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
137 if(new_ds == NULL) return -1; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
138 da->ds = new_ds; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
139 da->max = max; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
140 } \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
141 da->num += n; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
142 return 0; \ |
c6c0d017dc8e
Use DARRAY to manage variable length list
Thinker K.F. Li <thinker@branda.to>
parents:
375
diff
changeset
|
143 } |
158
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
144 #define DARRAY_CLEAN(da) do { (da)->num = 0; } while(0) |
235 | 145 #define DARRAY_INIT(da) \ |
146 do { (da)->num = (da)->max = 0; (da)->ds = NULL; } while(0) | |
158
c1cdd3fcd28f
Postponing rdman_coord_free() and rdman_remove_shape().
Thinker K.F. Li <thinker@branda.to>
parents:
155
diff
changeset
|
147 #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
|
148 /* @} */ |
55 | 149 |
131
6a8588df68af
Tank can change direction and navigate on the mud area
Thinker K.F. Li <thinker@branda.to>
parents:
96
diff
changeset
|
150 #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
|
151 |
55 | 152 #define O_ALLOC(type) ((type *)malloc(sizeof(type))) |
153 | |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
55
diff
changeset
|
154 #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
|
155 #define MEM2OBJ(var, type, mem) ((type *)((void *)var - OFFSET(type, mem))) |
93 | 156 #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
|
157 |
375
44b8223f307c
Rename MIN/MAX to MB_MIN/MB_MAX.
Thinker K.F. Li <thinker@branda.to>
parents:
250
diff
changeset
|
158 #define MB_MAX(a, b) ((a) > (b)? (a): (b)) |
44b8223f307c
Rename MIN/MAX to MB_MIN/MB_MAX.
Thinker K.F. Li <thinker@branda.to>
parents:
250
diff
changeset
|
159 #define MB_MIN(a, b) ((a) < (b)? (a): (b)) |
250
bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
Thinker K.F. Li <thinker@branda.to>
parents:
235
diff
changeset
|
160 |
12 | 161 #endif /* __TOOLS_H_ */ |