ansi.h |
\defgroup spa_ansi ANSI codes
ANSI color code macros
|
3813 |
defs.h |
\defgroup spa_utils_defs Miscellaneous
Helper macros and functions
|
10190 |
dict.h |
\defgroup spa_dict Dictionary
Dictionary data structure
|
3387 |
dll.h |
extern "C" |
2070 |
hook.h |
\defgroup spa_interfaces Interfaces
\brief 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:
\code{.c}
// 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
);/
})
\endcode
The `struct foo_methods` and the invocation macro `foo_bar()` must be
available to the caller. The implementation of `struct foo` can be private.
\code{.c}
void main(void) {
struct foo *myfoo = get_foo_from_somewhere();
foo_bar(myfoo, "Invoking bar() on myfoo");
}
\endcode
The expansion of `foo_bar()` resolves roughly into this code:
\code{.c}
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");
}
\endcode
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.
\code{.c}
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;
}
\endcode
|
14909 |
json-pod.h |
\defgroup spa_json_pod JSON to POD
JSON to POD conversion
|
4936 |
json.h |
\defgroup spa_json JSON
Relaxed JSON variant parsing
|
11294 |
keys.h |
\defgroup spa_keys Key Names
Key names used by SPA plugins
|
7249 |
list.h |
\defgroup spa_list List
Doubly linked list data structure
|
5145 |
names.h |
\defgroup spa_names Factory Names
SPA plugin factory names
|
7402 |
result.h |
\defgroup spa_result Result handling
Asynchronous result utilities
|
2123 |
ringbuffer.h |
\defgroup spa_ringbuffer Ringbuffer
Ring buffer implementation
|
5690 |
string.h |
\defgroup spa_string String handling
String handling utilities
|
8651 |
type-info.h |
\addtogroup spa_types
\{
|
6609 |
type.h |
\defgroup spa_types Types
Data type information enumerations
|
4212 |