Workspaces: reference count screens, otherwise they are never freed.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 12 Sep 2018 10:31:31 +0000 (12:31 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 13 Sep 2018 12:44:36 +0000 (14:44 +0200)
They are not directly accessible in the UI anymore, it's the workspaces
that we always keep until they are manually deleted now.

source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/workspace.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_workspace_types.h

index c569f43e7f461ea3c8a9f975187d7423ae19d3c9..27f0b653347182ce0c710d9f5de90a6717c654ca 100644 (file)
@@ -950,7 +950,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 
                                        /* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
                                         * However we can't acess layout->screen here since we are outside the workspace project. */
-                                       CALLBACK_INVOKE(screen, IDWALK_CB_NOP);
+                                       CALLBACK_INVOKE(screen, IDWALK_CB_USER);
                                        /* allow callback to set a different screen */
                                        BKE_workspace_layout_screen_set(layout, screen);
                                }
index a5e93c8d765eac2471971af8747f28eb8ebaf1cb..2829708391fb1c5671083f8caca54c42b5322643 100644 (file)
@@ -243,6 +243,7 @@ WorkSpaceLayout *BKE_workspace_layout_add(
        UNUSED_VARS(bmain);
 #endif
        layout->screen = screen;
+       id_us_plus(&layout->screen->id);
        workspace_layout_name_set(workspace, layout, name);
        BLI_addtail(&workspace->layouts, layout);
 
@@ -253,7 +254,8 @@ void BKE_workspace_layout_remove(
         Main *bmain,
         WorkSpace *workspace, WorkSpaceLayout *layout)
 {
-       BKE_libblock_free(bmain, BKE_workspace_layout_screen_get(layout));
+       id_us_min(&layout->screen->id);
+       BKE_libblock_free(bmain, layout->screen);
        BLI_freelinkN(&workspace->layouts, layout);
 }
 
index 810bc466275bb7f88977488ea8e4809c211688a1..b774bb8d1f623bd00c9842661e7e4717aeaa2745 100644 (file)
@@ -2949,15 +2949,13 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
                id_us_ensure_real(id);
 
                for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
-                       bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout));
+                       layout->screen = newlibadr_us(fd, id->lib, layout->screen);
 
                        layout_next = layout->next;
-                       if (screen) {
-                               BKE_workspace_layout_screen_set(layout, screen);
-
+                       if (layout->screen) {
                                if (ID_IS_LINKED(id)) {
-                                       screen->winid = 0;
-                                       if (screen->temp) {
+                                       layout->screen->winid = 0;
+                                       if (layout->screen->temp) {
                                                /* delete temp layouts when appending */
                                                BKE_workspace_layout_remove(bmain, workspace, layout);
                                        }
@@ -7251,7 +7249,6 @@ static void lib_link_screen(FileData *fd, Main *main)
        for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
                if (sc->id.tag & LIB_TAG_NEED_LINK) {
                        IDP_LibLinkProperty(sc->id.properties, fd);
-                       id_us_ensure_real(&sc->id);
 
                        /* deprecated, but needed for versioning (will be NULL'ed then) */
                        sc->scene = newlibadr(fd, sc->id.lib, sc->scene);
index 57aa5111addac0319a1f4f054ace5e5e5647bb43..16bc845a3e987230e140ea6463c1575642bc5ac5 100644 (file)
@@ -3005,15 +3005,18 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
 
 static void write_screen(WriteData *wd, bScreen *sc)
 {
-       /* write LibData */
-       /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
-       writestruct(wd, ID_SCRN, bScreen, 1, sc);
-       write_iddata(wd, &sc->id);
+       /* Screens are reference counted, only saved if used by a workspace. */
+       if (sc->id.us > 0 || wd->use_memfile) {
+               /* write LibData */
+               /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
+               writestruct(wd, ID_SCRN, bScreen, 1, sc);
+               write_iddata(wd, &sc->id);
 
-       write_previews(wd, sc->preview);
+               write_previews(wd, sc->preview);
 
-       /* direct data */
-       write_area_map(wd, AREAMAP_FROM_SCREEN(sc));
+               /* direct data */
+               write_area_map(wd, AREAMAP_FROM_SCREEN(sc));
+       }
 }
 
 static void write_bone(WriteData *wd, Bone *bone)
index ad047a85c189f163ee23bcbfd05b0ea5a5407f38..296fa8a713c3102c41b11d59e6d68ee81db0fe43 100644 (file)
@@ -111,7 +111,7 @@ typedef struct bToolRef {
 typedef struct WorkSpaceLayout {
        struct WorkSpaceLayout *next, *prev;
 
-       struct bScreen *screen DNA_PRIVATE_WORKSPACE;
+       struct bScreen *screen;
        /* The name of this layout, we override the RNA name of the screen with this (but not ID name itself) */
        char name[64] DNA_PRIVATE_WORKSPACE; /* MAX_NAME */
 } WorkSpaceLayout;