Commit: 1cb68135fd02be478d73e9afa3f0c73e7042814b
Author: Bastien Montagne
Date:   Mon Apr 27 16:59:04 2015 +0200
Branches: ui-preview-buttons
https://developer.blender.org/rB1cb68135fd02be478d73e9afa3f0c73e7042814b

Rework previews handling to be 'simpler' on py-level, as discussed with Campbell

This removes ID-free previews handling from RNA, adds a low-level hidden API
in bpy.app._previews, and the real previews manager in bpy.utils.

There is still lots of cleanup and renaming to be done...

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

M       release/scripts/modules/bpy/utils.py
M       source/blender/blenkernel/BKE_icons.h
M       source/blender/blenkernel/intern/icons.c
M       source/blender/editors/interface/interface_icons.c
M       source/blender/makesrna/intern/rna_ID.c
M       source/blender/makesrna/intern/rna_brush.c
M       source/blender/makesrna/intern/rna_main_api.c
M       source/blender/python/intern/CMakeLists.txt
M       source/blender/python/intern/bpy_app.c
A       source/blender/python/intern/bpy_app_previews.c
A       source/blender/python/intern/bpy_app_previews.h

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

diff --git a/release/scripts/modules/bpy/utils.py 
b/release/scripts/modules/bpy/utils.py
index 5f235ae..3047f02 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -38,6 +38,7 @@ __all__ = (
     "unregister_manual_map",
     "make_rna_paths",
     "manual_map",
+    "previews",
     "resource_path",
     "script_path_user",
     "script_path_pref",
@@ -51,6 +52,7 @@ __all__ = (
     )
 
 from _bpy import (
+        app,
         escape_identifier,
         register_class,
         unregister_class,
@@ -697,3 +699,89 @@ def make_rna_paths(struct_name, prop_name, enum_name):
         else:
             src = src_rna = struct_name
     return src, src_rna, src_enum
+
+
+# High-level previews manager.
+class BPyPreviewsManager:
+    """
+    Fake module like class.
+
+    bpy.app.previews_manager
+    """
+    __slots__ = ('_previews_collections',)
+
+    def __init__(self):
+        self._previews_collections = {}
+
+    def __del__(self):
+        self.clear()
+
+    def new(self, name):
+        """
+        Return a new preview collection, or existing one if 'name' already 
exists.
+        """
+        return self._previews_collections.setdefault(name, 
BPyPreviewsCollection(name))
+
+    def _remove(self, name):
+        return self._previews_collections.pop(name, None)
+
+    def delete(self, name):
+        pcoll = self._remove(name)
+        if pcoll is not None:
+            del pcoll
+
+    def clear(self):
+        for pcoll in self._previews_collections.values():
+            del pcoll
+        self._previews_collections.clear()
+
+    def __repr__(self):
+        return "<module like class 'bpy.app.previews_manager'>"
+
+
+class BPyPreviewsCollection:
+    """
+    Fake dict-like class of previews.
+    """
+    __slots__ = ('_previews', '_coll_name')
+
+    def __init__(self, name):
+        self._previews = {}
+        self._coll_name = name
+
+    def __del__(self):
+        self.clear()
+
+    def _gen_key(self, name):
+        return self._coll_name + name
+
+    def new(self, name):
+        """
+        Return a new empty preview, or existing one if 'name' already exists.
+        """
+        return self._previews.setdefault(name, 
app._previews.new(self._gen_key(name)))
+
+    def load(self, name, path, path_type, force_reload=False):
+        """
+        Return a new preview from given file path, or existing one if 'name' 
already exists.
+        """
+        pkey = self._gen_key(name)
+        if force_reload:
+            self._previews[name] = p = app._previews.load(pkey, path, 
path_type, True)
+            return p
+        else:
+            return self._previews.setdefault(name, app._previews.load(pkey, 
path, path_type, False))
+
+    def release(self, name):
+        p = self._previews.pop(name, None)
+        if p is not None:
+            del p
+            app._previews.release(self._gen_key(name))
+
+    def clear(self):
+        for name in self._previews.keys():
+            _previews.release(self._gen_key(name))
+        self._previews.clear()
+
+previews = BPyPreviewsManager()
+
diff --git a/source/blender/blenkernel/BKE_icons.h 
b/source/blender/blenkernel/BKE_icons.h
index 58f3edf..a950caa 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -90,12 +90,16 @@ void BKE_previewimg_free_id(struct ID *id);
 /* create a new preview image */
 struct PreviewImage *BKE_previewimg_create(void);
 
-struct PreviewImage *BKE_previewimg_thumbnail_create(const char *path, const 
int source, bool force_update);
-
 /* create a copy of the preview image */
 struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv);
 
+struct PreviewImage *BKE_previewimg_name_get(const char *name);
+
+struct PreviewImage *BKE_previewimg_thumbnail_get(const char *name, const char 
*path, const int source, bool force_update);
+
+void BKE_previewimg_name_release(const char *name);
+
 /* retrieve existing or create new preview image */
-struct PreviewImage *BKE_previewimg_get(struct ID *id);
+struct PreviewImage *BKE_previewimg_id_get(struct ID *id);
 
 #endif /*  __BKE_ICONS_H__ */
diff --git a/source/blender/blenkernel/intern/icons.c 
b/source/blender/blenkernel/intern/icons.c
index 857fd1d..a54a80e 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -45,6 +45,7 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
+#include "BLI_string.h"
 
 #include "BKE_icons.h"
 #include "BKE_global.h" /* only for G.background test */
@@ -125,7 +126,7 @@ void BKE_icons_free(void)
        }
 
        if (gFilePreviews) {
-               BLI_ghash_free(gFilePreviews, NULL, BKE_previewimg_freefunc);
+               BLI_ghash_free(gFilePreviews, MEM_freeN, 
BKE_previewimg_freefunc);
                gFilePreviews = NULL;
        }
 }
