root/trunk/src/game-event.c

Revision 817, 4.0 kB (checked in by ajps, 2 months ago)

Proper fix for #413 (segfaulting in game-event.c).

Line 
1 /*
2  * File: ui-event.c
3  * Purpose: Allows the registering of handlers to be told about ui "events",
4  *          and the game to signal these events to the UI.
5  *
6  * Copyright (c) 2007 Antony Sidwell
7  *
8  * This work is free software; you can redistribute it and/or modify it
9  * under the terms of either:
10  *
11  * a) the GNU General Public License as published by the Free Software
12  *    Foundation, version 2, or
13  *
14  * b) the "Angband licence":
15  *    This software may be copied and distributed for educational, research,
16  *    and not for profit purposes provided that this copyright and statement
17  *    are included in all such copies.  Other copyrights may also apply.
18  */
19
20 #include <assert.h>
21 #include "z-virt.h"
22 #include "game-event.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 struct event_handler_entry *event_handlers[N_GAME_EVENTS];
32
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
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
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
93 void event_add_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
94 {
95         int i;
96
97         for (i = 0; i < n_types; i++)
98         {
99                 event_add_handler(type[i], fn, user);
100         }
101 }
102
103 void event_remove_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
104 {
105         int i;
106
107         for (i = 0; i < n_types; i++)
108         {
109                 event_remove_handler(type[i], fn, user);
110         }
111 }
112
113
114
115
116 void event_signal(game_event_type type)
117 {
118         game_event_dispatch(type, NULL);
119 }
120
121
122 void event_signal_point(game_event_type type, int x, int y)
123 {
124         game_event_data data;
125         data.point.x = x;
126         data.point.y = y;
127
128         game_event_dispatch(type, &data);
129 }
130
131
132 void event_signal_string(game_event_type type, const char *s)
133 {
134         game_event_data data;
135         data.string = s;
136
137         game_event_dispatch(type, &data);
138 }
139
140
141 void event_signal_birthstage_question(enum birth_stage stage, const char *hint, int n_choices, int initial_choice, const char *choices[], const char *helptexts[])
142 {
143         game_event_data data;
144
145         data.birthstage.stage = stage;
146         data.birthstage.hint = hint;
147         data.birthstage.n_choices = n_choices;
148         data.birthstage.initial_choice = initial_choice;
149         data.birthstage.choices = choices;
150         data.birthstage.helptexts = helptexts;
151
152         game_event_dispatch(EVENT_BIRTHSTAGE, &data);
153 }
154
155 void event_signal_birthstage(enum birth_stage stage, void *xtra)
156 {
157         game_event_data data;
158
159         data.birthstage.stage = stage;
160         data.birthstage.xtra = xtra;
161
162         game_event_dispatch(EVENT_BIRTHSTAGE, &data);
163 }
164
165 void event_signal_birthstats(int stats[6], int remaining)
166 {
167         game_event_data data;
168
169         data.birthstats.stats = stats;
170         data.birthstats.remaining = remaining;
171
172         game_event_dispatch(EVENT_BIRTHSTATS, &data);
173 }
174
175
176 void event_signal_birthautoroller(int limits[6], int matches[6], int current[6], unsigned long round)
177 {
178         game_event_data data;
179
180         data.birthautoroll.limits = limits;
181         data.birthautoroll.matches = matches;
182         data.birthautoroll.current = current;
183         data.birthautoroll.round = round;
184
185         game_event_dispatch(EVENT_BIRTHAUTOROLLER, &data);
186 }
Note: See TracBrowser for help on using the browser.