/[zanavi_public1]/navit/navit/callback.c
ZANavi

Contents of /navit/navit/callback.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 5483 byte(s)
import files
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include <glib.h>
21 #include <string.h>
22 #include "item.h"
23 #include "debug.h"
24 #include "callback.h"
25
26 struct callback {
27 void (*func)();
28 int pcount;
29 enum attr_type type;
30 void *p[0];
31
32 };
33
34 struct callback_list {
35 GList *list;
36 };
37
38 struct callback_list *
39 callback_list_new(void)
40 {
41 struct callback_list *ret=g_new0(struct callback_list, 1);
42
43 return ret;
44 }
45
46 struct callback *
47 callback_new_attr(void (*func)(void), enum attr_type type, int pcount, void **p)
48 {
49 struct callback *ret;
50 int i;
51
52 ret=g_malloc0(sizeof(struct callback)+pcount*sizeof(void *));
53 ret->func=func;
54 ret->pcount=pcount;
55 ret->type=type;
56 for (i = 0 ; i < pcount ; i++) {
57 ret->p[i]=p[i];
58 }
59 return ret;
60 }
61
62 struct callback *
63 callback_new_attr_args(void (*func)(void), enum attr_type type, int count, ...)
64 {
65 int i;
66 void **p=g_alloca(sizeof(void*)*count);
67 va_list ap;
68 va_start(ap, count);
69 for (i = 0 ; i < count ; i++)
70 p[i]=va_arg(ap, void *);
71 va_end(ap);
72 return callback_new_attr(func, type, count, p);
73 }
74
75 struct callback *
76 callback_new(void (*func)(void), int pcount, void **p)
77 {
78 return callback_new_attr(func, attr_none, pcount, p);
79 }
80
81 struct callback *
82 callback_new_args(void (*func)(void), int count, ...)
83 {
84 int i;
85 void **p=g_alloca(sizeof(void*)*count);
86 va_list ap;
87 va_start(ap, count);
88 for (i = 0 ; i < count ; i++)
89 p[i]=va_arg(ap, void *);
90 va_end(ap);
91 return callback_new(func, count, p);
92 }
93
94 void
95 callback_destroy(struct callback *cb)
96 {
97 g_free(cb);
98 }
99
100 void
101 callback_set_arg(struct callback *cb, int arg, void *p)
102 {
103 if (arg < 0 || arg > cb->pcount)
104 return;
105 cb->p[arg]=p;
106 }
107
108 void
109 callback_list_add(struct callback_list *l, struct callback *cb)
110 {
111 l->list=g_list_prepend(l->list, cb);
112 }
113
114
115 struct callback *
116 callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p)
117 {
118 struct callback *ret;
119
120 ret=callback_new(func, pcount, p);
121 callback_list_add(l, ret);
122 return ret;
123 }
124
125 void
126 callback_list_remove(struct callback_list *l, struct callback *cb)
127 {
128 l->list=g_list_remove(l->list, cb);
129 }
130
131 void
132 callback_list_remove_destroy(struct callback_list *l, struct callback *cb)
133 {
134 callback_list_remove(l, cb);
135 g_free(cb);
136 }
137
138 void
139 callback_call(struct callback *cb, int pcount, void **p)
140 {
141 int i;
142 void *pf[8];
143 if (! cb)
144 return;
145 if (cb->pcount + pcount <= 8) {
146 dbg(1,"cb->pcount=%d\n", cb->pcount);
147 if (cb->pcount && cb->p)
148 dbg(1,"cb->p[0]=%p\n", cb->p[0]);
149 dbg(1,"pcount=%d\n", pcount);
150 if (pcount) {
151 dbg_assert(p!=NULL);
152 dbg(1,"p[0]=%p\n", p[0]);
153 }
154 for (i = 0 ; i < cb->pcount ; i++)
155 pf[i]=cb->p[i];
156 for (i = 0 ; i < pcount ; i++)
157 pf[i+cb->pcount]=p[i];
158 switch (cb->pcount+pcount) {
159 case 8:
160 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]);
161 break;
162 case 7:
163 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]);
164 break;
165 case 6:
166 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5]);
167 break;
168 case 5:
169 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4]);
170 break;
171 case 4:
172 cb->func(pf[0],pf[1],pf[2],pf[3]);
173 break;
174 case 3:
175 cb->func(pf[0],pf[1],pf[2]);
176 break;
177 case 2:
178 cb->func(pf[0],pf[1]);
179 break;
180 case 1:
181 cb->func(pf[0]);
182 break;
183 case 0:
184 cb->func();
185 break;
186 }
187 } else {
188 dbg(0,"too many parameters for callback (%d+%d)\n", cb->pcount, pcount);
189 }
190 }
191
192 void
193 callback_call_args(struct callback *cb, int count, ...)
194 {
195 int i;
196 void **p=g_alloca(sizeof(void*)*count);
197 va_list ap;
198 va_start(ap, count);
199 for (i = 0 ; i < count ; i++)
200 p[i]=va_arg(ap, void *);
201 va_end(ap);
202 callback_call(cb, count, p);
203 }
204
205 void
206 callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p)
207 {
208 GList *cbi;
209 struct callback *cb;
210
211 if (!l) {
212 return;
213 }
214
215 cbi=l->list;
216 while (cbi) {
217 cb=cbi->data;
218 if (type == attr_any || cb->type == attr_any || cb->type == type)
219 callback_call(cb, pcount, p);
220 cbi=g_list_next(cbi);
221 }
222
223 }
224
225 void
226 callback_list_call_attr_args(struct callback_list *cbl, enum attr_type type, int count, ...)
227 {
228 int i;
229 void **p=g_alloca(sizeof(void*)*count);
230 va_list ap;
231 va_start(ap, count);
232 for (i = 0 ; i < count ; i++)
233 p[i]=va_arg(ap, void *);
234 va_end(ap);
235 callback_list_call_attr(cbl, type, count, p);
236 }
237
238 void
239 callback_list_call(struct callback_list *l, int pcount, void **p)
240 {
241 callback_list_call_attr(l, attr_any, pcount, p);
242 }
243
244 void
245 callback_list_call_args(struct callback_list *cbl, int count, ...)
246 {
247 int i;
248 void **p=g_alloca(sizeof(void*)*count);
249 va_list ap;
250 va_start(ap, count);
251 for (i = 0 ; i < count ; i++)
252 p[i]=va_arg(ap, void *);
253 va_end(ap);
254 callback_list_call(cbl, count, p);
255 }
256
257 void
258 callback_list_destroy(struct callback_list *l)
259 {
260 GList *cbi;
261 cbi=l->list;
262 while (cbi) {
263 g_free(cbi->data);
264 cbi=g_list_next(cbi);
265 }
266 g_list_free(l->list);
267 g_free(l);
268 }

   
Visit the ZANavi Wiki