chiark / gitweb /
66eae8816969e26a37cefa693553fc4944212258
[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
19 #include "common.h"
20
21 #include "mem.h"
22 #include "eventdist.h"
23 #include "hash.h"
24
25 struct event_data {
26   struct event_data *next;
27   const char *event;
28   event_handler *callback;
29   void *callbackdata;
30 };
31
32 static hash *events;
33
34 /** @brief Register an event handler
35  * @param event Event type to handle
36  * @param callback Function to call when event occurs
37  * @param callbackdata Passed to @p callback
38  * @return Handle for this registration (for use with event_cancel())
39  */
40 event_handle event_register(const char *event,
41                             event_handler *callback,
42                             void *callbackdata) {
43   static const struct event_data *null;
44   struct event_data *ed = xmalloc(sizeof *ed), **head;
45
46   if(!events)
47     events = hash_new(sizeof (struct event_data *));
48   if(!(head = hash_find(events, event))) {
49     hash_add(events, event, &null, HASH_INSERT);
50     head = hash_find(events, event);
51   }
52   ed->next = *head;
53   ed->event = xstrdup(event);
54   ed->callback = callback;
55   ed->callbackdata = callbackdata;
56   *head = ed;
57   return ed;
58 }
59
60 /** @brief Stop handling an event
61  * @param handle Registration to cancel (as returned from event_register())
62  *
63  * @p handle is allowed to be NULL.
64  */
65 void event_cancel(event_handle handle) {
66   struct event_data **head, **edp;
67   
68   if(!handle)
69     return;
70   assert(events);
71   head = hash_find(events, handle->event);
72   for(edp = head; *edp && *edp != handle; edp = &(*edp)->next)
73     ;
74   assert(*edp == handle);
75   *edp = handle->next;
76 }
77
78 /** @brief Raise an event
79  * @param event Event type to raise
80  * @param eventdata Event-specific data
81  */
82 void event_raise(const char *event,
83                  void *eventdata) {
84   struct event_data *ed, **head;
85   if(!events)
86     return;
87   if(!(head = hash_find(events, event)))
88     return;
89   for(ed = *head; ed; ed = ed->next)
90     ed->callback(event, eventdata, ed->callbackdata);
91 }
92
93 /*
94 Local Variables:
95 c-basic-offset:2
96 comment-column:40
97 fill-column:79
98 indent-tabs-mode:nil
99 End:
100 */