PipeWire  0.3.66
hook.h
Go to the documentation of this file.
1 /* Simple Plugin API */
2 /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
3 /* SPDX-License-Identifier: MIT */
4 
5 #ifndef SPA_HOOK_H
6 #define SPA_HOOK_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 #include <spa/utils/defs.h>
13 #include <spa/utils/list.h>
14 
110 struct spa_callbacks {
111  const void *funcs;
112  void *data;
113 };
114 
116 #define SPA_CALLBACK_VERSION_MIN(c,v) ((c) && ((v) == 0 || (c)->version > (v)-1))
117 
119 #define SPA_CALLBACK_CHECK(c,m,v) (SPA_CALLBACK_VERSION_MIN(c,v) && (c)->m)
120 
125 #define SPA_CALLBACKS_INIT(_funcs,_data) ((struct spa_callbacks){ (_funcs), (_data), })
126 
129 struct spa_interface {
130  const char *type;
131  uint32_t version;
132  struct spa_callbacks cb;
133 };
134 
148 #define SPA_INTERFACE_INIT(_type,_version,_funcs,_data) \
149  ((struct spa_interface){ (_type), (_version), SPA_CALLBACKS_INIT(_funcs,_data), })
150 
156 #define spa_callbacks_call(callbacks,type,method,vers,...) \
157 ({ \
158  const type *_f = (const type *) (callbacks)->funcs; \
159  bool _res = SPA_CALLBACK_CHECK(_f,method,vers); \
160  if (SPA_LIKELY(_res)) \
161  _f->method((callbacks)->data, ## __VA_ARGS__); \
162  _res; \
163 })
164 
168 #define spa_callback_version_min(callbacks,type,vers) \
169 ({ \
170  const type *_f = (const type *) (callbacks)->funcs; \
171  SPA_CALLBACK_VERSION_MIN(_f,vers); \
172 })
173 
178 #define spa_callback_check(callbacks,type,method,vers) \
179 ({ \
180  const type *_f = (const type *) (callbacks)->funcs; \
181  SPA_CALLBACK_CHECK(_f,method,vers); \
182 })
183 
190 #define spa_callbacks_call_res(callbacks,type,res,method,vers,...) \
191 ({ \
192  const type *_f = (const type *) (callbacks)->funcs; \
193  if (SPA_LIKELY(SPA_CALLBACK_CHECK(_f,method,vers))) \
194  res = _f->method((callbacks)->data, ## __VA_ARGS__); \
195  res; \
196 })
197 
201 #define spa_interface_callback_version_min(iface,method_type,vers) \
202  spa_callback_version_min(&(iface)->cb, method_type, vers)
203 
208 #define spa_interface_callback_check(iface,method_type,method,vers) \
209  spa_callback_check(&(iface)->cb, method_type, method, vers)
210 
216 #define spa_interface_call(iface,method_type,method,vers,...) \
217  spa_callbacks_call(&(iface)->cb,method_type,method,vers,##__VA_ARGS__)
218 
226 #define spa_interface_call_res(iface,method_type,res,method,vers,...) \
227  spa_callbacks_call_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__)
228 
311 struct spa_hook_list {
312  struct spa_list list;
313 };
314 
315 
322 struct spa_hook {
323  struct spa_list link;
324  struct spa_callbacks cb;
327  void (*removed) (struct spa_hook *hook);
328  void *priv;
329 };
330 
332 static inline void spa_hook_list_init(struct spa_hook_list *list)
333 {
334  spa_list_init(&list->list);
335 }
336 
337 static inline bool spa_hook_list_is_empty(struct spa_hook_list *list)
338 {
339  return spa_list_is_empty(&list->list);
340 }
341 
343 static inline void spa_hook_list_append(struct spa_hook_list *list,
344  struct spa_hook *hook,
345  const void *funcs, void *data)
346 {
347  spa_zero(*hook);
348  hook->cb = SPA_CALLBACKS_INIT(funcs, data);
349  spa_list_append(&list->list, &hook->link);
350 }
351 
353 static inline void spa_hook_list_prepend(struct spa_hook_list *list,
354  struct spa_hook *hook,
355  const void *funcs, void *data)
356 {
357  spa_zero(*hook);
358  hook->cb = SPA_CALLBACKS_INIT(funcs, data);
359  spa_list_prepend(&list->list, &hook->link);
360 }
361 
363 static inline void spa_hook_remove(struct spa_hook *hook)
364 {
365  if (spa_list_is_initialized(&hook->link))
366  spa_list_remove(&hook->link);
367  if (hook->removed)
368  hook->removed(hook);
369 }
370 
372 static inline void spa_hook_list_clean(struct spa_hook_list *list)
373 {
374  struct spa_hook *h;
375  spa_list_consume(h, &list->list, link)
376  spa_hook_remove(h);
377 }
378 
379 static inline void
381  struct spa_hook_list *save,
382  struct spa_hook *hook,
383  const void *funcs, void *data)
384 {
385  /* init save list and move hooks to it */
386  spa_hook_list_init(save);
387  spa_list_insert_list(&save->list, &list->list);
388  /* init hooks and add single hook */
390  spa_hook_list_append(list, hook, funcs, data);
391 }
392 
393 static inline void
394 spa_hook_list_join(struct spa_hook_list *list,
395  struct spa_hook_list *save)
396 {
397  spa_list_insert_list(&list->list, &save->list);
398 }
399 
400 #define spa_hook_list_call_simple(l,type,method,vers,...) \
401 ({ \
402  struct spa_hook_list *_l = l; \
403  struct spa_hook *_h, *_t; \
404  spa_list_for_each_safe(_h, _t, &_l->list, link) \
405  spa_callbacks_call(&_h->cb,type,method,vers, ## __VA_ARGS__); \
406 })
407 
411 #define spa_hook_list_do_call(l,start,type,method,vers,once,...) \
412 ({ \
413  struct spa_hook_list *_list = l; \
414  struct spa_list *_s = start ? (struct spa_list *)start : &_list->list; \
415  struct spa_hook _cursor = { 0 }, *_ci; \
416  int _count = 0; \
417  spa_list_cursor_start(_cursor, _s, link); \
418  spa_list_for_each_cursor(_ci, _cursor, &_list->list, link) { \
419  if (spa_callbacks_call(&_ci->cb,type,method,vers, ## __VA_ARGS__)) { \
420  _count++; \
421  if (once) \
422  break; \
423  } \
424  } \
425  spa_list_cursor_end(_cursor, link); \
426  _count; \
427 })
428 
433 #define spa_hook_list_call(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,false,##__VA_ARGS__)
439 #define spa_hook_list_call_once(l,t,m,v,...) spa_hook_list_do_call(l,NULL,t,m,v,true,##__VA_ARGS__)
440 
441 #define spa_hook_list_call_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,false,##__VA_ARGS__)
442 #define spa_hook_list_call_once_start(l,s,t,m,v,...) spa_hook_list_do_call(l,s,t,m,v,true,##__VA_ARGS__)
443 
448 #ifdef __cplusplus
449 }
450 #endif
451 
452 #endif /* SPA_HOOK_H */
spa/utils/defs.h
static bool spa_hook_list_is_empty(struct spa_hook_list *list)
Definition: hook.h:346
static void spa_hook_list_append(struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data)
Append a hook.
Definition: hook.h:352
static void spa_hook_list_join(struct spa_hook_list *list, struct spa_hook_list *save)
Definition: hook.h:403
static void spa_hook_list_init(struct spa_hook_list *list)
Initialize a hook list to the empty list.
Definition: hook.h:341
static void spa_hook_remove(struct spa_hook *hook)
Remove a hook.
Definition: hook.h:372
static void spa_hook_list_clean(struct spa_hook_list *list)
Remove all hooks from the list.
Definition: hook.h:381
static void spa_hook_list_prepend(struct spa_hook_list *list, struct spa_hook *hook, const void *funcs, void *data)
Prepend a hook.
Definition: hook.h:362
static void spa_hook_list_isolate(struct spa_hook_list *list, struct spa_hook_list *save, struct spa_hook *hook, const void *funcs, void *data)
Definition: hook.h:389
#define SPA_CALLBACKS_INIT(_funcs, _data)
Initialize the set of functions funcs as a spa_callbacks, together with _data.
Definition: hook.h:134
static int spa_list_is_initialized(struct spa_list *list)
Definition: list.h:40
#define spa_list_consume(pos, head, member)
Definition: list.h:92
static void spa_list_init(struct spa_list *list)
Definition: list.h:35
static void spa_list_remove(struct spa_list *elem)
Definition: list.h:65
#define spa_list_prepend(list, item)
Definition: list.h:80
#define spa_list_is_empty(l)
Definition: list.h:45
#define spa_list_append(list, item)
Definition: list.h:77
static void spa_list_insert_list(struct spa_list *list, struct spa_list *other)
Definition: list.h:55
#define spa_zero(x)
Definition: defs.h:417
spa/utils/list.h
Callbacks, contains the structure with functions and the data passed to the functions.
Definition: hook.h:116
const void * funcs
Definition: hook.h:117
void * data
Definition: hook.h:118
A list of hooks.
Definition: hook.h:320
struct spa_list list
Definition: hook.h:321
A hook, contains the structure with functions and the data passed to the functions.
Definition: hook.h:331
void(* removed)(struct spa_hook *hook)
callback and data for the hook list, private to the hook_list implementor
Definition: hook.h:336
struct spa_callbacks cb
Definition: hook.h:333
struct spa_list link
Definition: hook.h:332
void * priv
Definition: hook.h:337
Definition: hook.h:138
uint32_t version
Definition: hook.h:140
const char * type
Definition: hook.h:139
struct spa_callbacks cb
Definition: hook.h:141
Definition: list.h:27