]> jfr.im git - irc/quakenet/newserv.git/blob - core/hooks.c
merge
[irc/quakenet/newserv.git] / core / hooks.c
1 /* hooks.c */
2
3 #include "hooks.h"
4 #include <assert.h>
5 #include "../lib/array.h"
6 #include <stdlib.h>
7
8 array hooks[HOOKMAX];
9 unsigned int hookqueuelength;
10
11 void inithooks() {
12 int i;
13
14 hookqueuelength=0;
15 for (i=0;i<HOOKMAX;i++) {
16 array_init(&(hooks[i]),sizeof(HookCallback));
17 array_setlim1(&(hooks[i]),2);
18 array_setlim2(&(hooks[i]),2);
19 }
20 }
21
22 int registerhook(int hooknum, HookCallback callback) {
23 int i;
24 HookCallback *hcbs;
25
26 if (hooknum>HOOKMAX)
27 return 1;
28
29 hcbs=(HookCallback *)(hooks[hooknum].content);
30 for(i=0;i<hooks[hooknum].cursi;i++)
31 if(hcbs[i]==callback)
32 return 1;
33
34 /* If there is a previously blanked slot, go in there */
35 for(i=0;i<hooks[hooknum].cursi;i++) {
36 if(hcbs[i]==NULL) {
37 hcbs[i]=callback;
38 return 0;
39 }
40 }
41
42 i=array_getfreeslot(&hooks[hooknum]);
43 hcbs=(HookCallback *)(hooks[hooknum].content);
44 hcbs[i]=callback;
45
46 return 0;
47 }
48
49 int deregisterhook(int hooknum, HookCallback callback) {
50 int i;
51 HookCallback *hcbs;
52
53 if (hooknum>HOOKMAX)
54 return 1;
55
56 hcbs=(HookCallback *)(hooks[hooknum].content);
57
58 for(i=0;i<hooks[hooknum].cursi;i++)
59 if(hcbs[i]==callback) {
60 /* If there is an ongoing callback, don't actually delete from the
61 * array in case THIS hook is active */
62 if (hookqueuelength) {
63 hcbs[i]=NULL;
64 } else {
65 array_delslot(&(hooks[hooknum]),i);
66 }
67 return 0;
68 }
69
70 return 1;
71 }
72
73 void triggerhook(int hooknum, void *arg) {
74 int i;
75 HookCallback *hcbs;
76
77 if (hooknum>HOOKMAX)
78 return;
79
80 hookqueuelength++;
81 hcbs=(HookCallback *)(hooks[hooknum].content);
82 for (i=0;i<hooks[hooknum].cursi;i++) {
83 if (hcbs[i])
84 (hcbs[i])(hooknum, arg);
85 }
86 hookqueuelength--;
87
88 if (!hookqueuelength && hooknum!=HOOK_CORE_ENDOFHOOKSQUEUE)
89 triggerhook(HOOK_CORE_ENDOFHOOKSQUEUE, 0);
90 }