4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
9 #include <libtu/types.h>
10 #include <libtu/misc.h>
11 #include <libtu/dlist.h>
12 #include <libtu/output.h>
14 #include <libtu/objp.h>
15 #include <libtu/locale.h>
16 #include <libextl/extl.h>
21 IMPLCLASS(WHook
, Obj
, hook_deinit
, NULL
);
23 static Rb_node named_hooks
=NULL
;
29 /* If hk==NULL to register, new is attempted to be created. */
30 WHook
*mainloop_register_hook(const char *name
, WHook
*hk
)
37 if(named_hooks
==NULL
){
38 named_hooks
=make_rb();
48 if(!rb_insert(named_hooks
, nnm
, hk
)){
50 destroy_obj((Obj
*)hk
);
57 WHook
*mainloop_unregister_hook(const char *name
, WHook
*hk
)
67 node
=rb_find_key_n(named_hooks
, name
, &found
);
69 rb_traverse(node
, named_hooks
){
70 if((WHook
*)rb_val(node
)==hk
){
78 hk
=(WHook
*)rb_val(node
);
79 free((char*)node
->k
.key
);
88 * Find named hook \var{name}.
92 WHook
*mainloop_get_hook(const char *name
)
97 if(named_hooks
!=NULL
){
99 Rb_node node
=rb_find_key_n(named_hooks
, name
, &found
);
101 return (WHook
*)rb_val(node
);
114 static void destroy_item(WHook
*hk
, WHookItem
*item
)
117 extl_unref_fn(item
->efn
);
118 UNLINK_ITEM(hk
->items
, item
, next
, prev
);
123 static WHookItem
*create_item(WHook
*hk
)
125 WHookItem
*item
=ALLOC(WHookItem
);
127 LINK_ITEM_FIRST(hk
->items
, item
, next
, prev
);
129 item
->efn
=extl_fn_none();
136 bool hook_init(WHook
*hk
)
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
);
160 /*{{{ Find/add/remove */
163 WHookItem
*hook_find(WHook
*hk
, WHookDummy
*fn
)
167 for(hi
=hk
->items
; hi
!=NULL
; hi
=hi
->next
){
176 WHookItem
*hook_find_extl(WHook
*hk
, ExtlFn efn
)
180 for(hi
=hk
->items
; hi
!=NULL
; hi
=hi
->next
){
181 if(extl_fn_eq(hi
->efn
, efn
))
190 * Is \var{fn} hooked to hook \var{hk}?
194 bool hook_listed(WHook
*hk
, ExtlFn efn
)
196 return hook_find_extl(hk
, efn
)!=NULL
;
200 bool hook_add(WHook
*hk
, WHookDummy
*fn
)
204 if(hook_find(hk
, fn
))
207 item
=create_item(hk
);
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
)
224 if(efn
==extl_fn_none()){
225 warn(TR("No function given."));
229 if(hook_find_extl(hk
, efn
))
232 item
=create_item(hk
);
237 item
->efn
=extl_ref_fn(efn
);
243 bool hook_remove(WHook
*hk
, WHookDummy
*fn
)
245 WHookItem
*item
=hook_find(hk
, fn
);
247 destroy_item(hk
, item
);
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
);
261 destroy_item(hk
, item
);
269 /*{{{ Basic marshallers */
272 static bool marshall_v(WHookDummy
*fn
, void *param
)
279 static bool marshall_extl_v(ExtlFn fn
, void *param
)
281 extl_call(fn
, NULL
, NULL
);
286 static bool marshall_o(WHookDummy
*fn
, void *param
)
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
)
306 static bool marshall_alt_v(bool (*fn
)(), void *param
)
312 static bool marshall_extl_alt_v(ExtlFn fn
, void *param
)
315 extl_call(fn
, NULL
, "b", &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
)
329 extl_call(fn
, "o", "b", (Obj
*)param
, &ret
);
334 static bool marshall_alt_p(bool (*fn
)(), void *param
)
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
){
361 bool hook_call_alt(const WHook
*hk
, void *p
,
362 WHookMarshall
*m
, WHookMarshallExtl
*em
)
364 WHookItem
*hi
, *next
;
367 for(hi
=hk
->items
; hi
!=NULL
; hi
=next
){
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
);