filename | src/hook.h |
changeset | 678:35eb00945316 |
next | 681:1755a126b109 |
author | nkeynes |
date | Thu May 29 11:00:26 2008 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Split gdrom.h into public and private gddriver.h Reorganize gdrom mount to use a disc change hook |
view | annotate | diff | log | raw |
1 /**
2 * $Id: hook.h 662 2008-03-02 11:38:08Z nkeynes $
3 *
4 * This file defines some useful generic macros for hooks
5 *
6 * Copyright (c) 2008 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #ifndef lxdream_hook_H
20 #define lxdream_hook_H 1
22 #include <assert.h>
24 /**
25 * Hook functions are generally useful, so we'd let to limit the overhead (and
26 * opportunity for stupid bugs) by minimizing the amount of code involved. Glib
27 * has GHook (and of course signals), but they don't actually simplify anything
28 * at this level.
29 *
30 * Hence, the gratuitous macro abuse here.
31 *
32 * Usage:
33 *
34 * In header file:
35 *
36 * DECLARE_HOOK( hook_name, hook_fn_type );
37 *
38 * In implementation file:
39 *
40 * DEFINE_HOOK( hook_name, hook_fn_type );
41 *
42 */
43 #define DECLARE_HOOK( name, fn_type ) \
44 void register_##name( fn_type fn, void *user_data ); \
45 void unregister_##name( fn_type fn, void *user_data );
47 #define FOREACH_HOOK( h, name ) struct name##_hook_struct *h; for( h = name##_hook_list; h != NULL; h = h->next )
49 #define CALL_HOOKS( name, args... ) FOREACH_HOOK(h, name) { h->fn(args, h->user_data); }
51 #define DEFINE_HOOK( name, fn_type ) \
52 struct name##_hook_struct { \
53 fn_type fn; \
54 void *user_data; \
55 struct name##_hook_struct *next; \
56 } *name##_hook_list = NULL; \
57 void register_##name( fn_type fn, void *user_data ) { \
58 struct name##_hook_struct *h = malloc(sizeof(struct name##_hook_struct)); \
59 assert(h != NULL); \
60 h->fn = fn; \
61 h->user_data = user_data; \
62 h->next = name##_hook_list; \
63 name##_hook_list = h; \
64 } \
65 void unregister_##name( fn_type fn, void *user_data ) { \
66 struct name##_hook_struct *last = NULL, *h = name##_hook_list; \
67 while( h != NULL ) { \
68 if( h->fn == fn && h->user_data == user_data ) { \
69 if( last == NULL ) { \
70 name##_hook_list = h->next; \
71 } else { \
72 last->next = h->next; \
73 } \
74 free( h ); \
75 } \
76 last = h; \
77 h = h->next; \
78 }\
79 }
82 #endif /* !lxdream_hook_H */
.