Fix:Core:Replace g_warning with dbg(0, some wince fixes
[navit-package] / navit / callback.c
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(void (*func)(void), int pcount, void **p)
64 {
65         return callback_new_attr(func, attr_none, pcount, p);
66 }
67
68 void
69 callback_destroy(struct callback *cb)
70 {
71         g_free(cb);
72 }
73
74 void
75 callback_set_arg(struct callback *cb, int arg, void *p)
76 {
77         if (arg < 0 || arg > cb->pcount)
78                 return;
79         cb->p[arg]=p;
80 }
81
82 void
83 callback_list_add(struct callback_list *l, struct callback *cb)
84 {
85         l->list=g_list_prepend(l->list, cb);
86 }
87
88
89 struct callback *
90 callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p)
91 {
92         struct callback *ret;
93         
94         ret=callback_new(func, pcount, p);      
95         callback_list_add(l, ret);
96         return ret;
97 }
98
99 void
100 callback_list_remove(struct callback_list *l, struct callback *cb)
101 {
102         l->list=g_list_remove(l->list, cb);
103 }
104
105 void
106 callback_list_remove_destroy(struct callback_list *l, struct callback *cb)
107 {
108         callback_list_remove(l, cb);
109         g_free(cb);
110 }
111
112 void
113 callback_call(struct callback *cb, int pcount, void **p)
114 {
115         int i;
116         void *pf[8];
117         if (! cb)
118                 return;
119         if (cb->pcount + pcount <= 8) {
120                 dbg(1,"cb->pcount=%d\n", cb->pcount);
121                 if (cb->pcount && cb->p) 
122                         dbg(1,"cb->p[0]=%p\n", cb->p[0]);
123                 dbg(1,"pcount=%d\n", pcount);
124                 if (pcount && p) 
125                         dbg(1,"p[0]=%p\n", p[0]);
126                 for (i = 0 ; i < cb->pcount ; i++) 
127                         pf[i]=cb->p[i];
128                 for (i = 0 ; i < pcount ; i++)
129                         pf[i+cb->pcount]=p[i];
130                 switch (cb->pcount+pcount) {
131                 case 8:
132                         cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]);
133                         break;
134                 case 7:
135                         cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]);
136                         break;
137                 case 6:
138                         cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5]);
139                         break;
140                 case 5:
141                         cb->func(pf[0],pf[1],pf[2],pf[3],pf[4]);
142                         break;
143                 case 4:
144                         cb->func(pf[0],pf[1],pf[2],pf[3]);
145                         break;
146                 case 3:
147                         cb->func(pf[0],pf[1],pf[2]);
148                         break;
149                 case 2:
150                         cb->func(pf[0],pf[1]);
151                         break;
152                 case 1:
153                         cb->func(pf[0]);
154                         break;
155                 case 0:
156                         cb->func();
157                         break;
158                 }
159         } else {
160                 dbg(0,"too many parameters for callback (%d+%d)\n", cb->pcount, pcount);
161         }
162 }
163
164 void
165 callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p)
166 {
167         GList *cbi;
168         struct callback *cb;
169
170         cbi=l->list;
171         while (cbi) {
172                 cb=cbi->data;
173                 if (type == attr_any || cb->type == attr_any || cb->type == type)
174                         callback_call(cb, pcount, p);
175                 cbi=g_list_next(cbi);
176         }
177         
178 }
179
180 void
181 callback_list_call(struct callback_list *l, int pcount, void **p)
182 {
183         callback_list_call_attr(l, attr_any, pcount, p);
184 }
185
186
187 void 
188 callback_list_destroy(struct callback_list *l)
189 {
190         GList *cbi;
191         cbi=l->list;
192         while (cbi) {
193                 g_free(cbi->data);
194                 cbi=g_list_next(cbi);
195         }
196         g_list_free(l->list);
197         g_free(l);
198 }