瀏覽代碼

libobs: Remove group_sceneitem from obs_scene struct

(This commit also modifies UI)

Removes obs_scene::group_sceneitem and replaces it with
obs_scene::is_group.  Changes a number of other functions related to
groups so that a group is not inherently tied to a specific scene, and
helps allow a single group to be referenced in multiple scenes if
desired.
jp9000 7 年之前
父節點
當前提交
35704c4c04
共有 6 個文件被更改,包括 95 次插入73 次删除
  1. 5 4
      UI/source-tree.cpp
  2. 1 1
      UI/window-basic-main.cpp
  3. 5 2
      UI/window-basic-preview.cpp
  4. 77 61
      libobs/obs-scene.c
  5. 1 1
      libobs/obs-scene.h
  6. 6 4
      libobs/obs.h

+ 5 - 4
UI/source-tree.cpp

@@ -917,7 +917,7 @@ void SourceTree::dropEvent(QDropEvent *event)
 
 	obs_sceneitem_t *dropGroup = itemIsGroup
 		? dropItem
-		: obs_sceneitem_get_group(dropItem);
+		: obs_sceneitem_get_group(scene, dropItem);
 
 	/* not a group if moving above the group */
 	if (indicator == QAbstractItemView::AboveItem && itemIsGroup)
@@ -966,7 +966,7 @@ void SourceTree::dropEvent(QDropEvent *event)
 		: stm->items[row];
 	if (hasGroups) {
 		if (!itemBelow ||
-		    obs_sceneitem_get_group(itemBelow) != dropGroup) {
+		    obs_sceneitem_get_group(scene, itemBelow) != dropGroup) {
 			indicator = QAbstractItemView::BelowItem;
 			dropGroup = nullptr;
 			dropOnCollapsed = false;
@@ -1006,7 +1006,8 @@ void SourceTree::dropEvent(QDropEvent *event)
 				for (int j = items.size() - 1; j >= 0; j--) {
 					obs_sceneitem_t *subitem = items[j];
 					obs_sceneitem_t *subitemGroup =
-						obs_sceneitem_get_group(subitem);
+						obs_sceneitem_get_group(scene,
+								subitem);
 
 					if (subitemGroup == item) {
 						QModelIndex idx =
@@ -1117,7 +1118,7 @@ void SourceTree::dropEvent(QDropEvent *event)
 			if (!hasGroups && i >= firstIdx && i <= lastIdx)
 				group = dropGroup;
 			else
-				group = obs_sceneitem_get_group(item);
+				group = obs_sceneitem_get_group(scene, item);
 
 			if (lastGroup && lastGroup != group) {
 				insertLastGroup();

+ 1 - 1
UI/window-basic-main.cpp

@@ -2627,7 +2627,7 @@ void OBSBasic::DeactivateAudioSource(OBSSource source)
 bool OBSBasic::QueryRemoveSource(obs_source_t *source)
 {
 	if (obs_source_get_type(source) == OBS_SOURCE_TYPE_SCENE &&
-	    !obs_sceneitem_group_from_source(source)) {
+	    !obs_source_is_group(source)) {
 		int count = ui->scenes->count();
 
 		if (count == 1) {

+ 5 - 2
UI/window-basic-preview.cpp

@@ -420,7 +420,7 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
 		cropSize.y = float(obs_source_get_height(source) -
 				startCrop.top - startCrop.bottom);
 
-		stretchGroup = obs_sceneitem_get_group(stretchItem);
+		stretchGroup = obs_sceneitem_get_group(scene, stretchItem);
 		if (stretchGroup) {
 			obs_sceneitem_get_draw_transform(stretchGroup,
 					&invGroupTransform);
@@ -1135,8 +1135,11 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
 		pos.y = std::round(pos.y);
 
 		if (stretchHandle != ItemHandle::None) {
+			OBSBasic *main = reinterpret_cast<OBSBasic*>(
+					App()->GetMainWindow());
+			OBSScene scene = main->GetCurrentScene();
 			obs_sceneitem_t *group = obs_sceneitem_get_group(
-					stretchItem);
+					scene, stretchItem);
 			if (group) {
 				vec3 group_pos;
 				vec3_set(&group_pos, pos.x, pos.y, 0.0f);

+ 77 - 61
libobs/obs-scene.c

@@ -530,9 +530,8 @@ static void scene_video_tick(void *data, float seconds)
 
 /* assumes video lock */
 static void update_transforms_and_prune_sources(obs_scene_t *scene,
-		struct darray *remove_items)
+		struct darray *remove_items, obs_sceneitem_t *group_sceneitem)
 {
-	obs_sceneitem_t *group_sceneitem = scene->group_sceneitem;
 	struct obs_scene_item *item = scene->first_item;
 	bool rebuild_group = group_sceneitem &&
 		os_atomic_load_bool(&group_sceneitem->update_group_resize);
@@ -554,7 +553,7 @@ static void update_transforms_and_prune_sources(obs_scene_t *scene,
 
 			video_lock(group_scene);
 			update_transforms_and_prune_sources(group_scene,
-					remove_items);
+					remove_items, item);
 			video_unlock(group_scene);
 		}
 
@@ -568,8 +567,8 @@ static void update_transforms_and_prune_sources(obs_scene_t *scene,
 		item = item->next;
 	}
 
-	if (rebuild_group && scene->group_sceneitem)
-		resize_group(scene->group_sceneitem);
+	if (rebuild_group && group_sceneitem)
+		resize_group(group_sceneitem);
 }
 
 static void scene_video_render(void *data, gs_effect_t *effect)
@@ -582,8 +581,9 @@ static void scene_video_render(void *data, gs_effect_t *effect)
 
 	video_lock(scene);
 
-	if (!scene->group_sceneitem) {
-		update_transforms_and_prune_sources(scene, &remove_items.da);
+	if (!scene->is_group) {
+		update_transforms_and_prune_sources(scene, &remove_items.da,
+				NULL);
 	}
 
 	gs_blend_state_push();
@@ -671,7 +671,7 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
 
 	if (is_group) {
 		item->is_group = true;
-		((obs_scene_t *)source->context.data)->group_sceneitem = item;
+		((obs_scene_t *)source->context.data)->is_group = true;
 	}
 
 	obs_data_set_default_int(item_data, "align",
@@ -779,7 +779,8 @@ static void scene_load(void *data, obs_data_t *settings)
 static void scene_save(void *data, obs_data_t *settings);
 
 static void scene_save_item(obs_data_array_t *array,
-		struct obs_scene_item *item, bool group_item_backup)
+		struct obs_scene_item *item,
+		struct obs_scene_item *backup_group)
 {
 	obs_data_t *item_data = obs_data_create();
 	const char *name     = obs_source_get_name(item->source);
@@ -788,9 +789,8 @@ static void scene_save_item(obs_data_array_t *array,
 	struct vec2 scale = item->scale;
 	float rot = item->rot;
 
-	if (group_item_backup) {
-		obs_sceneitem_t *group = item->parent->group_sceneitem;
-		get_ungrouped_transform(group, &pos, &scale, &rot);
+	if (backup_group) {
+		get_ungrouped_transform(backup_group, &pos, &scale, &rot);
 	}
 
 	obs_data_set_string(item_data, "name",         name);
@@ -809,7 +809,7 @@ static void scene_save_item(obs_data_array_t *array,
 	obs_data_set_int  (item_data, "crop_bottom",  (int)item->crop.bottom);
 	obs_data_set_int  (item_data, "id",           item->id);
 	obs_data_set_bool (item_data, "is_group",     item->is_group);
-	obs_data_set_bool (item_data, "group_item_backup", group_item_backup);
+	obs_data_set_bool (item_data, "group_item_backup", !!backup_group);
 
 	if (item->is_group) {
 		obs_data_t *group_data = obs_data_create();
@@ -825,7 +825,7 @@ static void scene_save_item(obs_data_array_t *array,
 
 		group_item = group_scene->first_item;
 		while (group_item) {
-			scene_save_item(array, group_item, true);
+			scene_save_item(array, group_item, item);
 			group_item = group_item->next;
 		}
 
@@ -865,7 +865,7 @@ static void scene_save(void *data, obs_data_t *settings)
 
 	item = scene->first_item;
 	while (item) {
-		scene_save_item(array, item, false);
+		scene_save_item(array, item, NULL);
 		item = item->next;
 	}
 
@@ -1687,16 +1687,6 @@ static void signal_parent(obs_scene_t *parent, const char *command,
 {
 	calldata_set_ptr(params, "scene", parent);
 	signal_handler_signal(parent->source->context.signals, command, params);
-
-	if (parent->group_sceneitem) {
-		parent = parent->group_sceneitem->parent;
-		if (!parent)
-			return;
-
-		calldata_set_ptr(params, "scene", parent);
-		signal_handler_signal(parent->source->context.signals, command,
-				params);
-	}
 }
 
 void obs_sceneitem_select(obs_sceneitem_t *item, bool select)
@@ -2271,13 +2261,13 @@ static void get_ungrouped_transform(obs_sceneitem_t *group,
 	*rot += group->rot;
 }
 
-static void remove_group_transform(obs_sceneitem_t *item)
+static void remove_group_transform(obs_sceneitem_t *group,
+		obs_sceneitem_t *item)
 {
 	obs_scene_t *parent = item->parent;
-	if (!parent || !parent->group_sceneitem)
+	if (!parent || !group)
 		return;
 
-	obs_sceneitem_t *group = parent->group_sceneitem;
 	get_ungrouped_transform(group, &item->pos, &item->scale, &item->rot);
 
 	update_item_transform(item);
@@ -2411,7 +2401,6 @@ obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene,
 
 	obs_sceneitem_t *item = obs_scene_add_internal(
 			scene, sub_scene->source, last_item, true);
-	sub_scene->group_sceneitem = item;
 	sub_scene->custom_size = true;
 
 	obs_scene_release(sub_scene);
@@ -2427,7 +2416,7 @@ obs_sceneitem_t *obs_scene_insert_group(obs_scene_t *scene,
 
 	for (size_t i = count; i > 0; i--) {
 		size_t idx = i - 1;
-		remove_group_transform(items[idx]);
+		remove_group_transform(item, items[idx]);
 		detach_sceneitem(items[idx]);
 	}
 	for (size_t i = 0; i < count; i++) {
@@ -2480,17 +2469,6 @@ obs_sceneitem_t *obs_scene_get_group(obs_scene_t *scene, const char *name)
 	return group;
 }
 
-obs_sceneitem_t *obs_sceneitem_group_from_scene(obs_scene_t *scene)
-{
-	return scene ? scene->group_sceneitem : NULL;
-}
-
-obs_sceneitem_t *obs_sceneitem_group_from_source(obs_source_t *source)
-{
-	obs_scene_t *scene = obs_scene_from_source(source);
-	return obs_sceneitem_group_from_scene(scene);
-}
-
 bool obs_sceneitem_is_group(obs_sceneitem_t *item)
 {
 	return item && item->is_group;
@@ -2517,7 +2495,7 @@ void obs_sceneitem_group_ungroup(obs_sceneitem_t *item)
 	first = subscene->first_item;
 	last = first;
 	while (last) {
-		remove_group_transform(last);
+		remove_group_transform(item, last);
 		last->parent = scene;
 		if (!last->next)
 			break;
@@ -2567,7 +2545,7 @@ void obs_sceneitem_group_add_item(obs_sceneitem_t *group, obs_sceneitem_t *item)
 	/* ------------------------- */
 
 	full_lock(scene);
-	remove_group_transform(item);
+	remove_group_transform(group, item);
 	detach_sceneitem(item);
 
 	/* ------------------------- */
@@ -2596,41 +2574,38 @@ void obs_sceneitem_group_add_item(obs_sceneitem_t *group, obs_sceneitem_t *item)
 	full_unlock(scene);
 }
 
-void obs_sceneitem_group_remove_item(obs_sceneitem_t *item)
+void obs_sceneitem_group_remove_item(obs_sceneitem_t *group,
+		obs_sceneitem_t *item)
 {
-	if (!item)
+	if (!item || !group || !group->is_group)
 		return;
 
 	obs_scene_t *groupscene = item->parent;
-	obs_sceneitem_t *groupitem = groupscene->group_sceneitem;
-	if (!groupitem)
-		return;
-
-	obs_scene_t *scene = groupitem->parent;
+	obs_scene_t *scene = group->parent;
 
 	/* ------------------------- */
 
 	full_lock(scene);
 	full_lock(groupscene);
-	remove_group_transform(item);
+	remove_group_transform(group, item);
 	detach_sceneitem(item);
 
 	/* ------------------------- */
 
-	if (groupitem->prev) {
-		groupitem->prev->next = item;
-		item->prev = groupitem->prev;
+	if (group->prev) {
+		group->prev->next = item;
+		item->prev = group->prev;
 	} else {
 		scene->first_item = item;
 		item->prev = NULL;
 	}
-	groupitem->prev = item;
-	item->next = groupitem;
+	group->prev = item;
+	item->next = group;
 	item->parent = scene;
 
 	/* ------------------------- */
 
-	resize_group(groupitem);
+	resize_group(group);
 	full_unlock(groupscene);
 	full_unlock(scene);
 }
@@ -2695,6 +2670,23 @@ static bool sceneitems_match2(obs_scene_t *scene,
 	return true;
 }
 
+static obs_sceneitem_t *get_sceneitem_parent_group(obs_scene_t *scene,
+		obs_sceneitem_t *group_subitem)
+{
+	if (group_subitem->is_group)
+		return NULL;
+
+	obs_sceneitem_t *item = scene->first_item;
+	while (item) {
+		if (item->is_group &&
+		    item->source->context.data == group_subitem->parent)
+			return item;
+		item = item->next;
+	}
+
+	return NULL;
+}
+
 bool obs_scene_reorder_items2(obs_scene_t *scene,
 		struct obs_sceneitem_order_info *item_order,
 		size_t item_order_size)
@@ -2714,7 +2706,9 @@ bool obs_scene_reorder_items2(obs_scene_t *scene,
 	for (size_t i = 0; i < item_order_size; i++) {
 		struct obs_sceneitem_order_info *info = &item_order[i];
 		if (!info->item->is_group) {
-			remove_group_transform(info->item);
+			obs_sceneitem_t *group =
+				get_sceneitem_parent_group(scene, info->item);
+			remove_group_transform(group, info->item);
 		}
 	}
 
@@ -2783,16 +2777,38 @@ bool obs_scene_reorder_items2(obs_scene_t *scene,
 	return true;
 }
 
-obs_sceneitem_t *obs_sceneitem_get_group(obs_sceneitem_t *item)
+obs_sceneitem_t *obs_sceneitem_get_group(obs_scene_t *scene,
+		obs_sceneitem_t *group_subitem)
+{
+	if (!scene || !group_subitem || group_subitem->is_group)
+		return NULL;
+
+	full_lock(scene);
+	obs_sceneitem_t *group = get_sceneitem_parent_group(scene,
+			group_subitem);
+	full_unlock(scene);
+
+	return group;
+}
+
+bool obs_source_is_group(const obs_source_t *source)
+{
+	if (!source || source->info.id != scene_info.id)
+		return false;
+
+	return ((obs_scene_t *)source->context.data)->is_group;
+}
+
+bool obs_scene_is_group(const obs_scene_t *scene)
 {
-	return item && item->parent ? item->parent->group_sceneitem : NULL;
+	return scene ? scene->is_group : false;
 }
 
 void obs_sceneitem_group_enum_items(obs_sceneitem_t *group,
 		bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*),
 		void *param)
 {
-	if (!group)
+	if (!group || !group->is_group)
 		return;
 
 	obs_scene_t *scene = obs_scene_from_source(group->source);

+ 1 - 1
libobs/obs-scene.h

@@ -85,8 +85,8 @@ struct obs_scene_item {
 
 struct obs_scene {
 	struct obs_source     *source;
-	struct obs_scene_item *group_sceneitem;
 
+	bool                  is_group;
 	bool                  custom_size;
 	uint32_t              cx;
 	uint32_t              cy;

+ 6 - 4
libobs/obs.h

@@ -1447,12 +1447,14 @@ EXPORT void obs_sceneitem_group_ungroup(obs_sceneitem_t *group);
 
 EXPORT void obs_sceneitem_group_add_item(obs_sceneitem_t *group,
 		obs_sceneitem_t *item);
-EXPORT void obs_sceneitem_group_remove_item(obs_sceneitem_t *item);
+EXPORT void obs_sceneitem_group_remove_item(obs_sceneitem_t *group,
+		obs_sceneitem_t *item);
 
-EXPORT obs_sceneitem_t *obs_sceneitem_get_group(obs_sceneitem_t *item);
+EXPORT obs_sceneitem_t *obs_sceneitem_get_group(obs_scene_t *scene,
+		obs_sceneitem_t *item);
 
-EXPORT obs_sceneitem_t *obs_sceneitem_group_from_scene(obs_scene_t *scene);
-EXPORT obs_sceneitem_t *obs_sceneitem_group_from_source(obs_source_t *source);
+EXPORT bool obs_source_is_group(const obs_source_t *source);
+EXPORT bool obs_scene_is_group(const obs_scene_t *scene);
 
 EXPORT void obs_sceneitem_group_enum_items(obs_sceneitem_t *group,
 		bool (*callback)(obs_scene_t*, obs_sceneitem_t*, void*),