[Bf-blender-cvs] [9804f91] asset-engine: Make 'check update' async, and add possibilities for engines to make async callbacks 'immediate'.

Bastien Montagne noreply at git.blender.org
Mon Apr 11 21:32:46 CEST 2016


Commit: 9804f9181fe3fb31a89497a7a2a9b5f128372067
Author: Bastien Montagne
Date:   Mon Apr 11 17:35:31 2016 +0200
Branches: asset-engine
https://developer.blender.org/rB9804f9181fe3fb31a89497a7a2a9b5f128372067

Make 'check update' async, and add possibilities for engines to make async callbacks 'immediate'.

So now, jobs callback (async ones) of asset may return a specific job id value in case they actually
complete (or fail) on the first run.

This allows engines that do not need slow async stuff to perform an action to use simpler code
(e.g. imagine an engine able to list its assets from a cached DB, in most cases its list_dir
callback can execute instantaneously (from a user PoV), no need for a listing job then).

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

M	release/scripts/startup/bl_operators/amber.py
M	source/blender/blenkernel/BKE_asset.h
M	source/blender/blenkernel/intern/blender.c
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 bef43f9..2cb7c6d 100644
--- a/release/scripts/startup/bl_operators/amber.py
+++ b/release/scripts/startup/bl_operators/amber.py
@@ -441,6 +441,12 @@ class AssetEngineAmber(AssetEngine):
             self.tags.clear()
         return job_id
 
+    def update_check(self, job_id, uuids):
+        # do nothing for now, no need to use actual job...
+        for uuid in uuids.uuids:
+            uuid.use_asset_reload = True
+        return self.job_id_invalid
+
     def load_pre(self, uuids, entries):
         # Not quite sure this engine will need it in the end, but for sake of testing...
         if self.repo:
@@ -476,12 +482,6 @@ class AssetEngineAmber(AssetEngine):
         #~ print(entries.root_path)
         pass
 
-    def update_check(self, uuids):
-        # do nothing for now...
-        for uuid in uuids.uuids:
-            uuid.use_asset_reload = True
-        return True
-
     def sort_filter(self, use_sort, use_filter, params, entries):
 #        print(use_sort, use_filter)
         if use_filter:
diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index 5a2319d..043cfd7 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -74,9 +74,17 @@ typedef void (*ae_kill)(struct AssetEngine *engine, const int job_id);
 
 /* Those callbacks will be called from a 'fake-job' start *and* update functions (i.e. main thread, working one will
  * just sleep).
- * If given id is not null, engine should update from a running job if available, otherwise it should start a new one.
+ *
+ * If given id is not AE_JOB_ID_UNSET, engine should update from a running job if available, otherwise it should
+ * start a new one.
  * It is the responsability of the engine to start/stop background processes to actually perform tasks as/if needed.
+ *
+ * If the engine returns AE_JOB_ID_INVALID as job id, then code assumes whole execution was done in that single first
+ * call (i.e. allows engine that do not need it to not bother with whole async crap - they should then process
+ * the whole request in a very short amount of time (typically below 100ms).
  */
+#define AE_JOB_ID_UNSET 0
+#define AE_JOB_ID_INVALID -1
 
 /* FILEBROWSER - List everything available at given root path - only returns numbers of entries! */
 typedef int (*ae_list_dir)(struct AssetEngine *engine, const int job_id, struct FileDirEntryArr *entries_r);
