1 /**
2 * \file game-event.c
3 * \brief Allows the registering of handlers to be told about game events.
4 *
5 * Copyright (c) 2007 Antony Sidwell
6 *
7 * This work is free software; you can redistribute it and/or modify it
8 * under the terms of either:
9 *
10 * a) the GNU General Public License as published by the Free Software
11 * Foundation, version 2, or
12 *
13 * b) the "Angband licence":
14 * This software may be copied and distributed for educational, research,
15 * and not for profit purposes provided that this copyright and statement
16 * are included in all such copies. Other copyrights may also apply.
17 */
18
19 #include <assert.h>
20 #include "game-event.h"
21 #include "object.h"
22 #include "z-virt.h"
23
24 struct event_handler_entry
25 {
26 struct event_handler_entry *next;
27 game_event_handler *fn;
28 void *user;
29 };
30
31 static struct event_handler_entry *event_handlers[N_GAME_EVENTS];
32
game_event_dispatch(game_event_type type,game_event_data * data)33 static void game_event_dispatch(game_event_type type, game_event_data *data)
34 {
35 struct event_handler_entry *this = event_handlers[type];
36
37 /*
38 * Send the word out to all interested event handlers.
39 */
40 while (this)
41 {
42 /* Call the handler with the relevant data */
43 this->fn(type, data, this->user);
44 this = this->next;
45 }
46 }
47
event_add_handler(game_event_type type,game_event_handler * fn,void * user)48 void event_add_handler(game_event_type type, game_event_handler *fn, void *user)
49 {
50 struct event_handler_entry *new;
51
52 assert(fn != NULL);
53
54 /* Make a new entry */
55 new = mem_alloc(sizeof *new);
56 new->fn = fn;
57 new->user = user;
58
59 /* Add it to the head of the appropriate list */
60 new->next = event_handlers[type];
61 event_handlers[type] = new;
62 }
63
event_remove_handler(game_event_type type,game_event_handler * fn,void * user)64 void event_remove_handler(game_event_type type, game_event_handler *fn, void *user)
65 {
66 struct event_handler_entry *prev = NULL;
67 struct event_handler_entry *this = event_handlers[type];
68
69 /* Look for the entry in the list */
70 while (this)
71 {
72 /* Check if this is the entry we want to remove */
73 if (this->fn == fn && this->user == user)
74 {
75 if (!prev)
76 {
77 event_handlers[type] = this->next;
78 }
79 else
80 {
81 prev->next = this->next;
82 }
83
84 mem_free(this);
85 return;
86 }
87
88 prev = this;
89 this = this->next;
90 }
91 }
92
event_remove_handler_type(game_event_type type)93 void event_remove_handler_type(game_event_type type)
94 {
95 struct event_handler_entry *handler = event_handlers[type];
96
97 while (handler) {
98 struct event_handler_entry *next = handler->next;
99 mem_free(handler);
100 handler = next;
101 }
102 event_handlers[type] = NULL;
103 }
104
event_remove_all_handlers(void)105 void event_remove_all_handlers(void)
106 {
107 int type;
108 struct event_handler_entry *handler, *next;
109
110 for (type = 0; type < N_GAME_EVENTS; type++) {
111 handler = event_handlers[type];
112 while (handler) {
113 next = handler->next;
114 mem_free(handler);
115 handler = next;
116 }
117 event_handlers[type] = NULL;
118 }
119 }
120
event_add_handler_set(game_event_type * type,size_t n_types,game_event_handler * fn,void * user)121 void event_add_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
122 {
123 size_t i;
124
125 for (i = 0; i < n_types; i++)
126 event_add_handler(type[i], fn, user);
127 }
128
event_remove_handler_set(game_event_type * type,size_t n_types,game_event_handler * fn,void * user)129 void event_remove_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
130 {
131 size_t i;
132
133 for (i = 0; i < n_types; i++)
134 event_remove_handler(type[i], fn, user);
135 }
136
137
138
139
event_signal(game_event_type type)140 void event_signal(game_event_type type)
141 {
142 game_event_dispatch(type, NULL);
143 }
144
event_signal_flag(game_event_type type,bool flag)145 void event_signal_flag(game_event_type type, bool flag)
146 {
147 game_event_data data;
148 data.flag = flag;
149
150 game_event_dispatch(type, &data);
151 }
152
153
event_signal_point(game_event_type type,int x,int y)154 void event_signal_point(game_event_type type, int x, int y)
155 {
156 game_event_data data;
157 data.point.x = x;
158 data.point.y = y;
159
160 game_event_dispatch(type, &data);
161 }
162
163
event_signal_string(game_event_type type,const char * s)164 void event_signal_string(game_event_type type, const char *s)
165 {
166 game_event_data data;
167 data.string = s;
168
169 game_event_dispatch(type, &data);
170 }
171
event_signal_message(game_event_type type,int t,const char * s)172 void event_signal_message(game_event_type type, int t, const char *s)
173 {
174 game_event_data data;
175 memset(&data, 0, sizeof data);
176
177 data.message.type = t;
178 data.message.msg = s;
179
180 game_event_dispatch(type, &data);
181 }
182
event_signal_birthpoints(int stats[6],int remaining)183 void event_signal_birthpoints(int stats[6], int remaining)
184 {
185 game_event_data data;
186
187 data.birthstats.stats = stats;
188 data.birthstats.remaining = remaining;
189
190 game_event_dispatch(EVENT_BIRTHPOINTS, &data);
191 }
192
event_signal_blast(game_event_type type,int proj_type,int num_grids,int * distance_to_grid,bool drawing,bool * player_sees_grid,struct loc * blast_grid,struct loc centre)193 void event_signal_blast(game_event_type type,
194 int proj_type,
195 int num_grids,
196 int *distance_to_grid,
197 bool drawing,
198 bool *player_sees_grid,
199 struct loc *blast_grid,
200 struct loc centre)
201 {
202 game_event_data data;
203 data.explosion.proj_type = proj_type;
204 data.explosion.num_grids = num_grids;
205 data.explosion.distance_to_grid = distance_to_grid;
206 data.explosion.drawing = drawing;
207 data.explosion.player_sees_grid = player_sees_grid;
208 data.explosion.blast_grid = blast_grid;
209 data.explosion.centre = centre;
210
211 game_event_dispatch(type, &data);
212 }
213
event_signal_bolt(game_event_type type,int proj_type,bool drawing,bool seen,bool beam,int oy,int ox,int y,int x)214 void event_signal_bolt(game_event_type type,
215 int proj_type,
216 bool drawing,
217 bool seen,
218 bool beam,
219 int oy,
220 int ox,
221 int y,
222 int x)
223 {
224 game_event_data data;
225 data.bolt.proj_type = proj_type;
226 data.bolt.drawing = drawing;
227 data.bolt.seen = seen;
228 data.bolt.beam = beam;
229 data.bolt.oy = oy;
230 data.bolt.ox = ox;
231 data.bolt.y = y;
232 data.bolt.x = x;
233
234 game_event_dispatch(type, &data);
235 }
236
event_signal_missile(game_event_type type,struct object * obj,bool seen,int y,int x)237 void event_signal_missile(game_event_type type,
238 struct object *obj,
239 bool seen,
240 int y,
241 int x)
242 {
243 game_event_data data;
244 data.missile.obj = obj;
245 data.missile.seen = seen;
246 data.missile.y = y;
247 data.missile.x = x;
248
249 game_event_dispatch(type, &data);
250 }
251