[Bf-blender-cvs] [c8f9be2930] workspaces: Fix crashes when reading files saved with workspace branch

Julian Eisel noreply at git.blender.org
Wed Mar 15 12:03:30 CET 2017


Commit: c8f9be2930d7f353e163d9205e8ea07d25866314
Author: Julian Eisel
Date:   Wed Mar 15 12:01:34 2017 +0100
Branches: workspaces
https://developer.blender.org/rBc8f9be2930d7f353e163d9205e8ea07d25866314

Fix crashes when reading files saved with workspace branch

Wasn't easy to solve this and would prefer a more elegant solution,
commented in code what the issues are.

===================================================================

M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/blenloader/intern/writefile.c

===================================================================

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2873fcef9c..4b66835d0e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2773,25 +2773,35 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
 	BKE_workspace_iter_end;
 }
 
-static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook, ID *id)
+static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main *main)
 {
-	WorkSpace *workspace = BKE_workspace_active_get(hook);
-	BKE_workspace_active_set(hook, newlibadr(fd, id->lib, workspace));
-}
+	link_list(fd, BKE_workspace_layouts_get(workspace));
 
-static void direct_link_workspace(FileData *fd, WorkSpace *ws)
-{
-	SceneLayer *layer = BKE_workspace_render_layer_get(ws);
-	link_list(fd, BKE_workspace_layouts_get(ws));
-	BKE_workspace_render_layer_set(ws, newdataadr(fd, layer));
+	/* Same issue/fix as in direct_link_scene_update_screen_data: Can't read workspace data
+	 * when reading windows, so have to update windows after/when reading workspaces. */
+	for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) {
+		for (wmWindow *win = wm->windows.first; win; win = win->next) {
+			WorkSpaceLayout *act_layout = newdataadr(fd, BKE_workspace_active_layout_get(win->workspace_hook));
+			if (act_layout) {
+				BKE_workspace_active_layout_set(win->workspace_hook, act_layout);
+			}
+		}
+	}
 }
 
-static void direct_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook)
+static void lib_link_workspace_instance_hook(FileData *fd, WorkSpaceInstanceHook *hook, ID *id)
 {
+	WorkSpace *workspace = BKE_workspace_active_get(hook);
 	WorkSpaceLayout *act_layout = BKE_workspace_active_layout_get(hook);
-	BKE_workspace_active_layout_set(hook, newdataadr(fd, act_layout));
+
+	BKE_workspace_active_set(hook, newlibadr(fd, id->lib, workspace));
+	if (act_layout) {
+		bScreen *screen = BKE_workspace_layout_screen_get(act_layout);
+		BKE_workspace_layout_screen_set(act_layout, newlibadr(fd, id->lib, screen));
+	}
 }
 
+
 /* ************ READ MOTION PATHS *************** */
 
 /* direct data for cache */
@@ -6047,16 +6057,26 @@ static void direct_link_layer_collections(FileData *fd, ListBase *lb)
 }
 
 /**
- * bScreen data may use pointers to Scene data. bScreens are however read before Scenes, meaning
- * FileData.datamap doesn't contain the Scene data when reading bScreens. This function should
- * be called during Scene direct linking to update needed pointers within bScreen data.
+ * bScreen data may use pointers to Scene data. We can't read this when reading screens
+ * though, so we have to update screens when/after reading scenes. This function should
+ * be called during Scene direct linking to update needed pointers within screen data
+ * (as in everything visible in the window, not just bScreen).
  *
  * Maybe we could change read order so that screens are read after scene. But guess that
- * would be asking for trouble. Depending on the write/read order sounds ugly anyway...
+ * would be asking for trouble. Depending on the write/read order sounds ugly anyway,
+ * Workspaces already depend on it...
  * -- Julian
  */
