filename | src/hook.h |
changeset | 1034:7044e01148f0 |
prev | 1021:848db285a184 |
author | nkeynes |
date | Tue Feb 28 17:25:26 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Implement display output for the GLES2 case (no fixed function rendering) |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
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 like 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_HOOKS0( name ) FOREACH_HOOK(h,name) { h->fn(h->user_data); }
50 #define CALL_HOOKS( name, args... ) FOREACH_HOOK(h, name) { h->fn(args, h->user_data); }
52 #define DEFINE_HOOK( name, fn_type ) \
53 struct name##_hook_struct { \
54 fn_type fn; \
55 void *user_data; \
56 struct name##_hook_struct *next; \
57 } *name##_hook_list = NULL; \
58 void register_##name( fn_type fn, void *user_data ) { \
59 struct name##_hook_struct *h = malloc(sizeof(struct name##_hook_struct)); \
60 assert(h != NULL); \
61 h->fn = fn; \
62 h->user_data = user_data; \
63 h->next = name##_hook_list; \
64 name##_hook_list = h; \
65 } \
66 void unregister_##name( fn_type fn, void *user_data ) { \
67 struct name##_hook_struct *last = NULL, *h = name##_hook_list; \
68 while( h != NULL ) { \
69 if( h->fn == fn && h->user_data == user_data ) { \
70 if( last == NULL ) { \
71 name##_hook_list = h->next; \
72 } else { \
73 last->next = h->next; \
74 } \
75 free( h ); \
76 } \
77 last = h; \
78 h = h->next; \
79 }\
80 }
83 #endif /* !lxdream_hook_H */
.