… | |
… | |
21 | #include <string.h> |
21 | #include <string.h> |
22 | #include "item.h" |
22 | #include "item.h" |
23 | #include "debug.h" |
23 | #include "debug.h" |
24 | #include "callback.h" |
24 | #include "callback.h" |
25 | |
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 | |
26 | |
38 | struct callback_list * |
27 | struct callback_list * |
39 | callback_list_new(void) |
28 | callback_list_new(void) |
40 | { |
29 | { |
41 | struct callback_list *ret=g_new0(struct callback_list, 1); |
30 | struct callback_list *ret=g_new0(struct callback_list, 1); |
… | |
… | |
51 | |
40 | |
52 | ret=g_malloc0(sizeof(struct callback)+pcount*sizeof(void *)); |
41 | ret=g_malloc0(sizeof(struct callback)+pcount*sizeof(void *)); |
53 | ret->func=func; |
42 | ret->func=func; |
54 | ret->pcount=pcount; |
43 | ret->pcount=pcount; |
55 | ret->type=type; |
44 | ret->type=type; |
56 | for (i = 0 ; i < pcount ; i++) { |
45 | for (i = 0 ; i < pcount ; i++) |
|
|
46 | { |
57 | ret->p[i]=p[i]; |
47 | ret->p[i]=p[i]; |
58 | } |
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 | |
59 | return ret; |
64 | return ret; |
60 | } |
65 | } |
61 | |
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 | |
62 | struct callback * |
121 | struct callback * |
63 | callback_new_attr_args(void (*func)(void), enum attr_type type, int count, ...) |
122 | callback_new_attr_args(const char *module, const int mlen,const char *function, void (*func)(void), enum attr_type type, int count, ...) |
64 | { |
123 | { |
65 | int i; |
124 | int i; |
66 | void **p=g_alloca(sizeof(void*)*count); |
125 | void **p=g_alloca(sizeof(void*)*count); |
67 | va_list ap; |
126 | va_list ap; |
68 | va_start(ap, count); |
127 | va_start(ap, count); |
69 | for (i = 0 ; i < count ; i++) |
128 | for (i = 0 ; i < count ; i++) |
70 | p[i]=va_arg(ap, void *); |
129 | p[i]=va_arg(ap, void *); |
71 | va_end(ap); |
130 | va_end(ap); |
|
|
131 | |
72 | return callback_new_attr(func, type, count, p); |
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; |
73 | } |
137 | } |
74 | |
138 | |
75 | struct callback * |
139 | struct callback * |
76 | callback_new(void (*func)(void), int pcount, void **p) |
140 | callback_new(void (*func)(void), int pcount, void **p) |
77 | { |
141 | { |
78 | return callback_new_attr(func, attr_none, pcount, p); |
142 | return callback_new_attr(func, attr_none, pcount, p); |
79 | } |
143 | } |
80 | |
144 | |
81 | struct callback * |
145 | struct callback * |
82 | callback_new_args(void (*func)(void), int count, ...) |
146 | callback_new_args(const char *module, const int mlen,const char *function, void (*func)(void), int count, ...) |
83 | { |
147 | { |
84 | int i; |
148 | int i; |
85 | void **p=g_alloca(sizeof(void*)*count); |
149 | void **p=g_alloca(sizeof(void*)*count); |
86 | va_list ap; |
150 | va_list ap; |
87 | va_start(ap, count); |
151 | va_start(ap, count); |
88 | for (i = 0 ; i < count ; i++) |
152 | for (i = 0 ; i < count ; i++) |
89 | p[i]=va_arg(ap, void *); |
153 | p[i]=va_arg(ap, void *); |
90 | va_end(ap); |
154 | va_end(ap); |
|
|
155 | |
91 | return callback_new(func, count, p); |
156 | struct callback *ret = callback_new(func, count, p); |
92 | } |
|
|
93 | |
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 | |
94 | void |
164 | void |
95 | callback_destroy(struct callback *cb) |
165 | callback_destroy_real(const char *module, const int mlen,const char *function, struct callback *cb) |
96 | { |
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 | |
97 | g_free(cb); |
179 | g_free(cb); |
98 | } |
180 | } |
99 | |
181 | |
100 | void |
182 | void |
101 | callback_set_arg(struct callback *cb, int arg, void *p) |
183 | callback_set_arg(struct callback *cb, int arg, void *p) |
… | |
… | |
129 | } |
211 | } |
130 | |
212 | |
131 | void |
213 | void |
132 | callback_list_remove_destroy(struct callback_list *l, struct callback *cb) |
214 | callback_list_remove_destroy(struct callback_list *l, struct callback *cb) |
133 | { |
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 | |
134 | callback_list_remove(l, cb); |
232 | callback_list_remove(l, cb); |
|
|
233 | #ifdef NAVIT_CALLBACK_DEBUG_PRINT |
|
|
234 | callback_print_names(cb, "callback_list_remove_destroy"); |
|
|
235 | #endif |
135 | g_free(cb); |
236 | g_free(cb); |
136 | } |
237 | } |
137 | |
238 | |
138 | void |
239 | void |
139 | callback_call(struct callback *cb, int pcount, void **p) |
240 | callback_call(struct callback *cb, int pcount, void **p) |
140 | { |
241 | { |
141 | int i; |
242 | int i; |
142 | void *pf[8]; |
243 | void *pf[8]; |
|
|
244 | |
143 | if (! cb) |
245 | if (! cb) |
|
|
246 | { |
|
|
247 | #ifdef NAVIT_CALLBACK_DEBUG_PRINT |
|
|
248 | dbg(0,"callback_call:CB=NULL!!\n"); |
|
|
249 | #endif |
144 | return; |
250 | return; |
|
|
251 | } |
|
|
252 | |
|
|
253 | #ifdef NAVIT_CALLBACK_DEBUG_PRINT |
|
|
254 | callback_print_names(cb, "callback_call"); |
|
|
255 | #endif |
|
|
256 | |
145 | if (cb->pcount + pcount <= 8) { |
257 | if (cb->pcount + pcount <= 8) |
|
|
258 | { |
146 | dbg(1,"cb->pcount=%d\n", cb->pcount); |
259 | //dbg(1,"cb->pcount=%d\n", cb->pcount); |
147 | if (cb->pcount && cb->p) |
260 | if (cb->pcount && cb->p) |
|
|
261 | { |
148 | dbg(1,"cb->p[0]=%p\n", cb->p[0]); |
262 | //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 | } |
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 | |
154 | for (i = 0 ; i < cb->pcount ; i++) |
271 | for (i = 0 ; i < cb->pcount ; i++) |
155 | pf[i]=cb->p[i]; |
272 | pf[i]=cb->p[i]; |
|
|
273 | |
156 | for (i = 0 ; i < pcount ; i++) |
274 | for (i = 0 ; i < pcount ; i++) |
157 | pf[i+cb->pcount]=p[i]; |
275 | pf[i+cb->pcount]=p[i]; |
|
|
276 | |
158 | switch (cb->pcount+pcount) { |
277 | switch (cb->pcount+pcount) |
|
|
278 | { |
159 | case 8: |
279 | case 8: |
160 | cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]); |
280 | cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]); |
161 | break; |
281 | break; |
162 | case 7: |
282 | case 7: |
163 | cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]); |
283 | cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]); |
… | |
… | |
182 | break; |
302 | break; |
183 | case 0: |
303 | case 0: |
184 | cb->func(); |
304 | cb->func(); |
185 | break; |
305 | break; |
186 | } |
306 | } |
187 | } else { |
307 | } |
|
|
308 | else |
|
|
309 | { |
|
|
310 | #ifdef NAVIT_CALLBACK_DEBUG_PRINT |
188 | dbg(0,"too many parameters for callback (%d+%d)\n", cb->pcount, pcount); |
311 | dbg(0,"too many parameters for callback (%d+%d)\n", cb->pcount, pcount); |
|
|
312 | #endif |
189 | } |
313 | } |
190 | } |
314 | } |
191 | |
315 | |
192 | void |
316 | void |
193 | callback_call_args(struct callback *cb, int count, ...) |
317 | callback_call_args_real(const char *module, const int mlen,const char *function, struct callback *cb, int count, ...) |
194 | { |
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 | |
195 | int i; |
333 | int i; |
196 | void **p=g_alloca(sizeof(void*)*count); |
334 | void **p=g_alloca(sizeof(void*)*count); |
197 | va_list ap; |
335 | va_list ap; |
198 | va_start(ap, count); |
336 | va_start(ap, count); |
199 | for (i = 0 ; i < count ; i++) |
337 | for (i = 0 ; i < count ; i++) |
200 | p[i]=va_arg(ap, void *); |
338 | p[i]=va_arg(ap, void *); |
201 | va_end(ap); |
339 | va_end(ap); |
202 | callback_call(cb, count, p); |
340 | callback_call(cb, count, p); |
203 | } |
341 | } |
204 | |
342 | |
|
|
343 | |
205 | void |
344 | void |
206 | callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p) |
345 | callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p) |
207 | { |
346 | { |
208 | GList *cbi; |
347 | GList *cbi; |
209 | struct callback *cb; |
348 | struct callback *cb; |
210 | |
349 | |
211 | if (!l) { |
350 | if (!l) |
|
|
351 | { |
212 | return; |
352 | return; |
213 | } |
353 | } |
214 | |
354 | |
215 | cbi=l->list; |
355 | cbi=l->list; |
216 | while (cbi) { |
356 | while (cbi) |
|
|
357 | { |
217 | cb=cbi->data; |
358 | cb=cbi->data; |
218 | if (type == attr_any || cb->type == attr_any || cb->type == type) |
359 | if (type == attr_any || cb->type == attr_any || cb->type == type) |
|
|
360 | { |
219 | callback_call(cb, pcount, p); |
361 | callback_call(cb, pcount, p); |
|
|
362 | } |
220 | cbi=g_list_next(cbi); |
363 | cbi=g_list_next(cbi); |
221 | } |
364 | } |
222 | |
365 | |
223 | } |
366 | } |
224 | |
367 | |
225 | void |
368 | void |
226 | callback_list_call_attr_args(struct callback_list *cbl, enum attr_type type, int count, ...) |
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, ...) |
227 | { |
370 | { |
228 | int i; |
371 | int i; |
229 | void **p=g_alloca(sizeof(void*)*count); |
372 | void **p=g_alloca(sizeof(void*)*count); |
230 | va_list ap; |
373 | va_list ap; |
231 | va_start(ap, count); |
374 | va_start(ap, count); |
232 | for (i = 0 ; i < count ; i++) |
375 | for (i = 0 ; i < count ; i++) |
233 | p[i]=va_arg(ap, void *); |
376 | p[i]=va_arg(ap, void *); |
234 | va_end(ap); |
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 | |
235 | callback_list_call_attr(cbl, type, count, p); |
393 | callback_list_call_attr(cbl, type, count, p); |
236 | } |
394 | } |
237 | |
395 | |
238 | void |
396 | void |
239 | callback_list_call(struct callback_list *l, int pcount, void **p) |
397 | callback_list_call(struct callback_list *l, int pcount, void **p) |
240 | { |
398 | { |
241 | callback_list_call_attr(l, attr_any, pcount, p); |
399 | callback_list_call_attr(l, attr_any, pcount, p); |
242 | } |
400 | } |
243 | |
401 | |
244 | void |
402 | void |
245 | callback_list_call_args(struct callback_list *cbl, int count, ...) |
403 | callback_list_call_args(const char *module, const int mlen,const char *function, struct callback_list *cbl, int count, ...) |
246 | { |
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 | |
247 | int i; |
420 | int i; |
248 | void **p=g_alloca(sizeof(void*)*count); |
421 | void **p=g_alloca(sizeof(void*)*count); |
249 | va_list ap; |
422 | va_list ap; |
250 | va_start(ap, count); |
423 | va_start(ap, count); |
251 | for (i = 0 ; i < count ; i++) |
424 | for (i = 0 ; i < count ; i++) |