typedef struct _LttvHookClosure {
- LttvHook hook;
- void *hook_data;
+ LttvHook hook;
+ void *hook_data;
+ LttvHookPrio prio;
} LttvHookClosure;
+gint lttv_hooks_prio_compare(LttvHookClosure *a, LttvHookClosure *b)
+{
+ if(a->prio < b->prio) return -1;
+ if(a->prio > b->prio) return 1;
+ return 0;
+}
+
LttvHooks *lttv_hooks_new()
{
}
-void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data)
+void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data, LttvHookPrio p)
{
LttvHookClosure c;
c.hook = f;
c.hook_data = hook_data;
+ c.prio = p;
g_array_append_val(h,c);
+ g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare);
}
for(i = 0 ; i < list->len; i++) {
g_array_append_val(h,g_array_index(list, LttvHookClosure, i));
}
+ g_array_sort(h, (GCompareFunc)lttv_hooks_prio_compare);
}
}
-void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data)
+void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data,
+ LttvHookPrio *p)
{
LttvHookClosure *c;
+ if(i >= h->len)
+ {
+ *f = NULL;
+ *hook_data = NULL;
+ *p = 0;
+ return;
+ }
+
c = &g_array_index(h, LttvHookClosure, i);
*f = c->hook;
*hook_data = c->hook_data;
+ *p = c->prio;
}
g_array_remove_index(h, i);
}
-
gboolean lttv_hooks_call(LttvHooks *h, void *call_data)
{
gboolean ret, sum_ret = FALSE;
return FALSE;
}
+gboolean lttv_hooks_call_merge(LttvHooks *h1, void *call_data1,
+ LttvHooks *h2, void *call_data2)
+{
+ gboolean ret, sum_ret = FALSE;
+
+ LttvHookClosure *c1, *c2;
+
+ guint i, j;
+
+ if(h1 != NULL && h2 != NULL) {
+ for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ if(c1->prio <= c2->prio) {
+ ret = c1->hook(c1->hook_data,call_data1);
+ sum_ret = sum_ret || ret;
+ i++;
+ }
+ else {
+ ret = c2->hook(c2->hook_data,call_data2);
+ sum_ret = sum_ret || ret;
+ j++;
+ }
+ }
+ /* Finish the last list with hooks left */
+ for(;i < h1->len; i++) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ ret = c1->hook(c1->hook_data,call_data1);
+ sum_ret = sum_ret || ret;
+ }
+ for(;j < h2->len; j++) {
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ ret = c2->hook(c2->hook_data,call_data2);
+ sum_ret = sum_ret || ret;
+ }
+ }
+ else if(h1 != NULL && h2 == NULL) {
+ for(i = 0 ; i < h1->len ; i++) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ ret = c1->hook(c1->hook_data,call_data1);
+ sum_ret = sum_ret || ret;
+ }
+ }
+ else if(h1 == NULL && h2 != NULL) {
+ for(j = 0 ; j < h2->len ; j++) {
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ ret = c2->hook(c2->hook_data,call_data2);
+ sum_ret = sum_ret || ret;
+ }
+ }
+
+ return sum_ret;
+}
+
+gboolean lttv_hooks_call_check_merge(LttvHooks *h1, void *call_data1,
+ LttvHooks *h2, void *call_data2)
+{
+ LttvHookClosure *c1, *c2;
+
+ guint i, j;
+
+ if(h1 != NULL && h2 != NULL) {
+ for(i = 0, j = 0 ; i < h1->len && j < h2->len ;) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ if(c1->prio <= c2->prio) {
+ if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+ i++;
+ }
+ else {
+ if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+ j++;
+ }
+ }
+ /* Finish the last list with hooks left */
+ for(;i < h1->len; i++) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+ }
+ for(;j < h2->len; j++) {
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+ }
+ }
+ else if(h1 != NULL && h2 == NULL) {
+ for(i = 0 ; i < h1->len ; i++) {
+ c1 = &g_array_index(h1, LttvHookClosure, i);
+ if(c1->hook(c1->hook_data,call_data1)) return TRUE;
+ }
+ }
+ else if(h1 == NULL && h2 != NULL) {
+ for(j = 0 ; j < h2->len ; j++) {
+ c2 = &g_array_index(h2, LttvHookClosure, j);
+ if(c2->hook(c2->hook_data,call_data2)) return TRUE;
+ }
+ }
+
+ return FALSE;
+
+}
+
LttvHooksById *lttv_hooks_by_id_new()
{