chiark / gitweb /
disorder.h: more consistent approach to function attributes
[disorder] / lib / eventdist.c
CommitLineData
eb5e0673
RK
1/*
2 * This file is part of DisOrder
3 * Copyright (C) 2008 Richard Kettlewell
4 *
e7eb3a27 5 * This program is free software: you can redistribute it and/or modify
eb5e0673 6 * it under the terms of the GNU General Public License as published by
e7eb3a27 7 * the Free Software Foundation, either version 3 of the License, or
eb5e0673 8 * (at your option) any later version.
e7eb3a27
RK
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 *
eb5e0673 15 * You should have received a copy of the GNU General Public License
e7eb3a27 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
eb5e0673 17 */
132a5a4a
RK
18/** @file lib/eventdist.c
19 * @brief Event distribution
20 */
eb5e0673
RK
21#include "common.h"
22
23#include "mem.h"
24#include "eventdist.h"
25#include "hash.h"
26
598b07b7
RK
27/** @brief Event data
28 *
29 * @c event_data structures form linked lists; one list per event and one node
30 * per handler.
31 */
eb5e0673 32struct event_data {
598b07b7 33 /** @brief Next handler */
eb5e0673 34 struct event_data *next;
598b07b7
RK
35
36 /** @brief Name of event */
eb5e0673 37 const char *event;
598b07b7
RK
38
39 /** @brief Handler callback */
eb5e0673 40 event_handler *callback;
598b07b7
RK
41
42 /** @brief Passed to @ref callback */
eb5e0673
RK
43 void *callbackdata;
44};
45
46static hash *events;
47
48/** @brief Register an event handler
49 * @param event Event type to handle
50 * @param callback Function to call when event occurs
51 * @param callbackdata Passed to @p callback
52 * @return Handle for this registration (for use with event_cancel())
53 */
54event_handle event_register(const char *event,
55 event_handler *callback,
56 void *callbackdata) {
57 static const struct event_data *null;
58 struct event_data *ed = xmalloc(sizeof *ed), **head;
59
60 if(!events)
61 events = hash_new(sizeof (struct event_data *));
62 if(!(head = hash_find(events, event))) {
63 hash_add(events, event, &null, HASH_INSERT);
64 head = hash_find(events, event);
65 }
66 ed->next = *head;
67 ed->event = xstrdup(event);
68 ed->callback = callback;
69 ed->callbackdata = callbackdata;
70 *head = ed;
71 return ed;
72}
73
74/** @brief Stop handling an event
75 * @param handle Registration to cancel (as returned from event_register())
76 *
77 * @p handle is allowed to be NULL.
78 */
79void event_cancel(event_handle handle) {
80 struct event_data **head, **edp;
81
82 if(!handle)
83 return;
84 assert(events);
85 head = hash_find(events, handle->event);
86 for(edp = head; *edp && *edp != handle; edp = &(*edp)->next)
87 ;
88 assert(*edp == handle);
89 *edp = handle->next;
90}
91
92/** @brief Raise an event
93 * @param event Event type to raise
94 * @param eventdata Event-specific data
95 */
96void event_raise(const char *event,
97 void *eventdata) {
98 struct event_data *ed, **head;
99 if(!events)
100 return;
101 if(!(head = hash_find(events, event)))
102 return;
103 for(ed = *head; ed; ed = ed->next)
104 ed->callback(event, eventdata, ed->callbackdata);
105}
106
107/*
108Local Variables:
109c-basic-offset:2
110comment-column:40
111fill-column:79
112indent-tabs-mode:nil
113End:
114*/