@@ -144,72 +145,6 @@ PreviewImage *BKE_previewimg_create(void)
        return prv_img;
 }
 
-/**
- * Generate a PreviewImage from given file path, using thumbnails management.
- */
-PreviewImage *BKE_previewimg_thumbnail_create(const char *path, const int 
source, bool force_update)
-{
-       PreviewImage *prv = NULL;
-       void **prv_v;
-       int icon_w, icon_h;
-
-       prv_v = BLI_ghash_lookup_p(gFilePreviews, path);
-
-       if (prv_v) {
-               prv = *prv_v;
-               BLI_assert(prv);
-       }
-
-       if (prv && force_update) {
-               BKE_previewimg_clear(prv, ICON_SIZE_ICON);
-               BKE_previewimg_clear(prv, ICON_SIZE_PREVIEW);
-       }
-       else if (!prv) {
-               prv = BKE_previewimg_create();
-               force_update = true;
-       }
-
-       if (force_update) {
-               ImBuf *thumb = IMB_thumb_manage(path, THB_NORMAL, source);
-
-               if (thumb) {
-                       prv->w[ICON_SIZE_PREVIEW] = thumb->x;
-                       prv->h[ICON_SIZE_PREVIEW] = thumb->y;
-                       prv->rect[ICON_SIZE_PREVIEW] = 
MEM_dupallocN(thumb->rect);
-                       prv->flag[ICON_SIZE_PREVIEW] &= ~(CHANGED | 
USER_EDITED);
-
-                       if (thumb->x > thumb->y) {
-                               icon_w = ICON_RENDER_DEFAULT_HEIGHT;
-                               icon_h = (thumb->y * icon_w) / thumb->x + 1;
-                       }
-                       else if (thumb->x < thumb->y) {
-                               icon_h = ICON_RENDER_DEFAULT_HEIGHT;
-                               icon_w = (thumb->x * icon_h) / thumb->y + 1;
-                       }
-                       else {
-                               icon_w = icon_h = ICON_RENDER_DEFAULT_HEIGHT;
-                       }
-
-                       IMB_scaleImBuf(thumb, icon_w, icon_h);
-                       prv->w[ICON_SIZE_ICON] = icon_w;
-                       prv->h[ICON_SIZE_ICON] = icon_h;
-                       prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect);
-                       prv->flag[ICON_SIZE_ICON] &= ~(CHANGED | USER_EDITED);
-
-                       IMB_freeImBuf(thumb);
-               }
-
-               if (prv_v) {
-                       *prv_v = prv;
-               }
-               else {
-                       BLI_ghash_insert(gFilePreviews, (void *)path, prv);
-               }
-       }
-
-       return prv;
-}
-
 void BKE_previewimg_freefunc(void *link)
 {
        PreviewImage *prv = (PreviewImage *)link;
@@ -299,7 +234,114 @@ void BKE_previewimg_free_id(ID *id)
        }
 }
 
