PipeWire 1.6.8

Loading...
Searching...
No Matches
Interfaces
SPA » Utilities

Generic implementation of implementation-independent interfaces. More...

## Files
file | hook.h
| spa/utils/hook.h

## Data Structures
struct | spa_callbacks
| Callbacks, contains the structure with functions and the data passed to the functions. More...
struct | spa_interface

## Macros
#define | SPA_CALLBACK_VERSION_MIN(c, v)
| Check if a callback c is of at least version v.
#define | SPA_CALLBACK_CHECK(c, m, v)
| Check if a callback c has method m of version v.
#define | SPA_CALLBACKS_INIT(_funcs, _data)
| Initialize the set of functions funcs as a spa_callbacks, together with _data.
#define | SPA_INTERFACE_INIT(_type, _version, _funcs, _data)
| Initialize a spa_interface.
#define | spa_callbacks_call(callbacks, type, method, vers, ...)
| Invoke method named method in the callbacks.
#define | spa_callbacks_call_fast(callbacks, type, method, vers, ...)
#define | spa_callback_version_min(callbacks, type, vers)
| True if the callbacks are of version vers, false otherwise.
#define | spa_callback_check(callbacks, type, method, vers)
| True if the callbacks contains method of version vers, false otherwise.
#define | spa_callbacks_call_res(callbacks, type, res, method, vers, ...)
| Invoke method named method in the callbacks.
#define | spa_callbacks_call_fast_res(callbacks, type, res, method, vers, ...)
#define | spa_interface_callback_version_min(iface, method_type, vers)
| True if the iface's callbacks are of version vers, false otherwise.
#define | spa_interface_callback_check(iface, method_type, method, vers)
| True if the iface's callback method is of version vers and exists, false otherwise.
#define | spa_interface_call(iface, method_type, method, vers, ...)
| Invoke method named method in the callbacks on the given interface object.
#define | spa_interface_call_fast(iface, method_type, method, vers, ...)
#define | spa_interface_call_res(iface, method_type, res, method, vers, ...)
| Invoke method named method in the callbacks on the given interface object.
#define | spa_interface_call_fast_res(iface, method_type, res, method, vers, ...)
#define | spa_api_func_v(o, method, version, ...)
#define | spa_api_func_r(rtype, def, o, method, version, ...)
#define | spa_api_func_fast(o, method, ...)
#define | spa_api_method_v(type, o, method, version, ...)
#define | spa_api_method_r(rtype, def, type, o, method, version, ...)
#define | spa_api_method_null_v(type, co, o, method, version, ...)
#define | spa_api_method_null_r(rtype, def, type, co, o, method, version, ...)
#define | spa_api_method_fast_v(type, o, method, version, ...)
#define | spa_api_method_fast_r(rtype, def, type, o, method, version, ...)

## Detailed Description

Generic implementation of implementation-independent interfaces.

A SPA Interface is a generic struct that, together with a few macros, provides a generic way of invoking methods on objects without knowing the details of the implementation.

The primary interaction with interfaces is through macros that expand into the right method call. For the implementation of an interface, we need two structs and a macro to invoke the bar method:

// this struct must be public and defines the interface to a
// struct foo
struct foo_methods {
uint32_t version;
void (*bar)(void *object, const char *msg);
};
// this struct does not need to be public
struct foo {
struct spa_interface iface; // must be first element, see foo_bar()
int some_other_field;
...
};
// if struct foo is private, we need to cast to a
// generic spa_interface object
#define foo_bar(obj, ...) ({ \
struct foo *f = obj;
spa_interface_call((struct spa_interface *)f, // pointer to spa_interface in foo
struct foo_methods, // type of callbacks
bar, // name of methods
0, // hardcoded version to match foo_methods->version
__VA_ARGS__ // pass rest of args through
);/
})
spa_interface_call
#define spa_interface_call(iface, method_type, method, vers,...)
Invoke method named method in the callbacks on the given interface object.
Definition hook.h:248
spa_interface
Definition hook.h:148

The struct foo_methods and the invocation macro foo_bar() must be available to the caller. The implementation of struct foo can be private.

void main(void) {
struct foo *myfoo = get_foo_from_somewhere();
foo_bar(myfoo, "Invoking bar() on myfoo");
}

The expansion of foo_bar() resolves roughly into this code:

