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

Contents of /navit/navit/callback.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations) (download)
Wed Aug 22 17:01:27 2012 UTC (7 years, 4 months ago) by zoff99
File MIME type: text/plain
File size: 9617 byte(s)
ZANavi 2.0, lots of changes, everything in its own thread, more performance
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
27 struct callback_list *
28 callback_list_new(void)
29 {
30 struct callback_list *ret=g_new0(struct callback_list, 1);
31
32 return ret;
33 }
34
35 struct callback *
36 callback_new_attr(void (*func)(void), enum attr_type type, int pcount, void **p)
37 {
38 struct callback *ret;
39 int i;
40
41 ret=g_malloc0(sizeof(struct callback)+pcount*sizeof(void *));
42 ret->func=func;
43 ret->pcount=pcount;
44 ret->type=type;
45 for (i = 0 ; i < pcount ; i++)
46 {
47 ret->p[i]=p[i];
48 }
49
50 ret->func_name[0] = 'e';
51 ret->func_name[1] = 'm';
52 ret->func_name[2] = 'p';
53 ret->func_name[3] = 't';
54 ret->func_name[4] = 'y';
55 ret->func_name[5] = '\0';
56
57 ret->setup_func_name[0] = 'e';
58 ret->setup_func_name[1] = 'm';
59 ret->setup_func_name[2] = 'p';
60 ret->setup_func_name[3] = 't';
61 ret->setup_func_name[4] = 'y';
62 ret->setup_func_name[5] = '\0';
63
64 return ret;
65 }
66
67 static void callback_print_names(struct callback *cb, const char *cb_func)
68 {
69 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
70 if (cb == NULL)
71 {
72 dbg(0,"%d CB_f=%s:CB=NULL!\n", cb, cb_func);
73 }
74 else
75 {
76 dbg(0,"%d CB_f=%s, parent=%s, func=%s\n", cb, cb_func, cb->setup_func_name, cb->func_name);
77 }
78 #endif
79 }
80
81 static void callback_print_names2(struct callback *cb, const char *cb_func, const char *module, const int mlen,const char *function)
82 {
83 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
84 if (cb == NULL)
85 {
86 dbg(0,"%d CB_f=%s:CB=NULL! file=%s line=%d func=%s\n", cb, cb_func, module, mlen, function);
87 }
88 else
89 {
90 dbg(0,"%d CB_f=%s, parent=%s, func=%s -- file=%s line=%d func=%s\n", cb, cb_func, cb->setup_func_name, cb->func_name, module, mlen, function);
91 }
92 #endif
93 }
94
95 void callback_add_names(struct callback *cb, const char *parent_name, const char *func_name)
96 {
97 if (cb == NULL)
98 {
99 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
100 dbg(0,"callback_add_names:CB=NULL!\n");
101 #endif
102 return;
103 }
104
105 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
106 dbg(0,"%d CB_I=%s, %s\n", cb, parent_name, func_name);
107 #endif
108
109 snprintf(cb->func_name, 398, "%s", func_name);
110 cb->func_name[397] = '\0';
111 cb->func_name[398] = '\0';
112 cb->func_name[399] = '\0';
113
114 snprintf(cb->setup_func_name, 398, "%s", parent_name);
115 cb->setup_func_name[397] = '\0';
116 cb->setup_func_name[398] = '\0';
117 cb->setup_func_name[399] = '\0';
118
119 }
120
121 struct callback *
122 callback_new_attr_args(const char *module, const int mlen,const char *function, void (*func)(void), enum attr_type type, int count, ...)
123 {
124 int i;
125 void **p=g_alloca(sizeof(void*)*count);
126 va_list ap;
127 va_start(ap, count);
128 for (i = 0 ; i < count ; i++)
129 p[i]=va_arg(ap, void *);
130 va_end(ap);
131
132 struct callback *ret = callback_new_attr(func, type, count, p);
133 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
134 dbg(0,"%d callback_new_attr_%d -- file=%s line=%d func=%s\n", ret, count, module, mlen, function);
135 #endif
136 return ret;
137 }
138
139 struct callback *
140 callback_new(void (*func)(void), int pcount, void **p)
141 {
142 return callback_new_attr(func, attr_none, pcount, p);
143 }
144
145 struct callback *
146 callback_new_args(const char *module, const int mlen,const char *function, void (*func)(void), int count, ...)
147 {
148 int i;
149 void **p=g_alloca(sizeof(void*)*count);
150 va_list ap;
151 va_start(ap, count);
152 for (i = 0 ; i < count ; i++)
153 p[i]=va_arg(ap, void *);
154 va_end(ap);
155
156 struct callback *ret = callback_new(func, count, p);
157
158 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
159 dbg(0,"%d callback_new_%d -- file=%s line=%d func=%s\n", ret, count, module, mlen, function);
160 #endif
161 return ret;
162 }
163
164 void
165 callback_destroy_real(const char *module, const int mlen,const char *function, struct callback *cb)
166 {
167 if (cb == NULL)
168 {
169 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
170 dbg(0,"%d callback_destroy_real:CB=NULL!! -- file=%s line=%d func=%s\n", cb, module, mlen, function);
171 #endif
172 return;
173 }
174
175 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
176 callback_print_names2(cb, "callback_destroy", module, mlen, function);
177 #endif
178
179 g_free(cb);
180 }
181
182 void
183 callback_set_arg(struct callback *cb, int arg, void *p)
184 {
185 if (arg < 0 || arg > cb->pcount)
186 return;
187 cb->p[arg]=p;
188 }
189
190 void
191 callback_list_add(struct callback_list *l, struct callback *cb)
192 {
193 l->list=g_list_prepend(l->list, cb);
194 }
195
196
197 struct callback *
198 callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p)
199 {
200 struct callback *ret;
201
202 ret=callback_new(func, pcount, p);
203 callback_list_add(l, ret);
204 return ret;
205 }
206
207 void
208 callback_list_remove(struct callback_list *l, struct callback *cb)
209 {
210 l->list=g_list_remove(l->list, cb);
211 }
212
213 void
214 callback_list_remove_destroy(struct callback_list *l, struct callback *cb)
215 {
216 if (l == NULL)
217 {
218 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
219 dbg(0,"callback_list_remove_destroy:CBL=NULL!!\n");
220 #endif
221 return;
222 }
223
224 if (cb == NULL)
225 {
226 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
227 dbg(0,"callback_list_remove_destroy:CB=NULL!!\n");
228 #endif
229 return;
230 }
231
232 callback_list_remove(l, cb);
233 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
234 callback_print_names(cb, "callback_list_remove_destroy");
235 #endif
236 g_free(cb);
237 }
238
239 void
240 callback_call(struct callback *cb, int pcount, void **p)
241 {
242 int i;
243 void *pf[8];
244
245 if (! cb)
246 {
247 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
248 dbg(0,"callback_call:CB=NULL!!\n");
249 #endif
250 return;
251 }
252
253 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
254 callback_print_names(cb, "callback_call");
255 #endif
256
257 if (cb->pcount + pcount <= 8)
258 {
259 //dbg(1,"cb->pcount=%d\n", cb->pcount);
260 if (cb->pcount && cb->p)
261 {
262 //dbg(1,"cb->p[0]=%p\n", cb->p[0]);
263 }
264 //dbg(1,"pcount=%d\n", pcount);
265 if (pcount)
266 {
267 dbg_assert(p!=NULL);
268 //dbg(1,"p[0]=%p\n", p[0]);
269 }
270
271 for (i = 0 ; i < cb->pcount ; i++)
272 pf[i]=cb->p[i];
273
274 for (i = 0 ; i < pcount ; i++)
275 pf[i+cb->pcount]=p[i];
276
277 switch (cb->pcount+pcount)
278 {
279 case 8:
280 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]);
281 break;
282 case 7:
283 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]);
284 break;
285 case 6:
286 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5]);
287 break;
288 case 5:
289 cb->func(pf[0],pf[1],pf[2],pf[3],pf[4]);
290 break;
291 case 4:
292 cb->func(pf[0],pf[1],pf[2],pf[3]);
293 break;
294 case 3:
295 cb->func(pf[0],pf[1],pf[2]);
296 break;
297 case 2:
298 cb->func(pf[0],pf[1]);
299 break;
300 case 1:
301 cb->func(pf[0]);
302 break;
303 case 0:
304 cb->func();
305 break;
306 }
307 }
308 else
309 {
310 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
311 dbg(0,"too many parameters for callback (%d+%d)\n", cb->pcount, pcount);
312 #endif
313 }
314 }
315
316 void
317 callback_call_args_real(const char *module, const int mlen,const char *function, struct callback *cb, int count, ...)
318 {
319
320 if (cb == NULL)
321 {
322 // callback struct is NULL
323 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
324 dbg(0,"callback_call:CB=NULL! file=%s line=%d func=%s\n", module, mlen, function);
325 #endif
326 return;
327 }
328
329 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
330 callback_print_names2(cb, "callback_call", module, mlen, function);
331 #endif
332
333 int i;
334 void **p=g_alloca(sizeof(void*)*count);
335 va_list ap;
336 va_start(ap, count);
337 for (i = 0 ; i < count ; i++)
338 p[i]=va_arg(ap, void *);
339 va_end(ap);
340 callback_call(cb, count, p);
341 }
342
343
344 void
345 callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p)
346 {
347 GList *cbi;
348 struct callback *cb;
349
350 if (!l)
351 {
352 return;
353 }
354
355 cbi=l->list;
356 while (cbi)
357 {
358 cb=cbi->data;
359 if (type == attr_any || cb->type == attr_any || cb->type == type)
360 {
361 callback_call(cb, pcount, p);
362 }
363 cbi=g_list_next(cbi);
364 }
365
366 }
367
368 void
369 callback_list_call_attr_args(const char *module, const int mlen,const char *function, struct callback_list *cbl, enum attr_type type, int count, ...)
370 {
371 int i;
372 void **p=g_alloca(sizeof(void*)*count);
373 va_list ap;
374 va_start(ap, count);
375 for (i = 0 ; i < count ; i++)
376 p[i]=va_arg(ap, void *);
377 va_end(ap);
378
379 if (cbl == NULL)
380 {
381 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
382 dbg(0,"%d callback_list_call_attr_args:CBL=NULL! file=%s line=%d func=%s\n", cbl, module, mlen, function);
383 #endif
384 return;
385 }
386 else
387 {
388 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
389 dbg(0,"%d callback_list_call_attr_args:file=%s line=%d func=%s\n", cbl, module, mlen, function);
390 #endif
391 }
392
393 callback_list_call_attr(cbl, type, count, p);
394 }
395
396 void
397 callback_list_call(struct callback_list *l, int pcount, void **p)
398 {
399 callback_list_call_attr(l, attr_any, pcount, p);
400 }
401
402 void
403 callback_list_call_args(const char *module, const int mlen,const char *function, struct callback_list *cbl, int count, ...)
404 {
405
406 if (cbl == NULL)
407 {
408 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
409 dbg(0,"%d callback_list_call_args:CBL=NULL! file=%s line=%d func=%s\n", cbl, module, mlen, function);
410 #endif
411 return;
412 }
413 else
414 {
415 #ifdef NAVIT_CALLBACK_DEBUG_PRINT
416 dbg(0,"%d callback_list_call_args:file=%s line=%d func=%s\n", cbl, module, mlen, function);
417 #endif
418 }
419
420 int i;
421 void **p=g_alloca(sizeof(void*)*count);
422 va_list ap;
423 va_start(ap, count);
424 for (i = 0 ; i < count ; i++)
425 p[i]=va_arg(ap, void *);
426 va_end(ap);
427 callback_list_call(cbl, count, p);
428 }
429
430 void
431 callback_list_destroy(struct callback_list *l)
432 {
433 GList *cbi;
434 cbi=l->list;
435 while (cbi) {
436 g_free(cbi->data);
437 cbi=g_list_next(cbi);
438 }
439 g_list_free(l->list);
440 g_free(l);
441 }

   
Visit the ZANavi Wiki