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
)
38 if(named_hooks
==NULL
){
39 named_hooks
=make_rb();
49 if(!rb_insert(named_hooks
, nnm
, hk
)){
51 destroy_obj((Obj
*)hk
);
58 WHook
*mainloop_unregister_hook(const char *name
, WHook
*hk
)
68 node
=rb_find_key_n(named_hooks
, name
, &found
);
70 rb_traverse(node
, named_hooks
){
71 if((WHook
*)rb_val(node
)==hk
){
79 hk
=(WHook
*)rb_val(node
);
80 free((char*)node
->k
.key
);
89 * Find named hook \var{name}.
93 WHook
*mainloop_get_hook(const char *name
)
98 if(named_hooks
!=NULL
){
100 Rb_node node
=rb_find_key_n(named_hooks
, name
, &found
);
102 return (WHook
*)rb_val(node
);
115 static void destroy_item(WHook
*hk
, WHookItem
*item
)
118 extl_unref_fn(item
->efn
);
119 UNLINK_ITEM(hk
->items
, item
, next
, prev
);
124 static WHookItem
*create_item(WHook
*hk
)
126 WHookItem
*item
=ALLOC(WHookItem
);
128 LINK_ITEM_FIRST(hk
->items
, item
, next
, prev
);
130 item
->efn
=extl_fn_none();
137 bool hook_init(WHook
*hk
)
146 CREATEOBJ_IMPL(WHook
, hook
, (p
));
150 void hook_deinit(WHook
*hk
)
152 mainloop_unregister_hook(NULL
, hk
);
153 while(hk
->items
!=NULL
)
154 destroy_item(hk
, hk
->items
);
161 /*{{{ Find/add/remove */
164 WHookItem
*hook_find(WHook
*hk
, WHookDummy
*fn
)
168 for(hi
=hk
->items
; hi
!=NULL
; hi
=hi
->next
){
177 WHookItem
*hook_find_extl(WHook
*hk
, ExtlFn efn
)
181 for(hi
=hk
->items
; hi
!=NULL
; hi
=hi
->next
){
182 if(extl_fn_eq(hi
->efn
, efn
))
191 * Is \var{fn} hooked to hook \var{hk}?
195 bool hook_listed(WHook
*hk
, ExtlFn efn
)
197 return hook_find_extl(hk
, efn
)!=NULL
;
201 bool hook_add(WHook
*hk
, WHookDummy
*fn
)
205 if(hook_find(hk
, fn
))
208 item
=create_item(hk
);
217 * Add \var{efn} to the list of functions to be called when the
218 * hook \var{hk} is triggered.
220 EXTL_EXPORT_AS(WHook
, add
)
221 bool hook_add_extl(WHook
*hk
, ExtlFn efn
)
225 if(efn
==extl_fn_none()){
226 warn(TR("No function given."));
230 if(hook_find_extl(hk
, efn
))
233 item
=create_item(hk
);
238 item
->efn
=extl_ref_fn(efn
);
244 bool hook_remove(WHook
*hk
, WHookDummy
*fn
)
246 WHookItem
*item
=hook_find(hk
, fn
);
248 destroy_item(hk
, item
);
254 * Remove \var{efn} from the list of functions to be called when the
255 * hook \var{hk} is triggered.
257 EXTL_EXPORT_AS(WHook
, remove
)
258 bool hook_remove_extl(WHook
*hk
, ExtlFn efn
)
260 WHookItem
*item
=hook_find_extl(hk
, efn
);
262 destroy_item(hk
, item
);
270 /*{{{ Basic marshallers */
273 static bool marshall_v(WHookDummy
*fn
, void *param
)
280 static bool marshall_extl_v(ExtlFn fn
, void *param
)
282 extl_call(fn
, NULL
, NULL
);
287 static bool marshall_o(WHookDummy
*fn
, void *param
)
294 static bool marshall_extl_o(ExtlFn fn
, void *param
)
296 return extl_call(fn
, "o", NULL
, (Obj
*)param
);
300 static bool marshall_p(WHookDummy
*fn
, void *param
)
307 static bool marshall_alt_v(bool (*fn
)(), void *param
)
313 static bool marshall_extl_alt_v(ExtlFn fn
, void *param
)
316 extl_call(fn
, NULL
, "b", &ret
);
321 static bool marshall_alt_o(bool (*fn
)(), void *param
)
323 return fn((Obj
*)param
);
327 static bool marshall_extl_alt_o(ExtlFn fn
, void *param
)
330 extl_call(fn
, "o", "b", (Obj
*)param
, &ret
);
335 static bool marshall_alt_p(bool (*fn
)(), void *param
)
347 void hook_call(const WHook
*hk
, void *p
,
348 WHookMarshall
*m
, WHookMarshallExtl
*em
)
350 WHookItem
*hi
, *next
;
352 for(hi
=hk
->items
; hi
!=NULL
; hi
=next
){
362 bool hook_call_alt(const WHook
*hk
, void *p
,
363 WHookMarshall
*m
, WHookMarshallExtl
*em
)
365 WHookItem
*hi
, *next
;
368 for(hi
=hk
->items
; hi
!=NULL
; hi
=next
){
382 void hook_call_v(const WHook
*hk
)
384 hook_call(hk
, NULL
, marshall_v
, marshall_extl_v
);
388 void hook_call_o(const WHook
*hk
, Obj
*o
)
390 hook_call(hk
, o
, marshall_o
, marshall_extl_o
);
394 void hook_call_p(const WHook
*hk
, void *p
, WHookMarshallExtl
*em
)
396 hook_call(hk
, p
, marshall_p
, em
);
400 bool hook_call_alt_v(const WHook
*hk
)
402 return hook_call_alt(hk
, NULL
, (WHookMarshall
*)marshall_alt_v
,
403 (WHookMarshallExtl
*)marshall_extl_alt_v
);
407 bool hook_call_alt_o(const WHook
*hk
, Obj
*o
)
409 return hook_call_alt(hk
, o
, (WHookMarshall
*)marshall_alt_o
,
410 (WHookMarshallExtl
*)marshall_extl_alt_o
);
414 bool hook_call_alt_p(const WHook
*hk
, void *p
, WHookMarshallExtl
*em
)
416 return hook_call_alt(hk
, p
, (WHookMarshall
*)marshall_alt_p
, em
);