From a2a8a5f148cd010c30e656b8be010c48153383be Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 4 Jan 2014 13:38:56 -0700 Subject: [PATCH] Added add/remove signals to scenes Scenes will now signal via their source when an item has been added or removed from them. "add" - Item added to the scene. Parameters: "scene": Scene that the item was added to. "item": Item that was added. "remove" - Item removed from the scene. Parameters: "scene": Scene that the item was removed from. "item": Item that was removed. --- libobs/obs-scene.c | 42 ++++++++++++++++++++++++++++++++++++++---- libobs/obs-source.c | 2 +- libobs/obs-source.h | 1 + libobs/obs-video.c | 1 - libobs/obs.c | 19 +++++++++++++++---- libobs/obs.h | 3 +++ 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 3925a9f71..3d9ddd07d 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -18,6 +18,16 @@ #include "graphics/math-defs.h" #include "obs-scene.h" +static inline void signal_item_destroy(struct obs_scene_item *item, + struct calldata *params) +{ + calldata_setptr(params, "scene", item->parent); + calldata_setptr(params, "item", item); + signal_handler_signal(item->parent->source->signals, "remove", + params); + calldata_clear(params); +} + static const char *scene_getname(const char *locale) { /* TODO: locale lookup of display name */ @@ -43,16 +53,20 @@ static void scene_destroy(void *data) { struct obs_scene *scene = data; struct obs_scene_item *item = scene->first_item; + struct calldata params = {0}; while (item) { struct obs_scene_item *del_item = item; item = item->next; + signal_item_destroy(del_item, ¶ms); + if (del_item->source) obs_source_release(del_item->source); bfree(del_item); } + calldata_free(¶ms); pthread_mutex_destroy(&scene->mutex); bfree(scene); } @@ -141,14 +155,19 @@ static const struct source_info scene_info = obs_scene_t obs_scene_create(const char *name) { struct obs_source *source = bmalloc(sizeof(struct obs_source)); - struct obs_scene *scene = scene_create(NULL, source); + struct obs_scene *scene; memset(source, 0, sizeof(struct obs_source)); + if (!obs_source_init_handlers(source)) { + bfree(source); + return NULL; + } + scene = scene_create(NULL, source); source->data = scene; - assert(source->data); - if (!source->data) { + assert(scene); + if (!scene) { bfree(source); return NULL; } @@ -230,6 +249,7 @@ obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source) { struct obs_scene_item *last; struct obs_scene_item *item = bmalloc(sizeof(struct obs_scene_item)); + struct calldata params = {0}; memset(item, 0, sizeof(struct obs_scene_item)); item->source = source; @@ -252,9 +272,14 @@ obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source) last->next = item; item->prev = last; } - + pthread_mutex_unlock(&scene->mutex); + calldata_setptr(¶ms, "scene", scene); + calldata_setptr(¶ms, "item", item); + signal_handler_signal(scene->source->signals, "add", ¶ms); + calldata_free(¶ms); + return item; } @@ -263,6 +288,10 @@ int obs_sceneitem_destroy(obs_sceneitem_t item) int ref = 0; if (item) { + struct calldata params = {0}; + signal_item_destroy(item, ¶ms); + calldata_free(¶ms); + pthread_mutex_lock(&item->parent->mutex); detach_sceneitem(item); pthread_mutex_unlock(&item->parent->mutex); @@ -275,6 +304,11 @@ int obs_sceneitem_destroy(obs_sceneitem_t item) return ref; } +obs_scene_t obs_sceneitem_getscene(obs_sceneitem_t item) +{ + return item->parent; +} + obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item) { return item->source; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 4c2e61d90..f513b26ca 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -104,7 +104,7 @@ static const struct source_info *get_source_info(enum obs_source_type type, return find_source(list, id); } -static inline bool obs_source_init_handlers(struct obs_source *source) +bool obs_source_init_handlers(struct obs_source *source) { source->signals = signal_handler_create(); if (!source->signals) diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 11e08f86a..a954d6960 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -252,6 +252,7 @@ struct obs_source { extern bool load_source_info(void *module, const char *module_name, const char *source_name, struct source_info *info); +bool obs_source_init_handlers(struct obs_source *source); extern bool obs_source_init(struct obs_source *source, const char *settings, const struct source_info *info); diff --git a/libobs/obs-video.c b/libobs/obs-video.c index f3ab9decd..738af426a 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -56,7 +56,6 @@ static inline void render_begin(struct obs_display *display) gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f); gs_setviewport(0, 0, width, height); - } static inline void render_end(struct obs_display *display) diff --git a/libobs/obs.c b/libobs/obs.c index 9946e7891..0ac5be98e 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -462,15 +462,26 @@ obs_source_t obs_get_output_source(uint32_t channel) void obs_set_output_source(uint32_t channel, obs_source_t source) { struct obs_source *prev_source; + struct calldata params = {0}; assert(channel < MAX_CHANNELS); prev_source = obs->data.channels[channel]; + + calldata_setuint32(¶ms, "channel", channel); + calldata_setptr(¶ms, "prev_source", prev_source); + calldata_setptr(¶ms, "source", source); + signal_handler_signal(obs->signals, "channel-change", ¶ms); + calldata_getptr(¶ms, "source", &source); + calldata_free(¶ms); + obs->data.channels[channel] = source; - if (source) - obs_source_addref(source); - if (prev_source) - obs_source_release(prev_source); + if (source != prev_source) { + if (source) + obs_source_addref(source); + if (prev_source) + obs_source_release(prev_source); + } } void obs_enum_sources(bool (*enum_proc)(obs_source_t, void*), void *param) diff --git a/libobs/obs.h b/libobs/obs.h index f2ce51e43..dfbbd1b9d 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -472,6 +472,9 @@ EXPORT obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source); * (if any) */ EXPORT int obs_sceneitem_destroy(obs_sceneitem_t item); +/** Gets the scene parent associated with the scene item */ +EXPORT obs_scene_t obs_sceneitem_getscene(obs_sceneitem_t item); + /** Gets the source of a scene item */ EXPORT obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item);