@@ -84,6 +92,13 @@ typedef int (*ae_list_dir)(struct AssetEngine *engine, const int job_id, struct
 /* Ensure given assets (uuids) are really available for append/link (some kind of 'anticipated loading'...). */
 typedef int (*ae_ensure_entries)(struct AssetEngine *engine, const int job_id, struct AssetUUIDList *uuids);
 
+/* 'update' hook, called to prepare updating of given entries (typically after a file (re)load).
+ * Engine should check whether given assets are still valid, if they should be updated, etc.
+ * uuids tagged as needing reload will then be reloaded as new ones
+ * (ae_load_pre, then actual lib loading, then ae_load_post).
+ * \warning DO NOT add or remove (or alter order of) uuids from the list in this callback! */
+typedef int (*ae_update_check)(struct AssetEngine *engine, const int job_id, struct AssetUUIDList *uuids);
+
 /* ***** All callbacks below are blocking. They shall be completed upon return. ***** */
 
 /* FILEBROWSER - Perform sorting and/or filtering on engines' side.
@@ -121,14 +136,6 @@ typedef bool (*ae_load_post)(struct AssetEngine *engine, struct ID *items, const
  * r_dir is assumed to be least FILE_MAX. */
 typedef void (*ae_check_dir)(struct AssetEngine *engine, char *r_dir);
 
-/* 'update' hook, called to prepare updating of given entries (typically after a file (re)load).
- * Engine should check whether given assets are still valid, if they should be updated, etc.
- * uuids tagged as needing reload will then be reloaded as new ones
- * (ae_load_pre, then actual lib loading, then ae_load_post).
- * \warning DO NOT add or remove (or alter order of) uuids from the list in this callback! */
-/* XXX Should we make this non-blocking too? */
-typedef bool (*ae_update_check)(struct AssetEngine *engine, struct AssetUUIDList *uuids);
-
 typedef struct AssetEngineType {
 	struct AssetEngineType *next, *prev;
 
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2e92428..e3b03a6 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -583,10 +583,11 @@ static void read_file_update_assets(bContext *C)
 				continue;  /* uuids.uuids has not been allocated either, we can skip to next lib safely. */
 			}
 
-			const int nbr_uuids = uuids.nbr_uuids;
-			ae_type->update_check(ae, &uuids);
-
-			BLI_assert(nbr_uuids == uuids.nbr_uuids);
+			const int job_id = ae_type->update_check(ae, AE_JOB_ID_UNSET, &uuids);
+			if (job_id != AE_JOB_ID_INVALID) {
+				while (ae_type->status(ae, job_id) & AE_STATUS_RUNNING);
+				ae_type->kill(ae, job_id);
+			}
 
 			/* Note: UUIDs list itself is not editable from py (adding/removing/reordering items), so we can use mere
 			 *       order to map returned uuid data to their IDs. */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 90f7224..54545f7 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2821,6 +2821,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
 	if (flrj->filelist->ae) {
 		flrj->progress = progress;
 		flrj->stop = stop;
+		flrj->ae_job_id = AE_JOB_ID_UNSET;
 		/* When using AE engine, worker thread here is just sleeping! */
 		while ((flrj->filelist->flags & FL_IS_PENDING) && !*stop) {
 			PIL_sleep_ms(10);
@@ -2862,14 +2863,29 @@ static void filelist_readjob_update(void *flrjv)
 		/* We only communicate with asset engine from main thread! */
 		AssetEngine *ae = flrj->filelist->ae;
 
+		if (flrj->ae_job_id == AE_JOB_ID_INVALID) {
+			BLI_assert(0);  /* Should never reach this point... */
+			*flrj->progress = 1.0f;
+			*flrj->stop = true;
+			return;
+		}
+
 		flrj->ae_job_id = ae->type->list_dir(ae, flrj->ae_job_id, &flrj->filelist->filelist);
 
 		flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
 
-		*flrj->progress = ae->type->progress(ae, flrj->ae_job_id);
-		if ((ae->type->status(ae, flrj->ae_job_id) & (AE_STATUS_RUNNING | AE_STATUS_VALID)) != (AE_STATUS_RUNNING | AE_STATUS_VALID)) {
+		if (flrj->ae_job_id == AE_JOB_ID_INVALID) {
+			*flrj->progress = 1.0f;
 			*flrj->stop = true;
 		}
+		else {
+			*flrj->progress = ae->type->progress(ae, flrj->ae_job_id);
+			if ((ae->type->status(ae, flrj->ae_job_id) & (AE_STATUS_RUNNING | AE_STATUS_VALID)) !=
+			    (AE_STATUS_RUNNING | AE_STATUS_VALID))
+			{
+				*flrj->stop = true;
+			}
+		}
 	}
 	else {
 		FileListIntern *fl_intern = &flrj->filelist->filelist_intern;
@@ -2907,13 +2923,16 @@ static void filelist_readjob_endjob(void *flrjv)
 {
 	FileListReadJob *flrj = flrjv;
 
-	/* In case there would be some dangling update... */
-	filelist_readjob_update(flrjv);
+	/* In case there would be some dangling update.
+	 * Do not do this in case of ae job returning AE_JOB_ID_INVALID as job_id (immediate execution). */
+	if (flrj->filelist->ae == NULL || flrj->ae_job_id != AE_JOB_ID_INVALID) {
+		filelist_readjob_update(flrjv);
+	}
 
 	flrj->filelist->flags &= ~FL_IS_PENDING;
 	flrj->filelist->flags |= FL_IS_READY;
 
-	if (flrj->filelist->ae) {
+	if (flrj->filelist->ae && flrj->ae_job_id != 0) {
 		AssetEngine *ae = flrj->filelist->ae;
 		ae->type->kill(ae, flrj->ae_job_id);
 	}
diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c
index 72d4355..5b27985 100644
--- a/source/blender/makesrna/intern/rna_asset.c
+++ b/source/blender/makesrna/intern/rna_asset.c
@@ -341,7 +341,7 @@ static int rna_ae_status(AssetEngine *engine, const int id)
 	return ret_status;
 }
 
-static float rna_ae_progress(AssetEngine *engine, const int id)
+static float rna_ae_progress(AssetEngine *engine, const int job_id)
 {
 	extern FunctionRNA rna_AssetEngine_progress_func;
 	PointerRNA ptr;
@@ -352,11 +352,13 @@ static float rna_ae_progress(AssetEngine *engine, const int id)
 	void *ret;
 	float ret_progress;
 
+	BLI_assert(job_id != AE_JOB_ID_INVALID);
+
 	RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
 	func = &rna_AssetEngine_progress_func;
 
 	RNA_parameter_list_create(&list, &ptr, func);
-	RNA_parameter_set_lookup(&list, "job_id", &id);
+	RNA_parameter_set_lookup(&list, "job_id", &job_id);
 	engine->type->ext.call(NULL, &ptr, func, &list);
 
 	parm = RNA_function_find_parameter(NULL, func, "progress_return");
@@ -368,24 +370,26 @@ static float rna_ae_progress(AssetEngine *engine, const int id)
 	return ret_progress;
 }
 
-static void rna_ae_kill(AssetEngine *engine, const int id)
+static void rna_ae_kill(AssetEngine *engine, const int job_id)
 {
 	extern FunctionRNA rna_AssetEngine_kill_func;
 	PointerRNA ptr;
 	ParameterList list;
 	FunctionRNA *func;
 
+	BLI_assert(job_id != AE_JOB_ID_INVALID);
+
 	RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
 	func = &rna_AssetEngine_kill_func;
 
 	RNA_parameter_list_create(&list, &ptr, func);
-	RNA_parameter_set_lookup(&list, "job_id", &id);
+	RNA_parameter_set_lookup(&list, "job_id", &job_id);
 	engine->type->ext.call(NULL, &ptr, func, &list);
 
 	RNA_parameter_list_free(&list);
 }
 
-static int rna_ae_list_dir(AssetEngine *engine, const int id, FileDirEntryArr *entries_r)
+static int rna_ae_list_dir(AssetEngine *engine, const int job_id, FileDirEntryArr *entries_r)
 {
 	extern FunctionRNA rna_AssetEngine_list_dir_func;
 	PointerRNA ptr;
@@ -396,11 +400,13 @@ static int rna_ae_list_dir(AssetEngine *engine, const int id, FileDirEntryArr *e
 	void *ret;
 	int ret_job_id;
 
+	BLI_assert(job_id != AE_JOB_ID_INVALID);
+
 	RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
 	func = &rna_AssetEngine_list_dir_func;
 
 	RNA_parameter_list_create(&list, &ptr, func

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list