Commit: c33f98f6ae9abed454788ea7c9a3462ca39a023d
Author: Bastien Montagne
Date:   Sun Aug 14 13:14:10 2016 +0200
Branches: asset-engine
https://developer.blender.org/rBc33f98f6ae9abed454788ea7c9a3462ca39a023d

AssetEngine previews: fix some issues, make Amber generate dummy ones as 
test/example.

So now, amber generates dummy mosaic-like random previews (with a 100ms delay 
to mimic
really slow process), everything seems to work just fine. ;)

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

M       release/scripts/startup/bl_operators/amber.py
M       source/blender/editors/space_file/filelist.c
M       source/blender/makesrna/intern/rna_asset.c

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

diff --git a/release/scripts/startup/bl_operators/amber.py 
b/release/scripts/startup/bl_operators/amber.py
index 66a5983..d78fc6a 100644
--- a/release/scripts/startup/bl_operators/amber.py
+++ b/release/scripts/startup/bl_operators/amber.py
@@ -45,6 +45,7 @@ import os
 import stat
 import struct
 import time
+import random
 
 
 AMBER_DB_NAME = "__amber_db.json"
@@ -255,6 +256,68 @@ class AmberJobList(AmberJob):
             tsk.cancel()
 
 
+class AmberJobPreviews(AmberJob):
+    @staticmethod
+    def preview(uuid):
+        time.sleep(0.1)  # 100% Artificial Lag (c)
+        w = random.randint(2, 8)
+        h = random.randint(2, 8)
+        return [w, h, [random.getrandbits(32) for i in range(w * h)]]
+
+    def start(self, uuids):
+        self.nbr = 0
+        self.preview_tasks = {uuid.uuid_asset[:]: 
self.executor.submit(self.preview, uuid.uuid_asset[:]) for uuid in uuids.uuids}
+        self.tot = len(self.preview_tasks)
+        self.status = {'VALID', 'RUNNING'}
+
+    def update(self, uuids):
+        self.status = {'VALID', 'RUNNING'}
+
+        uuids = {uuid.uuid_asset[:]: uuid for uuid in uuids.uuids}
+
+        new_uuids = set(uuids)
+        old_uuids = set(self.preview_tasks)
+        del_uuids = old_uuids - new_uuids
+        new_uuids -= old_uuids
+
+        for uuid in del_uuids:
+            self.preview_tasks[uuid].cancel()
+            del self.preview_tasks[uuid]
+
+        for uuid in new_uuids:
+            self.preview_tasks[uuid] = self.executor.submit(self.preview, uuid)
+
+        self.tot = len(self.preview_tasks)
+        self.nbr = 0
+
+        done_uuids = set()
+        for uuid, tsk in self.preview_tasks.items():
+            if tsk.done():
+                w, h, pixels = tsk.result()
+                uuids[uuid].preview_size = (w, h)
+                uuids[uuid].preview_pixels = pixels
+                self.nbr += 1
+                done_uuids.add(uuid)
+
+        for uuid in done_uuids:
+            del self.preview_tasks[uuid]
+
+        self.progress = self.nbr / self.tot
+        if not self.preview_tasks:
+            self.status = {'VALID'}
+
+    def __init__(self, executor, job_id, uuids):
+        super().__init__(executor, job_id)
+        self.preview_tasks = {}
+
+        self.start(uuids)
+
+    def __del__(self):
+        # Avoid useless work!
+        for tsk in self.preview_tasks.values():
+            tsk.cancel()
+
+
 ###########################
 # Main Asset Engine class.
 class AmberTag(PropertyGroup):
@@ -383,6 +446,7 @@ class AssetEngineAmber(AssetEngine):
             is_lib_browser = params.use_library_browsing
 
             layout.prop(params, "display_type", expand=True, text="")
+            layout.prop(params, "display_size", text="")
             layout.prop(params, "sort_method", expand=True, text="")
 
             layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
@@ -487,10 +551,21 @@ class AssetEngineAmber(AssetEngine):
             if repo_uuid not in amber_repos or not 
os.path.exists(os.path.join(amber_repos[repo_uuid], AMBER_DB_NAME)):
                 uuid.is_asset_missing = True
                 continue
-            # Here in theory here we'd reload given repo (async process) and 
check for asset's status...
+            # Here in theory we'd reload given repo (async process) and check 
for asset's status...
             uuid.use_asset_reload = True
         return self.job_id_invalid
 
+    def previews_get(self, job_id, uuids):
+        job = self.jobs.get(job_id, None)
+        #~ print(entries.root_path, job_id, job)
+        if job is not None and isinstance(job, AmberJobPreviews):
+            job.update(uuids)
+        else:
+            job_id = self.job_uuid
+            self.job_uuid += 1
+            self.jobs[job_id] = AmberJobPreviews(self.executor, job_id, uuids)
+        return job_id
+
     def load_pre(self, uuids, entries):
         # Not quite sure this engine will need it in the end, but for sake of 
testing...
         if uuids.asset_engine_version != self.bl_version:
