Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-05-24 18:28:35 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-05-25 12:16:58 +0300
commit03a80facfc78178632086179e36f1c67128d5c09 (patch)
tree886d3eb3a6bc5cb68aaaae07aa8e0527e4882609 /source/blender/blenkernel/intern/workspace.c
parent08da2826e0f29a6a43b60deb3b31dac8dba22e6d (diff)
Fix T55183, fix T55174: crashes with workspace / view layer relation.
Don't store pointers to ViewLayer in the workspace, only names. Add specific relation type since the generic mechanism makes the code hard to follow. Integrate with pointer restore for undo and library remapping code to avoid data going out of sync. Also add relation automatically if there doesn't exists one yet in BKE_workspace_view_layer_get, because in general it's really hard to ensure it will exist when making arbitrary scene changes. Differential Revision: https://developer.blender.org/D3432
Diffstat (limited to 'source/blender/blenkernel/intern/workspace.c')
-rw-r--r--source/blender/blenkernel/intern/workspace.c80
1 files changed, 61 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 7fc0d814089..73b1defe8e6 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -26,6 +26,7 @@
#define DNA_PRIVATE_WORKSPACE_ALLOW
#include <stdlib.h>
+#include <string.h>
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -117,18 +118,6 @@ static void *workspace_relation_get_data_matching_parent(
}
}
-static void workspace_relation_remove_from_value(
- ListBase *relation_list, const void *value)
-{
- for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
- relation_next = relation->next;
-
- if (relation->value == value) {
- workspace_relation_remove(relation_list, relation);
- }
- }
-}
-
/**
* Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
* WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -168,7 +157,7 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
void BKE_workspace_free(WorkSpace *workspace)
{
BKE_workspace_relations_free(&workspace->hook_layout_relations);
- BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
+ BLI_freelistN(&workspace->scene_relations);
BLI_freelistN(&workspace->owner_ids);
BLI_freelistN(&workspace->layouts);
@@ -269,16 +258,45 @@ void BKE_workspace_relations_free(
}
}
+void BKE_workspace_scene_relations_free_invalid(
+ WorkSpace *workspace)
+{
+ for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first, *relation_next; relation; relation = relation_next) {
+ relation_next = relation->next;
+
+ if (relation->scene == NULL) {
+ BLI_freelinkN(&workspace->scene_relations, relation);
+ }
+ else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) {
+ BLI_freelinkN(&workspace->scene_relations, relation);
+ }
+ }
+}
/* -------------------------------------------------------------------- */
/* General Utils */
-void BKE_workspace_view_layer_remove_references(
+void BKE_workspace_view_layer_rename(
const Main *bmain,
- const ViewLayer *view_layer)
+ const Scene *scene,
+ const char *old_name,
+ const char *new_name)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer);
+ for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first; relation; relation = relation->next) {
+ if (relation->scene == scene && STREQ(relation->view_layer, old_name)) {
+ STRNCPY(relation->view_layer, new_name);
+ }
+ }
+ }
+}
+
+void BKE_workspace_view_layer_remove(
+ const Main *bmain,
+ const ViewLayer *UNUSED(view_layer))
+{
+ for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ BKE_workspace_scene_relations_free_invalid(workspace);
}
}
@@ -408,13 +426,38 @@ Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *sce
return view_layer->basact;
}
+ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene)
+{
+ WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+ return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL;
+}
+
ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
{
- return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene);
+ ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene);
+
+ if (layer == NULL) {
+ BKE_workspace_view_layer_set((WorkSpace*)workspace, scene->view_layers.first, (Scene *)scene);
+ layer = scene->view_layers.first;
+ }
+
+ return layer;
}
+
void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
{
- workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer);
+ WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+ if (relation == NULL) {
+ relation = MEM_callocN(sizeof(*relation), __func__);
+ }
+ else {
+ BLI_remlink(&workspace->scene_relations, relation);
+ }
+
+ /* (Re)insert at the head of the list, for faster lookups. */
+ relation->scene = scene;
+ STRNCPY(relation->view_layer, layer->name);
+ BLI_addhead(&workspace->scene_relations, relation);
}
ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
@@ -422,7 +465,6 @@ ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
return &workspace->layouts;
}
-
const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout)
{
return layout->name;