-PreviewImage *BKE_previewimg_get(ID *id)
+/**
+ * Generate an empty PreviewImage, if not yet existing.
+ */
+PreviewImage *BKE_previewimg_name_get(const char *name)
+{
+       PreviewImage *prv = NULL;
+       void **prv_v;
+
+       prv_v = BLI_ghash_lookup_p(gFilePreviews, name);
+
+       if (prv_v) {
+               prv = *prv_v;
+               BLI_assert(prv);
+       }
+
+       if (!prv) {
+               prv = BKE_previewimg_create();
+       }
+
+       if (prv_v) {
+               *prv_v = prv;
+       }
+       else {
+               BLI_ghash_insert(gFilePreviews, (void *)BLI_strdup(name), prv);
+       }
+
+       return prv;
+}
+
+/**
+ * Generate a PreviewImage from given file path, using thumbnails management, 
if not yet existing.
+ */
+PreviewImage *BKE_previewimg_thumbnail_get(const char *name, const char *path, 
const int source, bool force_update)
+{
+       PreviewImage *prv = NULL;
+       void **prv_v;
+       int icon_w, icon_h;
+
+       prv_v = BLI_ghash_lookup_p(gFilePreviews, name);
+
+       if (prv_v) {
+               prv = *prv_v;
+               BLI_assert(prv);
+       }
+
+       if (prv && force_update) {
+               BKE_previewimg_clear(prv, ICON_SIZE_ICON);
+               BKE_previewimg_clear(prv, ICON_SIZE_PREVIEW);
+       }
+       else if (!prv) {
+               prv = BKE_previewimg_create();
+               force_update = true;
+       }
+
+       if (force_update) {
+               ImBuf *thumb = IMB_thumb_manage(path, THB_NORMAL, source);
+
+               if (thumb) {
+                       prv->w[ICON_SIZE_PREVIEW] = thumb->x;
+                       prv->h[ICON_SIZE_PREVIEW] = thumb->y;
+                       prv->rect[ICON_SIZE_PREVIEW] = 
MEM_dupallocN(thumb->rect);
+                       prv->flag[ICON_SIZE_PREVIEW] &= ~(CHANGED | 
USER_EDITED);
+
+                       if (thumb->x > thumb->y) {
+                               icon_w = ICON_RENDER_DEFAULT_HEIGHT;
+                               icon_h = (thumb->y * icon_w) / thumb->x + 1;
+                       }
+                       else if (thumb->x < thumb->y) {
+                               icon_h = ICON_RENDER_DEFAULT_HEIGHT;
+                               icon_w = (thumb->x * icon_h) / thumb->y + 1;
+                       }
+                       else {
+                               icon_w = icon_h = ICON_RENDER_DEFAULT_HEIGHT;
+                       }
+
+                       IMB_scaleImBuf(thumb, icon_w, icon_h);
+                       prv->w[ICON_SIZE_ICON] = icon_w;
+                       prv->h[ICON_SIZE_ICON] = icon_h;
+                       prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect);
+                       prv->flag[ICON_SIZE_ICON] &= ~(CHANGED | USER_EDITED);
+
+                       IMB_freeImBuf(thumb);
+               }
+
+               if (prv_v) {
+                       *prv_v = prv;
+               }
+               else {
+                       BLI_ghash_insert(gFilePreviews, (void 
*)BLI_strdup(name), prv);
+               }
+       }
+
+       return prv;
+}
+
+void BKE_previewimg_name_release(const char *name)
+{
+       PreviewImage *prv = BLI_ghash_popkey(gFilePreviews, (void *)name, 
MEM_freeN);
+
+       if (prv) {
+               if (prv->icon_id) {
+                       BKE_icon_delete(prv->icon_id);
+               }
+               BKE_previewimg_freefunc(prv);
+       }
+}
+
+PreviewImage *BKE_previewimg_id_get(ID *id)
 {
        PreviewImage *prv_img = NULL;
 
@@ -346,7 +388,7 @@ void BKE_icon_changed(int id)
        icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id));
        
        if (icon) {
-               PreviewImage *prv = BKE_previewimg_get((ID *)icon->obj);
+               PreviewImage *prv = BKE_previewimg_id_get((ID *)icon->obj);
 
                /* all previews changed */
                if (prv) {
diff --git a/source/blender/editors/interface/interface_icons.c 
b/source/blender/editors/interface/interface_icons.c
index fb5960f..979cad1 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1156,7 +1156,7 @@ static void icon_draw_size(float x, float y, int icon_id, 
float aspect, float al
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        }
        else if (di->type == ICON_TYPE_PREVIEW) {
-               PreviewImage *pi = icon->type ? BKE_previewimg_get((ID 
*)icon->obj) : icon->obj;
+               PreviewImage *pi = icon->type ? BKE_previewimg_id_get((ID 
*)icon->obj) : icon->obj;
 
                if (pi) {
                        /* no create icon on this level in code */
@@ -1183,7 +1183,7 @@ static void u

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to