void main(void) {
struct foo *myfoo = get_foo_from_somewhere();
// foo_bar(myfoo, "Invoking bar() on myfoo");
const struct foo_methods *methods = ((struct spa_interface*)myfoo)->cb;
if (0 >= methods->version && // version check
methods->bar) // compile error if this function does not exist,
methods->bar(myfoo, "Invoking bar() on myfoo");
}
spa_interface::cb
struct spa_callbacks cb
Definition hook.h:151

The typecast used in foo_bar() allows struct foo to be opaque to the caller. The implementation may assign the callback methods at object instantiation, and the caller will transparently invoke the method on the given object. For example, the following code assigns a different bar() method on Mondays - the caller does not need to know this.

static void bar_stdout(struct foo *f, const char *msg) {
printf(msg);
}
static void bar_stderr(struct foo *f, const char *msg) {
fprintf(stderr, msg);
}
struct foo* get_foo_from_somewhere() {
struct foo *f = calloc(sizeof struct foo);
// illustrative only, use SPA_INTERFACE_INIT()
f->iface->cb = (struct foo_methods*) { .bar = bar_stdout };
if (today_is_monday)
f->iface->cb = (struct foo_methods*) { .bar = bar_stderr };
return f;
}

## Macro Definition Documentation

## ◆ SPA_CALLBACK_VERSION_MIN

#define SPA_CALLBACK_VERSION_MIN | ( |  | c,
|  |  | v )

Value:
((c) && ((v) == 0 || (c)->version > (v)-1))

Check if a callback c is of at least version v.

## ◆ SPA_CALLBACK_CHECK

#define SPA_CALLBACK_CHECK | ( |  | c,
|  |  | m,
|  |  | v )

Value:
(SPA_CALLBACK_VERSION_MIN(c,v) && (c)->m)
SPA_CALLBACK_VERSION_MIN
#define SPA_CALLBACK_VERSION_MIN(c, v)
Check if a callback c is of at least version v.
Definition hook.h:133

Check if a callback c has method m of version v.

## ◆ SPA_CALLBACKS_INIT

#define SPA_CALLBACKS_INIT | ( |  | _funcs,
|  |  | _data )

Value:
((struct spa_callbacks){ (_funcs), (_data), })
spa_callbacks
Callbacks, contains the structure with functions and the data passed to the functions.
Definition hook.h:126

Initialize the set of functions funcs as a spa_callbacks, together with _data.

## ◆ SPA_INTERFACE_INIT

#define SPA_INTERFACE_INIT | ( |  | _type,
|  |  | _version,
|  |  | _funcs,
|  |  | _data )

Value:
((struct spa_interface){ (_type), (_version), SPA_CALLBACKS_INIT(_funcs,_data), })
SPA_CALLBACKS_INIT
#define SPA_CALLBACKS_INIT(_funcs, _data)
Initialize the set of functions funcs as a spa_callbacks, together with _data.
Definition hook.h:144

Initialize a spa_interface.

const static struct foo_methods foo_funcs = {
.bar = some_bar_implementation,
};
struct foo *f = malloc(...);
f->iface = SPA_INTERFACE_INIT("foo type", 0, foo_funcs, NULL);
SPA_INTERFACE_INIT
#define SPA_INTERFACE_INIT(_type, _version, _funcs, _data)
Initialize a spa_interface.
Definition hook.h:167

Examples
  export-sink.c, and export-source.c.

## ◆ spa_callbacks_call

#define spa_callbacks_call | ( |  | callbacks,
|  |  | type,
|  |  | method,
|  |  | vers,
|  |  | ... )

Invoke method named method in the callbacks.

The method_type defines the type of the method struct. Returns true if the method could be called, false otherwise.

## ◆ spa_callbacks_call_fast

#define spa_callbacks_call_fast | ( |  | callbacks,
|  |  | type,
|  |  | method,
|  |  | vers,
|  |  | ... )

## ◆ spa_callback_version_min

#define spa_callback_version_min | ( |  | callbacks,
|  |  | type,
|  |  | vers )

True if the callbacks are of version vers, false otherwise.

## ◆ spa_callback_check

#define spa_callback_check | ( |  | callbacks,
|  |  | type,
|  |  | method,
|  |  | vers )

True if the callbacks contains method of version vers, false otherwise.

## ◆ spa_callbacks_call_res

#define spa_callbacks_call_res | ( |  | callbacks,
|  |  | type,
|  |  | res,
|  |  | method,
|  |  | vers,
|  |  | ... )