-static void direct_link_scene_update_screens(FileData *fd, const ListBase *screens)
+static void direct_link_scene_update_screen_data(
+        FileData *fd, const ListBase *workspaces, const ListBase *screens)
 {
+	BKE_workspace_iter_begin(workspace, workspaces->first)
+	{
+		SceneLayer *layer = newdataadr(fd, BKE_workspace_render_layer_get(workspace));
+		BKE_workspace_render_layer_set(workspace, layer);
+	}
+	BKE_workspace_iter_end;
+
 	for (bScreen *screen = screens->first; screen; screen = screen->id.next) {
 		for (ScrArea *area = screen->areabase.first; area; area = area->next) {
 			for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
@@ -6352,7 +6372,7 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
 		res->data = newdataadr(fd, res->data);
 	}
 
-	direct_link_scene_update_screens(fd, &bmain->screen);
+	direct_link_scene_update_screen_data(fd, &bmain->workspaces, &bmain->screen);
 }
 
 /* ************ READ WM ***************** */
@@ -6366,9 +6386,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 	
 	for (win = wm->windows.first; win; win = win->next) {
 		win->workspace_hook = newdataadr(fd, win->workspace_hook);
-		if (win->workspace_hook) { /* NULL for old files */
-			direct_link_workspace_instance_hook(fd, win->workspace_hook);
-		}
 
 		win->ghostwin = NULL;
 		win->eventstate = NULL;
@@ -8494,7 +8511,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
 			direct_link_cachefile(fd, (CacheFile *)id);
 			break;
 		case ID_WS:
-			direct_link_workspace(fd, (WorkSpace *)id);
+			direct_link_workspace(fd, (WorkSpace *)id, main);
 			break;
 	}
 	
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 23a8ec6327..220498a046 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -86,6 +86,11 @@ static void do_version_workspaces_before_lib_link(Main *main)
  */
 static void do_version_workspaces_after_lib_link(Main *main)
 {
+	for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+		WorkSpace *workspace = BLI_findstring(&main->workspaces, screen->id.name + 2, offsetof(ID, name) + 2);
+		BKE_workspace_render_layer_set(workspace, screen->scene->render_layers.first);
+	}
+
 	for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) {
 		for (wmWindow *win = wm->windows.first; win; win = win->next) {
 			bScreen *screen = win->screen;
@@ -96,7 +101,6 @@ static void do_version_workspaces_after_lib_link(Main *main)
 			BKE_workspace_active_set(win->workspace_hook, workspace);
 			BKE_workspace_active_layout_set(win->workspace_hook, layouts->first);
 			win->scene = screen->scene;
-			BKE_workspace_render_layer_set(workspace, win->scene->render_layers.first);
 
 			/* Deprecated from now on! */
 			win->screen = NULL;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 4346adaf04..b4bd618537 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2931,6 +2931,7 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb)
 
 		for (wmWindow *win = wm->windows.first; win; win = win->next) {
 			writestruct(wd, DATA, wmWindow, 1, win);
+			writestruct(wd, DATA, WorkSpaceInstanceHook, 1, win->workspace_hook);
 			writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format);
 		}
 	}
@@ -4043,6 +4044,7 @@ static bool write_file_handle(
 	mywrite_flush(wd);
 
 	write_windowmanagers(wd, &mainvar->wm);
+	write_workspaces(wd, &mainvar->workspaces); /* order matters: after wm, before scene */
 	write_screens(wd, &mainvar->screen);
 	write_movieclips(wd, &mainvar->movieclip);
 	write_masks(wd, &mainvar->mask);
@@ -4074,7 +4076,6 @@ static bool write_file_handle(
 	write_gpencils(wd, &mainvar->gpencil);
 	write_linestyles(wd, &mainvar->linestyle);
 	write_cachefiles(wd, &mainvar->cachefiles);
-	write_workspaces(wd, &mainvar->workspaces);
 	write_libraries(wd,  mainvar->next);
 
 	/* So changes above don't cause a 'DNA1' to be detected as changed on undo. */




More information about the Bf-blender-cvs mailing list