[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