More cleanups of dead code
[notion.git] / libmainloop / hooks.c
blob2ec4b346c9dbc25c55524ab442a504afdeb0cf38
1 /*
2 * ion/mainloop/hooks.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <libtu/types.h>
10 #include <libtu/misc.h>
11 #include <libtu/dlist.h>
12 #include <libtu/output.h>
13 #include <libtu/rb.h>
14 #include <libtu/objp.h>
15 #include <libtu/locale.h>
16 #include <libextl/extl.h>
17 #include "hooks.h"
20 EXTL_EXPORT
21 IMPLCLASS(WHook, Obj, hook_deinit, NULL);
23 static Rb_node named_hooks=NULL;
26 /*{{{ Named hooks */
29 /* If hk==NULL to register, new is attempted to be created. */
30 WHook *mainloop_register_hook(const char *name, WHook *hk)
32 char *nnm;
34 if(hk==NULL)
35 return NULL;
37 if(named_hooks==NULL){
38 named_hooks=make_rb();
39 if(named_hooks==NULL)
40 return NULL;
43 nnm=scopy(name);
45 if(nnm==NULL)
46 return NULL;
48 if(!rb_insert(named_hooks, nnm, hk)){
49 free(nnm);
50 destroy_obj((Obj*)hk);
53 return hk;
57 WHook *mainloop_unregister_hook(const char *name, WHook *hk)
59 bool found=FALSE;
60 Rb_node node;
62 if(named_hooks==NULL)
63 return NULL;
65 if(hk==NULL){
66 assert(name!=NULL);
67 node=rb_find_key_n(named_hooks, name, &found);
68 }else{
69 rb_traverse(node, named_hooks){
70 if((WHook*)rb_val(node)==hk){
71 found=TRUE;
72 break;
77 if(found){
78 hk=(WHook*)rb_val(node);
79 free((char*)node->k.key);
80 rb_delete_node(node);
83 return hk;
87 /*EXTL_DOC
88 * Find named hook \var{name}.
90 EXTL_SAFE
91 EXTL_EXPORT
92 WHook *mainloop_get_hook(const char *name)
94 if(name==NULL)
95 return NULL;
97 if(named_hooks!=NULL){
98 bool found=FALSE;
99 Rb_node node=rb_find_key_n(named_hooks, name, &found);
100 if(found)
101 return (WHook*)rb_val(node);
104 return NULL;
108 /*}}}*/
111 /*{{{ Init/deinit */
114 static void destroy_item(WHook *hk, WHookItem *item)
116 if(item->fn==NULL)
117 extl_unref_fn(item->efn);
118 UNLINK_ITEM(hk->items, item, next, prev);
119 free(item);
123 static WHookItem *create_item(WHook *hk)
125 WHookItem *item=ALLOC(WHookItem);
126 if(item!=NULL){
127 LINK_ITEM_FIRST(hk->items, item, next, prev);
128 item->fn=NULL;
129 item->efn=extl_fn_none();
132 return item;
136 bool hook_init(WHook *hk)
138 hk->items=NULL;
139 return TRUE;
143 WHook *create_hook()
145 CREATEOBJ_IMPL(WHook, hook, (p));
149 void hook_deinit(WHook *hk)
151 mainloop_unregister_hook(NULL, hk);
152 while(hk->items!=NULL)
153 destroy_item(hk, hk->items);
157 /*}}}*/
160 /*{{{ Find/add/remove */
163 WHookItem *hook_find(WHook *hk, WHookDummy *fn)
165 WHookItem *hi;
167 for(hi=hk->items; hi!=NULL; hi=hi->next){
168 if(hi->fn==fn)
169 return hi;
172 return NULL;
176 WHookItem *hook_find_extl(WHook *hk, ExtlFn efn)
178 WHookItem *hi;
180 for(hi=hk->items; hi!=NULL; hi=hi->next){
181 if(extl_fn_eq(hi->efn, efn))
182 return hi;
185 return NULL;
189 /*EXTL_DOC
190 * Is \var{fn} hooked to hook \var{hk}?
192 EXTL_SAFE
193 EXTL_EXPORT_MEMBER
194 bool hook_listed(WHook *hk, ExtlFn efn)
196 return hook_find_extl(hk, efn)!=NULL;
200 bool hook_add(WHook *hk, WHookDummy *fn)
202 WHookItem *item;
204 if(hook_find(hk, fn))
205 return FALSE;
207 item=create_item(hk);
208 if(item==NULL)
209 return FALSE;
210 item->fn=fn;
211 return TRUE;
215 /*EXTL_DOC
216 * Add \var{efn} to the list of functions to be called when the
217 * hook \var{hk} is triggered.
219 EXTL_EXPORT_AS(WHook, add)
220 bool hook_add_extl(WHook *hk, ExtlFn efn)
222 WHookItem *item;
224 if(efn==extl_fn_none()){
225 warn(TR("No function given."));
226 return FALSE;
229 if(hook_find_extl(hk, efn))
230 return FALSE;
232 item=create_item(hk);
234 if(item==NULL)
235 return FALSE;
237 item->efn=extl_ref_fn(efn);
239 return TRUE;
243 bool hook_remove(WHook *hk, WHookDummy *fn)
245 WHookItem *item=hook_find(hk, fn);
246 if(item!=NULL)
247 destroy_item(hk, item);
248 return (item!=NULL);
252 /*EXTL_DOC
253 * Remove \var{efn} from the list of functions to be called when the
254 * hook \var{hk} is triggered.
256 EXTL_EXPORT_AS(WHook, remove)
257 bool hook_remove_extl(WHook *hk, ExtlFn efn)
259 WHookItem *item=hook_find_extl(hk, efn);
260 if(item!=NULL)
261 destroy_item(hk, item);
262 return (item!=NULL);
266 /*}}}*/
269 /*{{{ Basic marshallers */
272 static bool marshall_v(WHookDummy *fn, void *param)
274 fn();
275 return TRUE;
279 static bool marshall_extl_v(ExtlFn fn, void *param)
281 extl_call(fn, NULL, NULL);
282 return TRUE;
286 static bool marshall_o(WHookDummy *fn, void *param)
288 fn((Obj*)param);
289 return TRUE;
293 static bool marshall_extl_o(ExtlFn fn, void *param)
295 return extl_call(fn, "o", NULL, (Obj*)param);
299 static bool marshall_p(WHookDummy *fn, void *param)
301 fn(param);
302 return TRUE;
306 static bool marshall_alt_v(bool (*fn)(), void *param)
308 return fn();
312 static bool marshall_extl_alt_v(ExtlFn fn, void *param)
314 bool ret=FALSE;
315 extl_call(fn, NULL, "b", &ret);
316 return ret;
320 static bool marshall_alt_o(bool (*fn)(), void *param)
322 return fn((Obj*)param);
326 static bool marshall_extl_alt_o(ExtlFn fn, void *param)
328 bool ret=FALSE;
329 extl_call(fn, "o", "b", (Obj*)param, &ret);
330 return ret;
334 static bool marshall_alt_p(bool (*fn)(), void *param)
336 return fn(param);
340 /*}}}*/
343 /*{{{ Call */
346 void hook_call(const WHook *hk, void *p,
347 WHookMarshall *m, WHookMarshallExtl *em)
349 WHookItem *hi, *next;
351 for(hi=hk->items; hi!=NULL; hi=next){
352 next=hi->next;
353 if(hi->fn!=NULL)
354 m(hi->fn, p);
355 else if(em!=NULL)
356 em(hi->efn, p);
361 bool hook_call_alt(const WHook *hk, void *p,
362 WHookMarshall *m, WHookMarshallExtl *em)
364 WHookItem *hi, *next;
365 bool ret=FALSE;
367 for(hi=hk->items; hi!=NULL; hi=next){
368 next=hi->next;
369 if(hi->fn!=NULL)
370 ret=m(hi->fn, p);
371 else if(em!=NULL)
372 ret=em(hi->efn, p);
373 if(ret)
374 break;
377 return ret;
381 void hook_call_v(const WHook *hk)
383 hook_call(hk, NULL, marshall_v, marshall_extl_v);
387 void hook_call_o(const WHook *hk, Obj *o)
389 hook_call(hk, o, marshall_o, marshall_extl_o);
393 void hook_call_p(const WHook *hk, void *p, WHookMarshallExtl *em)
395 hook_call(hk, p, marshall_p, em);
399 bool hook_call_alt_v(const WHook *hk)
401 return hook_call_alt(hk, NULL, (WHookMarshall*)marshall_alt_v,
402 (WHookMarshallExtl*)marshall_extl_alt_v);
406 bool hook_call_alt_o(const WHook *hk, Obj *o)
408 return hook_call_alt(hk, o, (WHookMarshall*)marshall_alt_o,
409 (WHookMarshallExtl*)marshall_extl_alt_o);
413 bool hook_call_alt_p(const WHook *hk, void *p, WHookMarshallExtl *em)
415 return hook_call_alt(hk, p, (WHookMarshall*)marshall_alt_p, em);
419 /*}}}*/