diff --git a/source/blender/editors/space_file/filelist.c 
b/source/blender/editors/space_file/filelist.c
index 3718486..19c5e32 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2089,9 +2089,13 @@ bool filelist_cache_previews_update(FileList *filelist)
        bool changed = false;
 
        if (filelist->ae) {
+               if (cache->ae_preview_uuids.nbr_uuids == 0) {
+                       return changed;  /* Nothing to preview! */
+               }
+
                ae_previews_get previews_get = filelist->ae->type->previews_get;
                if (!previews_get) {
-                       printf("%s: engine does not supports previews...\n", 
__func__);
+                       printf("%s: engine %s does not supports previews...\n", 
__func__, filelist->ae->type->name);
                        return changed;
                }
 
@@ -2110,9 +2114,10 @@ bool filelist_cache_previews_update(FileList *filelist)
                        FileDirEntry *entry = 
filelist_entry_find_uuid(filelist, uuid->uuid_asset);
 
                        if (entry) {
-                               if (!(uuid->tag & UUID_TAG_ASSET_NOPREVIEW)) {
+                               /* Due to asynchronous process, a preview for a 
given image may be generated several times, i.e.
+                                * entry->image may already be set at this 
point. */
+                               if (!(uuid->tag & UUID_TAG_ASSET_NOPREVIEW) && 
!entry->image) {
                                        BLI_assert(uuid->ibuff != NULL && 
!ELEM(0, uuid->width, uuid->height));
-                                       BLI_assert(!entry->image);
 
                                        entry->image = 
IMB_allocFromBuffer((unsigned int *)uuid->ibuff, NULL, uuid->width, 
uuid->height);
                                        changed = true;
@@ -2131,19 +2136,28 @@ bool filelist_cache_previews_update(FileList *filelist)
                }
 
                /* Remove uuids already processed from list... */
-               int nbr_uuids_new = cache->ae_preview_uuids.nbr_uuids - 
uuids_done;
-               AssetUUID *uuids_new = MEM_callocN(sizeof(*uuids_new) * 
nbr_uuids_new, __func__);
-               for (int i = cache->ae_preview_uuids.nbr_uuids, j = 
nbr_uuids_new; i-- && j--;) {
-                       AssetUUID *uuid = &cache->ae_preview_uuids.uuids[i];
-                       if (uuid->flag == 0) {
-                               BLI_assert(uuid->ibuff == NULL);
-                               uuids_new[j] = *uuid;
+               const int nbr_uuids_new = cache->ae_preview_uuids.nbr_uuids - 
uuids_done;
+               AssetUUID *uuids_new = NULL;
+               if (nbr_uuids_new != 0) {
+                       uuids_new = MEM_callocN(sizeof(*uuids_new) * 
nbr_uuids_new, __func__);
+                       for (int i = cache->ae_preview_uuids.nbr_uuids, j = 
nbr_uuids_new; i-- && j--;) {
+                               AssetUUID *uuid = 
&cache->ae_preview_uuids.uuids[i];
+                               if (uuid->flag == 0) {
+                                       BLI_assert(uuid->ibuff == NULL);
+                                       uuids_new[j] = *uuid;
+                               }
                        }
                }
                MEM_freeN(cache->ae_preview_uuids.uuids);
                cache->ae_preview_uuids.uuids = uuids_new;
                cache->ae_preview_uuids.nbr_uuids = nbr_uuids_new;
 
+               if (cache->ae_preview_job == AE_JOB_ID_INVALID) {
+                       /* Preview task finished at once... */
+                       BLI_assert(nbr_uuids_new == 0);
+                       cache->ae_preview_job = AE_JOB_ID_UNSET;
+               }
+
                return changed;
        }
 
@@ -2195,7 +2209,7 @@ bool filelist_cache_previews_running(FileList *filelist)
 
        if (filelist->ae) {
                return ((cache->ae_preview_job > AE_JOB_ID_UNSET) &&
-                       (filelist->ae->type->status(filelist->ae, 
cache->ae_preview_job) == AE_STATUS_RUNNING));
+                       (filelist->ae->type->status(filelist->ae, 
cache->ae_preview_job) & AE_STATUS_RUNNING));
        }
        else {
                return (cache->previews_pool != NULL);
diff --git a/source/blender/makesrna/intern/rna_asset.c 
b/source/blender/makesrna/intern/rna_asset.c
index bb55214..962e5f4 100644
--- a/source/blender/makesrna/intern/rna_asset.c
+++ b/source/blender/makesrna/intern/rna_asset.c
@@ -91,6 +91,10 @@ static void rna_AssetUUID_preview_pixels_set(PointerRNA 
*ptr, const int *values)
 {
        AssetUUID *uuid = ptr->data;
 
+       if (!uuid->ibuff) {
+               uuid->ibuff = MEM_mallocN(sizeof(*uuid->ibuff) * 4 * 
uuid->width * uuid->height, __func__);
+       }
+
        memcpy(uuid->ibuff, values, uuid->width * uuid->height * 
sizeof(unsigned int));
 }

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

Reply via email to