chiark / gitweb /
Memory management for hands-off reader
[disorder] / lib / eventdist.c
1 /*
2  * This file is part of DisOrder
3  * Copyright (C) 2008 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 /** @file lib/eventdist.c
19  * @brief Event distribution
20  */
21 #include "common.h"
22
23 #include "mem.h"
24 #include "eventdist.h"
25 #include "hash.h"
26
27 struct event_data {
28   struct event_data *next;
29   const char *event;
30   event_handler *callback;
31   void *callbackdata;
32 };
33
34 static hash *events;
35
36 /** @brief Register an event handler
37  * @param event Event type to handle
38  * @param callback Function to call when event occurs
39  * @param callbackdata Passed to @p callback
40  * @return Handle for this registration (for use with event_cancel())
41  */
42 event_handle event_register(const char *event,
43                             event_handler *callback,
44                             void *callbackdata) {
45   static const struct event_data *null;
46   struct event_data *ed = xmalloc(sizeof *ed), **head;
47
48   if(!events)
49     events = hash_new(sizeof (struct event_data *));
50   if(!(head = hash_find(events, event))) {
51     hash_add(events, event, &null, HASH_INSERT);
52     head = hash_find(events, event);
53   }
54   ed->next = *head;
55   ed->event = xstrdup(event);
56   ed->callback = callback;
57   ed->callbackdata = callbackdata;
58   *head = ed;
59   return ed;
60 }
61
62 /** @brief Stop handling an event
63  * @param handle Registration to cancel (as returned from event_register())
64  *
65  * @p handle is allowed to be NULL.
66  */
67 void event_cancel(event_handle handle) {
68   struct event_data **head, **edp;
69   
70   if(!handle)
71     return;
72   assert(events);
73   head = hash_find(events, handle->event);
74   for(edp = head; *edp && *edp != handle; edp = &(*edp)->next)
75     ;
76   assert(*edp == handle);
77   *edp = handle->next;
78 }
79
80 /** @brief Raise an event
81  * @param event Event type to raise
82  * @param eventdata Event-specific data
83  */
84 void event_raise(const char *event,
85                  void *eventdata) {
86   struct event_data *ed, **head;
87   if(!events)
88     return;
89   if(!(head = hash_find(events, event)))
90     return;
91   for(ed = *head; ed; ed = ed->next)
92     ed->callback(event, eventdata, ed->callbackdata);
93 }
94
95 /*
96 Local Variables:
97 c-basic-offset:2
98 comment-column:40
99 fill-column:79
100 indent-tabs-mode:nil
101 End:
102 */