libobs: Add obs_object abstraction and functions
With this, you can now cast normal obs objects (services, outputs, sources, encoders) to an obs_object_t, and then use obs_object_* functions to get references, release references, and similar for weak object references as well. This allows the ability for the frontend to use an object of any of those types interchangeably in certain situations without having to handle each specific type individually. This is useful because the properties view in particular doesn't care what type of object it uses, it just needs to be able to hold weak references to abstract OBS objects.
This commit is contained in:
83
libobs/obs.c
83
libobs/obs.c
@@ -2166,6 +2166,14 @@ void obs_context_data_free(struct obs_context_data *context)
|
||||
memset(context, 0, sizeof(*context));
|
||||
}
|
||||
|
||||
void obs_context_init_control(struct obs_context_data *context, void *object,
|
||||
obs_destroy_cb destroy)
|
||||
{
|
||||
context->control = bzalloc(sizeof(obs_weak_object_t));
|
||||
context->control->object = object;
|
||||
context->destroy = destroy;
|
||||
}
|
||||
|
||||
void obs_context_data_insert(struct obs_context_data *context,
|
||||
pthread_mutex_t *mutex, void *pfirst)
|
||||
{
|
||||
@@ -2650,3 +2658,78 @@ void obs_set_ui_task_handler(obs_task_handler_t handler)
|
||||
obs->ui_task_handler = handler;
|
||||
obs_queue_task(OBS_TASK_UI, set_ui_thread, NULL, false);
|
||||
}
|
||||
|
||||
obs_object_t *obs_object_get_ref(obs_object_t *object)
|
||||
{
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
return obs_weak_object_get_object(object->control);
|
||||
}
|
||||
|
||||
void obs_object_release(obs_object_t *object)
|
||||
{
|
||||
if (!obs) {
|
||||
blog(LOG_WARNING, "Tried to release an object when the OBS "
|
||||
"core is shut down!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
obs_weak_object_t *control = object->control;
|
||||
if (obs_ref_release(&control->ref)) {
|
||||
object->destroy(object);
|
||||
obs_weak_object_release(control);
|
||||
}
|
||||
}
|
||||
|
||||
void obs_weak_object_addref(obs_weak_object_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
obs_weak_ref_addref(&weak->ref);
|
||||
}
|
||||
|
||||
void obs_weak_object_release(obs_weak_object_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
if (obs_weak_ref_release(&weak->ref))
|
||||
bfree(weak);
|
||||
}
|
||||
|
||||
obs_weak_object_t *obs_object_get_weak_object(obs_object_t *object)
|
||||
{
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
obs_weak_object_t *weak = object->control;
|
||||
obs_weak_object_addref(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_object_t *obs_weak_object_get_object(obs_weak_object_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return NULL;
|
||||
|
||||
if (obs_weak_ref_get_ref(&weak->ref))
|
||||
return weak->object;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool obs_weak_object_expired(obs_weak_object_t *weak)
|
||||
{
|
||||
return weak ? obs_weak_ref_expired(&weak->ref) : true;
|
||||
}
|
||||
|
||||
bool obs_weak_object_references_object(obs_weak_object_t *weak,
|
||||
obs_object_t *object)
|
||||
{
|
||||
return weak && object && weak->object == object;
|
||||
}
|
||||
|
Reference in New Issue
Block a user