Invoke method named method in the callbacks.

The method_type defines the type of the method struct.

The return value is stored in res.

## ◆ spa_callbacks_call_fast_res

#define spa_callbacks_call_fast_res | ( |  | callbacks,
|  |  | type,
|  |  | res,
|  |  | method,
|  |  | vers,
|  |  | ... )

## ◆ spa_interface_callback_version_min

#define spa_interface_callback_version_min | ( |  | iface,
|  |  | method_type,
|  |  | vers )

Value:
spa_callback_version_min(&(iface)->cb, method_type, vers)
spa_callback_version_min
#define spa_callback_version_min(callbacks, type, vers)
True if the callbacks are of version vers, false otherwise.
Definition hook.h:195

True if the iface's callbacks are of version vers, false otherwise.

## ◆ spa_interface_callback_check

#define spa_interface_callback_check | ( |  | iface,
|  |  | method_type,
|  |  | method,
|  |  | vers )

Value:
spa_callback_check(&(iface)->cb, method_type, method, vers)
spa_callback_check
#define spa_callback_check(callbacks, type, method, vers)
True if the callbacks contains method of version vers, false otherwise.
Definition hook.h:205

True if the iface's callback method is of version vers and exists, false otherwise.

## ◆ spa_interface_call

#define spa_interface_call | ( |  | iface,
|  |  | method_type,
|  |  | method,
|  |  | vers,
|  |  | ... )

Value:
spa_callbacks_call(&(iface)->cb,method_type,method,vers,##__VA_ARGS__)
spa_callbacks_call
#define spa_callbacks_call(callbacks, type, method, vers,...)
Invoke method named method in the callbacks.
Definition hook.h:175

Invoke method named method in the callbacks on the given interface object.

The method_type defines the type of the method struct, not the interface itself.

## ◆ spa_interface_call_fast

#define spa_interface_call_fast | ( |  | iface,
|  |  | method_type,
|  |  | method,
|  |  | vers,
|  |  | ... )

Value:
spa_callbacks_call_fast(&(iface)->cb,method_type,method,vers,##__VA_ARGS__)
spa_callbacks_call_fast
#define spa_callbacks_call_fast(callbacks, type, method, vers,...)
Definition hook.h:184

## ◆ spa_interface_call_res

#define spa_interface_call_res | ( |  | iface,
|  |  | method_type,
|  |  | res,
|  |  | method,
|  |  | vers,
|  |  | ... )

Value:
spa_callbacks_call_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__)
res
uint32_t int int res
Definition core.h:433
spa_callbacks_call_res
#define spa_callbacks_call_res(callbacks, type, res, method, vers,...)
Invoke method named method in the callbacks.
Definition hook.h:217

Invoke method named method in the callbacks on the given interface object.

The method_type defines the type of the method struct, not the interface itself.

The return value is stored in res.

## ◆ spa_interface_call_fast_res

#define spa_interface_call_fast_res | ( |  | iface,
|  |  | method_type,
|  |  | res,
|  |  | method,
|  |  | vers,
|  |  | ... )

Value:
spa_callbacks_call_fast_res(&(iface)->cb,method_type,res,method,vers,##__VA_ARGS__)
spa_callbacks_call_fast_res
#define spa_callbacks_call_fast_res(callbacks, type, res, method, vers,...)
Definition hook.h:224

## ◆ spa_api_func_v

#define spa_api_func_v | ( |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_func_r

#define spa_api_func_r | ( |  | rtype,
|  |  | def,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_func_fast

#define spa_api_func_fast | ( |  | o,
|  |  | method,
|  |  | ... )

## ◆ spa_api_method_v

#define spa_api_method_v | ( |  | type,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_method_r

#define spa_api_method_r | ( |  | rtype,
|  |  | def,
|  |  | type,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_method_null_v

#define spa_api_method_null_v | ( |  | type,
|  |  | co,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_method_null_r

#define spa_api_method_null_r | ( |  | rtype,
|  |  | def,
|  |  | type,
|  |  | co,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_method_fast_v

#define spa_api_method_fast_v | ( |  | type,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )

## ◆ spa_api_method_fast_r

#define spa_api_method_fast_r | ( |  | rtype,
|  |  | def,
|  |  | type,
|  |  | o,
|  |  | method,
|  |  | version,
|  |  | ... )