[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