1 /*
2  * Contains functions for dealing with things that happen in the
3  * future.
4  *
5  * @(#)daemon.c	5.2 (Berkeley) 6/18/82
6  */
7 
8 #include "rogue.h"
9 #include "curses.h"
10 
11 #define EMPTY	0
12 #define FULL	1
13 #define DAEMON -1
14 #define MAXDAEMONS 20
15 
16 struct delayed_action {
17     int (*d_func)();
18     int d_arg;
19     int d_time;
20 } d_list[MAXDAEMONS];
21 
22 /*
23  * d_slot:
24  *	Find an empty slot in the daemon/fuse list
25  */
26 struct delayed_action *
27 d_slot()
28 {
29     register struct delayed_action *dev;
30 
31     for (dev = d_list; dev < &d_list[MAXDAEMONS]; dev++)
32 		if (dev->d_func == EMPTY)
33 		    return dev;
34 #ifdef DEBUG
35     debug("Ran out of fuse slots");
36 #endif
37     return NULL;
38 }
39 
40 /*
41  * find_slot:
42  *	Find a particular slot in the table
43  */
44 struct delayed_action *
45 find_slot(func)
46 int (*func)();
47 {
48     register struct delayed_action *dev;
49 
50     for (dev = d_list; dev < &d_list[MAXDAEMONS]; dev++)
51 	if (func == dev->d_func)
52 	    return dev;
53     return NULL;
54 }
55 
56 /*
57  * daemon:
58  *	Start a daemon, takes a function.
59  */
60 daemon(func, arg)
61 int (*func)(), arg;
62 {
63     register struct delayed_action *dev;
64 
65     dev = d_slot();
66     dev->d_func = func;
67     dev->d_arg = arg;
68     dev->d_time = DAEMON;
69 }
70 
71 /*
72  * do_daemons:
73  *	Run all the daemons, passing the argument to the function.
74  */
75 do_daemons()
76 {
77     register struct delayed_action *dev;
78 
79     /*
80      * Loop through the devil list
81      */
82     for (dev = d_list; dev < &d_list[MAXDAEMONS]; dev++)
83 	/*
84 	 * Executing each one, giving it the proper arguments
85 	 */
86 	if (dev->d_time == DAEMON && dev->d_func != EMPTY)
87 	    (*dev->d_func)(dev->d_arg);
88 }
89 
90 /*
91  * fuse:
92  *	Start a fuse to go off in a certain number of turns
93  */
94 fuse(func, arg, time)
95 int (*func)(), arg, time;
96 {
97     register struct delayed_action *wire;
98 
99     wire = d_slot();
100     wire->d_func = func;
101     wire->d_arg = arg;
102     wire->d_time = time;
103 }
104 
105 /*
106  * lengthen:
107  *	Increase the time until a fuse goes off
108  */
109 lengthen(func, xtime)
110 int (*func)();
111 int xtime;
112 {
113     register struct delayed_action *wire;
114 
115     if ((wire = find_slot(func)) == NULL)
116 	return;
117     wire->d_time += xtime;
118 }
119 
120 /*
121  * extinguish:
122  *	Put out a fuse
123  */
124 extinguish(func)
125 int (*func)();
126 {
127     register struct delayed_action *wire;
128 
129     if ((wire = find_slot(func)) == NULL)
130 	return;
131     wire->d_func = EMPTY;
132 }
133 
134 /*
135  * do_fuses:
136  *	Decrement counters and start needed fuses
137  */
138 do_fuses()
139 {
140     register struct delayed_action *wire;
141 
142     /*
143      * Step though the list
144      */
145     for (wire = d_list; wire < &d_list[MAXDAEMONS]; wire++) {
146 	/*
147 	 * Decrementing counters and starting things we want.  We also need
148 	 * to remove the fuse from the list once it has gone off.
149 	 */
150 		if (wire->d_func != EMPTY && wire->d_time > 0 && --wire->d_time == 0)
151 		{
152 		    (*wire->d_func)(wire->d_arg);
153 		    wire->d_func = EMPTY;
154 		}
155 	}
156 }
157 