forked from angband/angband
-
Notifications
You must be signed in to change notification settings - Fork 0
/
game-event.c
168 lines (133 loc) · 3.41 KB
/
game-event.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
* File: game-event.c
* Purpose: Allows the registering of handlers to be told about game events.
*
* Copyright (c) 2007 Antony Sidwell
*
* This work is free software; you can redistribute it and/or modify it
* under the terms of either:
*
* a) the GNU General Public License as published by the Free Software
* Foundation, version 2, or
*
* b) the "Angband licence":
* This software may be copied and distributed for educational, research,
* and not for profit purposes provided that this copyright and statement
* are included in all such copies. Other copyrights may also apply.
*/
#include <assert.h>
#include "z-virt.h"
#include "game-event.h"
struct event_handler_entry
{
struct event_handler_entry *next;
game_event_handler *fn;
void *user;
};
struct event_handler_entry *event_handlers[N_GAME_EVENTS];
static void game_event_dispatch(game_event_type type, game_event_data *data)
{
struct event_handler_entry *this = event_handlers[type];
/*
* Send the word out to all interested event handlers.
*/
while (this)
{
/* Call the handler with the relevant data */
this->fn(type, data, this->user);
this = this->next;
}
}
void event_add_handler(game_event_type type, game_event_handler *fn, void *user)
{
struct event_handler_entry *new;
assert(fn != NULL);
/* Make a new entry */
new = mem_alloc(sizeof *new);
new->fn = fn;
new->user = user;
/* Add it to the head of the appropriate list */
new->next = event_handlers[type];
event_handlers[type] = new;
}
void event_remove_handler(game_event_type type, game_event_handler *fn, void *user)
{
struct event_handler_entry *prev = NULL;
struct event_handler_entry *this = event_handlers[type];
/* Look for the entry in the list */
while (this)
{
/* Check if this is the entry we want to remove */
if (this->fn == fn && this->user == user)
{
if (!prev)
{
event_handlers[type] = this->next;
}
else
{
prev->next = this->next;
}
mem_free(this);
return;
}
prev = this;
this = this->next;
}
}
void event_remove_all_handlers(void)
{
int type;
struct event_handler_entry *handler, *next;
for (type = 0; type < N_GAME_EVENTS; type++) {
handler = event_handlers[type];
while (handler) {
next = handler->next;
mem_free(handler);
handler = next;
}
event_handlers[type] = NULL;
}
}
void event_add_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
{
size_t i;
for (i = 0; i < n_types; i++)
event_add_handler(type[i], fn, user);
}
void event_remove_handler_set(game_event_type *type, size_t n_types, game_event_handler *fn, void *user)
{
size_t i;
for (i = 0; i < n_types; i++)
event_remove_handler(type[i], fn, user);
}
void event_signal(game_event_type type)
{
game_event_dispatch(type, NULL);
}
void event_signal_flag(game_event_type type, bool flag)
{
game_event_data data;
data.flag = flag;
game_event_dispatch(type, &data);
}
void event_signal_point(game_event_type type, int x, int y)
{
game_event_data data;
data.point.x = x;
data.point.y = y;
game_event_dispatch(type, &data);
}
void event_signal_string(game_event_type type, const char *s)
{
game_event_data data;
data.string = s;
game_event_dispatch(type, &data);
}
void event_signal_birthpoints(int stats[6], int remaining)
{
game_event_data data;
data.birthstats.stats = stats;
data.birthstats.remaining = remaining;
game_event_dispatch(EVENT_BIRTHPOINTS, &data);
}