5 #include "../core/error.h"
10 #define HF_CONTIGUOUS 0x01
13 HookCallback callback
;
19 typedef struct HookHead
{
26 static HookHead hooks
[HOOKMAX
];
27 static int dirtyhooks
[HOOKMAX
];
28 static int dirtyhookcount
;
30 unsigned int hookqueuelength
= 0;
32 static void defraghook(HookHead
*h
);
33 static void markdirty(int hook
);
38 int registerhook(int hooknum
, HookCallback callback
) {
39 return registerpriorityhook(hooknum
, callback
, PRIORITY_DEFAULT
);
42 int registerpriorityhook(int hooknum
, HookCallback callback
, long priority
) {
49 if(hookqueuelength
> 0)
50 Error("core", ERR_WARNING
, "Attempting to register hook %d inside a hook queue: %p", hooknum
, callback
);
52 for(pred
=NULL
,h
=&hooks
[hooknum
],hp
=h
->head
;hp
;hp
=hp
->next
) {
53 if(hp
->callback
==callback
)
55 if(priority
>=hp
->priority
)
59 n
= malloc(sizeof(Hook
));
60 n
->priority
= priority
;
61 n
->callback
= callback
;
81 int deregisterhook(int hooknum
, HookCallback callback
) {
88 if(hookqueuelength
> 0)
89 Error("core", ERR_WARNING
, "Attempting to deregister hook %d inside a hook queue: %p", hooknum
, callback
);
91 for(h
=&hooks
[hooknum
],hp
=h
->head
;hp
;hp
=hp
->next
) {
92 if(hp
->callback
==callback
) {
103 void triggerhook(int hooknum
, void *arg
) {
111 for(hp
=hooks
[hooknum
].head
;hp
;hp
=hp
->next
) {
113 (hp
->callback
)(hooknum
, arg
);
117 for(i
=0;i
<dirtyhookcount
;i
++) {
118 defraghook(&hooks
[dirtyhooks
[i
]]);
122 if (!hookqueuelength
&& hooknum
!=HOOK_CORE_ENDOFHOOKSQUEUE
)
123 triggerhook(HOOK_CORE_ENDOFHOOKSQUEUE
, 0);
126 static void markdirty(int hook
) {
127 if(hooks
[hook
].dirty
)
130 hooks
[hook
].dirty
= 1;
131 dirtyhooks
[dirtyhookcount
++] = hook
;
134 /* Non compacting version
135 static void defraghook(HookHead *h) {
138 for(pp=NULL,hp=h->head;hp;hp=np) {
140 if(hp->callback==NULL) {
162 static void defraghook(HookHead
*h
) {
168 nstart
= n
= malloc(sizeof(Hook
) * h
->alive
);
173 for(pp
=NULL
,hp
=h
->head
;hp
;hp
=np
) {
175 if(!contig
&& (hp
->flags
& HF_CONTIGUOUS
))
178 if(hp
->callback
==NULL
) {
179 if(!(hp
->flags
& HF_CONTIGUOUS
))
182 memcpy(n
, hp
, sizeof(Hook
));
184 n
->flags
|=HF_CONTIGUOUS
;
195 assert(!(nstart
&& !pp
) && !(!nstart
&& pp
));