UI: Optimize backup scene for undo/redo
parent
ba3eb46bf9
commit
5998f4cc4d
|
@ -1286,8 +1286,16 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
|
||||
/* --------------------------------------- */
|
||||
/* save undo data */
|
||||
|
||||
OBSData undo_data = main->BackupScene(scenesource);
|
||||
std::vector<obs_source_t *> sources;
|
||||
for (int i = 0; i < indices.size(); i++) {
|
||||
obs_sceneitem_t *item = items[indices[i].row()];
|
||||
if (obs_sceneitem_get_scene(item) != scene)
|
||||
sources.push_back(obs_scene_get_source(
|
||||
obs_sceneitem_get_scene(item)));
|
||||
}
|
||||
if (dropGroup)
|
||||
sources.push_back(obs_sceneitem_get_source(dropGroup));
|
||||
OBSData undo_data = main->BackupScene(scene, &sources);
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* if selection includes base group items, */
|
||||
|
@ -1455,7 +1463,7 @@ void SourceTree::dropEvent(QDropEvent *event)
|
|||
/* --------------------------------------- */
|
||||
/* save redo data */
|
||||
|
||||
OBSData redo_data = main->BackupScene(scenesource);
|
||||
OBSData redo_data = main->BackupScene(scene, &sources);
|
||||
|
||||
/* --------------------------------------- */
|
||||
/* add undo/redo action */
|
||||
|
|
|
@ -3677,15 +3677,36 @@ void OBSBasic::DuplicateSelectedScene()
|
|||
}
|
||||
}
|
||||
|
||||
static void save_undo_source_enum(obs_source_t *, obs_source_t *source, void *p)
|
||||
static bool save_undo_source_enum(obs_scene_t *scene, obs_sceneitem_t *item,
|
||||
void *p)
|
||||
{
|
||||
obs_source_t *source = obs_sceneitem_get_source(item);
|
||||
if (obs_obj_is_private(source) && !obs_source_removed(source))
|
||||
return;
|
||||
return true;
|
||||
|
||||
obs_data_array_t *array = (obs_data_array_t *)p;
|
||||
|
||||
/* check if the source is already stored in the array */
|
||||
const char *name = obs_source_get_name(source);
|
||||
const size_t count = obs_data_array_count(array);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *sourceData = obs_data_array_item(array, i);
|
||||
if (strcmp(name, obs_data_get_string(sourceData, "name")) ==
|
||||
0) {
|
||||
obs_data_release(sourceData);
|
||||
return true;
|
||||
}
|
||||
obs_data_release(sourceData);
|
||||
}
|
||||
|
||||
if (obs_source_is_group(source))
|
||||
obs_scene_enum_items(obs_group_from_source(source),
|
||||
save_undo_source_enum, p);
|
||||
|
||||
obs_data_t *source_data = obs_save_source(source);
|
||||
obs_data_array_push_back(array, source_data);
|
||||
obs_data_release(source_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OBSBasic::RemoveSelectedScene()
|
||||
|
@ -3700,11 +3721,11 @@ void OBSBasic::RemoveSelectedScene()
|
|||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* save all sources in scene tree */
|
||||
/* save all sources in scene */
|
||||
|
||||
obs_data_array_t *array = obs_data_array_create();
|
||||
|
||||
obs_source_enum_full_tree(source, save_undo_source_enum, array);
|
||||
obs_scene_enum_items(scene, save_undo_source_enum, array);
|
||||
|
||||
obs_data_t *scene_data = obs_save_source(source);
|
||||
obs_data_array_push_back(array, scene_data);
|
||||
|
@ -5459,14 +5480,22 @@ static bool remove_items(obs_scene_t *, obs_sceneitem_t *item, void *param)
|
|||
return true;
|
||||
};
|
||||
|
||||
OBSData OBSBasic::BackupScene(obs_source_t *scene_source)
|
||||
OBSData OBSBasic::BackupScene(obs_scene_t *scene,
|
||||
std::vector<obs_source_t *> *sources)
|
||||
{
|
||||
obs_data_array_t *undo_array = obs_data_array_create();
|
||||
|
||||
obs_source_enum_full_tree(scene_source, save_undo_source_enum,
|
||||
undo_array);
|
||||
if (!sources) {
|
||||
obs_scene_enum_items(scene, save_undo_source_enum, undo_array);
|
||||
} else {
|
||||
for (obs_source_t *source : *sources) {
|
||||
obs_data_t *source_data = obs_save_source(source);
|
||||
obs_data_array_push_back(undo_array, source_data);
|
||||
obs_data_release(source_data);
|
||||
}
|
||||
}
|
||||
|
||||
obs_data_t *scene_data = obs_save_source(scene_source);
|
||||
obs_data_t *scene_data = obs_save_source(obs_scene_get_source(scene));
|
||||
obs_data_array_push_back(undo_array, scene_data);
|
||||
obs_data_release(scene_data);
|
||||
|
||||
|
@ -5479,6 +5508,13 @@ OBSData OBSBasic::BackupScene(obs_source_t *scene_source)
|
|||
return data;
|
||||
}
|
||||
|
||||
static bool add_source_enum(obs_scene_t *, obs_sceneitem_t *item, void *p)
|
||||
{
|
||||
auto sources = static_cast<std::vector<obs_source_t *> *>(p);
|
||||
sources->push_back(obs_sceneitem_get_source(item));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
|
||||
OBSData undo_data, OBSData redo_data)
|
||||
{
|
||||
|
@ -5486,9 +5522,10 @@ void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
|
|||
obs_data_t *base = obs_data_create_from_json(json.c_str());
|
||||
obs_data_array_t *array = obs_data_get_array(base, "array");
|
||||
std::vector<obs_source_t *> sources;
|
||||
std::vector<obs_source_t *> old_sources;
|
||||
|
||||
/* create missing sources */
|
||||
size_t count = obs_data_array_count(array);
|
||||
const size_t count = obs_data_array_count(array);
|
||||
sources.reserve(count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
|
@ -5498,12 +5535,16 @@ void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
|
|||
obs_source_t *source = obs_get_source_by_name(name);
|
||||
if (!source)
|
||||
source = obs_load_source(data);
|
||||
|
||||
sources.push_back(source);
|
||||
|
||||
/* update scene/group settings to restore their
|
||||
* contents to their saved settings */
|
||||
if (obs_source_is_group(source) ||
|
||||
obs_source_is_scene(source)) {
|
||||
* contents to their saved settings */
|
||||
obs_scene_t *scene =
|
||||
obs_group_or_scene_from_source(source);
|
||||
if (scene) {
|
||||
obs_scene_enum_items(scene, add_source_enum,
|
||||
&old_sources);
|
||||
obs_data_t *scene_settings =
|
||||
obs_data_get_obj(data, "settings");
|
||||
obs_source_update(source, scene_settings);
|
||||
|
@ -5512,6 +5553,8 @@ void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
|
|||
|
||||
obs_data_release(data);
|
||||
}
|
||||
for (obs_source_t *source : old_sources)
|
||||
obs_source_addref(source);
|
||||
|
||||
/* actually load sources now */
|
||||
for (obs_source_t *source : sources)
|
||||
|
@ -5520,6 +5563,8 @@ void OBSBasic::CreateSceneUndoRedoAction(const QString &action_name,
|
|||
/* release sources */
|
||||
for (obs_source_t *source : sources)
|
||||
obs_source_release(source);
|
||||
for (obs_source_t *source : old_sources)
|
||||
obs_source_release(source);
|
||||
|
||||
obs_data_array_release(array);
|
||||
obs_data_release(base);
|
||||
|
@ -5633,15 +5678,21 @@ void OBSBasic::MoveSceneItem(enum obs_order_movement movement,
|
|||
if (!source)
|
||||
return;
|
||||
|
||||
OBSSource scene_source = GetCurrentSceneSource();
|
||||
OBSData undo_data = BackupScene(scene_source);
|
||||
OBSScene scene = GetCurrentScene();
|
||||
std::vector<obs_source_t *> sources;
|
||||
if (scene != obs_sceneitem_get_scene(item))
|
||||
sources.push_back(
|
||||
obs_scene_get_source(obs_sceneitem_get_scene(item)));
|
||||
|
||||
OBSData undo_data = BackupScene(scene, &sources);
|
||||
|
||||
obs_sceneitem_set_order(item, movement);
|
||||
|
||||
const char *source_name = obs_source_get_name(source);
|
||||
const char *scene_name = obs_source_get_name(scene_source);
|
||||
const char *scene_name =
|
||||
obs_source_get_name(obs_scene_get_source(scene));
|
||||
|
||||
OBSData redo_data = BackupScene(scene_source);
|
||||
OBSData redo_data = BackupScene(scene, &sources);
|
||||
CreateSceneUndoRedoAction(action_name.arg(source_name, scene_name),
|
||||
undo_data, redo_data);
|
||||
}
|
||||
|
|
|
@ -860,14 +860,18 @@ public:
|
|||
|
||||
void ShowStatusBarMessage(const QString &message);
|
||||
|
||||
static OBSData BackupScene(obs_source_t *scene_source);
|
||||
static OBSData
|
||||
BackupScene(obs_scene_t *scene,
|
||||
std::vector<obs_source_t *> *sources = nullptr);
|
||||
void CreateSceneUndoRedoAction(const QString &action_name,
|
||||
OBSData undo_data, OBSData redo_data);
|
||||
|
||||
static inline OBSData BackupScene(obs_scene_t *scene)
|
||||
static inline OBSData
|
||||
BackupScene(obs_source_t *scene_source,
|
||||
std::vector<obs_source_t *> *sources = nullptr)
|
||||
{
|
||||
obs_source_t *source = obs_scene_get_source(scene);
|
||||
return BackupScene(source);
|
||||
obs_scene_t *scene = obs_scene_from_source(scene_source);
|
||||
return BackupScene(scene, sources);
|
||||
}
|
||||
|
||||
void CreateFilterPasteUndoRedoAction(const QString &text,
|
||||
|
|
Loading…
Reference in New Issue