context: add object store

Add method to set and get typed objects from the context. This can
be used to pass around context objects between modules without having
to register them.
This commit is contained in:
Wim Taymans 2019-12-16 10:28:18 +01:00
parent 6cf6af6620
commit 1bca1b15ea
5 changed files with 62 additions and 0 deletions

View file

@ -1639,6 +1639,8 @@ int main(int argc, char *argv[])
pw_context_add_spa_lib(impl.this.context, "api.alsa.*", "alsa/libspa-alsa"); pw_context_add_spa_lib(impl.this.context, "api.alsa.*", "alsa/libspa-alsa");
pw_context_add_spa_lib(impl.this.context, "api.v4l2.*", "v4l2/libspa-v4l2"); pw_context_add_spa_lib(impl.this.context, "api.v4l2.*", "v4l2/libspa-v4l2");
pw_context_set_object(impl.this.context, SM_TYPE_MEDIA_SESSION, &impl);
pw_map_init(&impl.globals, 64, 64); pw_map_init(&impl.globals, 64, 64);
spa_list_init(&impl.global_list); spa_list_init(&impl.global_list);
pw_map_init(&impl.endpoint_links, 64, 64); pw_map_init(&impl.endpoint_links, 64, 64);

View file

@ -32,6 +32,8 @@
extern "C" { extern "C" {
#endif #endif
#define SM_TYPE_MEDIA_SESSION PW_TYPE_INFO_OBJECT_BASE "SessionManager"
struct sm_media_session; struct sm_media_session;
struct sm_object_events { struct sm_object_events {

View file

@ -203,6 +203,7 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop,
this->n_support = n_support; this->n_support = n_support;
pw_array_init(&this->factory_lib, 32); pw_array_init(&this->factory_lib, 32);
pw_array_init(&this->objects, 32);
pw_map_init(&this->globals, 128, 32); pw_map_init(&this->globals, 128, 32);
spa_list_init(&this->core_impl_list); spa_list_init(&this->core_impl_list);
@ -317,6 +318,8 @@ void pw_context_destroy(struct pw_context *context)
} }
pw_array_clear(&context->factory_lib); pw_array_clear(&context->factory_lib);
pw_array_clear(&context->objects);
pw_map_clear(&context->globals); pw_map_clear(&context->globals);
free(context); free(context);
@ -889,3 +892,51 @@ const struct pw_export_type *pw_context_find_export_type(struct pw_context *cont
} }
return NULL; return NULL;
} }
struct object_entry {
const char *type;
void *value;
};
static struct object_entry *find_object(struct pw_context *context, const char *type)
{
struct object_entry *entry;
pw_array_for_each(entry, &context->objects) {
if (strcmp(entry->type, type) == 0)
return entry;
}
return NULL;
}
SPA_EXPORT
int pw_context_set_object(struct pw_context *context, const char *type, void *value)
{
struct object_entry *entry;
entry = find_object(context, type);
if (value == NULL) {
if (entry)
pw_array_remove(&context->objects, entry);
} else {
if (entry == NULL) {
entry = pw_array_add(&context->objects, sizeof(*entry));
if (entry == NULL)
return -errno;
entry->type = type;
}
entry->value = value;
}
return 0;
}
SPA_EXPORT
void *pw_context_get_object(struct pw_context *context, const char *type)
{
struct object_entry *entry;
if ((entry = find_object(context, type)) != NULL)
return entry->value;
return NULL;
}

View file

@ -160,6 +160,11 @@ int pw_context_register_export_type(struct pw_context *context, struct pw_export
/** find information about registered export type */ /** find information about registered export type */
const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, uint32_t type); const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, uint32_t type);
/** add an object to the context */
int pw_context_set_object(struct pw_context *context, const char *type, void *value);
/** get an object from the context */
void *pw_context_get_object(struct pw_context *context, const char *type);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -258,6 +258,8 @@ struct pw_context {
uint32_t n_support; /**< number of support items */ uint32_t n_support; /**< number of support items */
struct pw_array factory_lib; /**< mapping of factory_name regexp to library */ struct pw_array factory_lib; /**< mapping of factory_name regexp to library */
struct pw_array objects; /**< objects */
struct pw_impl_client *current_client; /**< client currently executing code in mainloop */ struct pw_impl_client *current_client; /**< client currently executing code in mainloop */
long sc_pagesize; long sc_pagesize;