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

Contents of /navit/navit/callback.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide 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 zoff99 2 /**
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