Search
lxdream.org :: lxdream/src/hook.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/hook.h
changeset 1034:7044e01148f0
prev1021:848db285a184
author nkeynes
date Wed Jul 04 12:01:31 2012 +1000 (11 years ago)
permissions -rw-r--r--
last change Remove use of extended regexes to make porting easier
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 */
.