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