[Bf-blender-cvs] [c33f98f] asset-engine: AssetEngine previews: fix some issues, make Amber generate dummy ones as test/example.

Bastien Montagne noreply at git.blender.org
Sun Aug 14 13:15:29 CEST 2016


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));
 }




More information about the Bf-blender-cvs mailing list