Search
lxdream.org :: lxdream/src/hook.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/hook.h
changeset 681:1755a126b109
prev678:35eb00945316
next968:6fb1481859a4
author nkeynes
date Sun Aug 24 01:43:17 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Correct generated UNDEF() => UNDEF(ir) for consistency with UNIMP(ir)
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 */
.