[Bf-blender-cvs] [473e702] asset-experiments: First step to add 'load_pre' behavior.

Bastien Montagne noreply at git.blender.org
Thu Mar 12 11:07:40 CET 2015


Commit: 473e702d5d83ba84656f85e11464d9d6cf6b8df8
Author: Bastien Montagne
Date:   Wed Mar 11 21:32:54 2015 +0100
Branches: asset-experiments
https://developer.blender.org/rB473e702d5d83ba84656f85e11464d9d6cf6b8df8

First step to add 'load_pre' behavior.

This will allow asset engines to:
* Actually ensure requested data is available (downloading it, generating it, etc. as needed).
* Change entries generated for user by actual data paths (allows e.g. to present
  a set of different paths to load as a single 'asset' to user).

As usual, had to change existing filebrowser code... Seems to be working fine
from quick tests (i.e. regular filebrowser not being broken).

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

M	source/blender/blenkernel/BKE_asset.h
M	source/blender/blenkernel/intern/asset.c
M	source/blender/editors/space_file/file_intern.h
M	source/blender/editors/space_file/file_ops.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/makesdna/DNA_space_types.h

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

diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index a0b6b65..8a3a173 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -36,15 +36,17 @@
 extern "C" {
 #endif
 
+#include "DNA_space_types.h"
+
 struct AssetEngine;
 struct AssetEngineType;
 struct FileDirEntryArr;
+struct FileDirEntry;
 struct ExtensionRNA;
+struct ID;
 struct ListBase;
 struct uiLayout;
 
-#include "DNA_space_types.h"
-
 enum {
 	AE_STATUS_VALID   = 1 << 0,
 	AE_STATUS_RUNNING = 1 << 1,  /* Asset engine is performing some background tasks... */
@@ -69,19 +71,22 @@ typedef void (*ae_kill)(struct AssetEngine *engine, const int job_id);
  */
 
 /* Return (list) everything available at given root path. */
-typedef int (*ae_list_dir)(struct AssetEngine *engine, const int id, struct FileDirEntryArr *entries_r);
+typedef int (*ae_list_dir)(struct AssetEngine *engine, const int job_id, struct FileDirEntryArr *entries_r);
 /* Ensure given direntries are really available for append/link (some kind of 'anticipated loading'...). */
-typedef int (*ae_ensure_entries)(struct AssetEngine *engine, const int id, char *uuids[ASSET_UUID_LENGTH], const int nbr_uuids);
+typedef int (*ae_ensure_entries)(struct AssetEngine *engine, const int job_id,
+                                 char (*uuids)[3][ASSET_UUID_LENGTH], const int nbr_uuids);
 
 /* ***** All callbacks below are blocking. They shall be completed upon return. ***** */
 
 /* 'pre-loading' hook, called before opening/appending/linking given entries.
+ * Note first given uuid is the one of 'active' entry, and first entry in returned list will be considered as such too.
  * E.g. allows the engine to ensure entries' paths are actually valid by downloading requested data, etc.
+ * If is_virtual is True, then there is no requirement that returned paths actually exist.
  * Note that the generated list shall be simpler than the one generated by ae_list_dir, since only the path from
  * active revision is used, no need to bother with variants, previews, etc.
  * This allows to present 'fake' entries to user, and then import actual data.
  */
-typedef bool (*ae_load_pre)(struct AssetEngine *engine, char *uuids[ASSET_UUID_LENGTH], const int nbr_uuids,
+typedef bool (*ae_load_pre)(struct AssetEngine *engine, char (*uuids)[3][ASSET_UUID_LENGTH], const int nbr_uuids,
                             struct FileDirEntryArr *entries_r);
 
 /* 'post-loading' hook, called after opening/appending/linking given entries.
@@ -133,6 +138,27 @@ AssetEngine *BKE_asset_engine_create(AssetEngineType *type);
 AssetEngine *BKE_asset_engine_copy(AssetEngine *engine);
 void BKE_asset_engine_free(AssetEngine *engine);
 
+void BKE_asset_engine_load_pre(AssetEngine *engine, struct FileDirEntryArr *r_entries);
+
+/* File listing utils... */
+
+typedef enum FileCheckType {
+	CHECK_NONE  = 0,
+	CHECK_DIRS  = 1 << 0,
+	CHECK_FILES = 1 << 1,
+	CHECK_ALL   = CHECK_DIRS | CHECK_FILES,
+} FileCheckType;
+
+#if 0  /* Unused */
+void BKE_filedir_entry_free(struct FileDirEntry *entry);
+void BKE_filedir_entry_clear(struct FileDirEntry *entry);
+#endif
+struct FileDirEntry *BKE_filedir_entry_copy(struct FileDirEntry *entry);
+
+void BKE_filedir_entryarr_clear(struct FileDirEntryArr *array);
+
+bool BKE_filedir_entry_is_selected(struct FileDirEntry *entry, FileCheckType check);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/asset.c b/source/blender/blenkernel/intern/asset.c
index 43fa1b4..f451cc9 100644
--- a/source/blender/blenkernel/intern/asset.c
+++ b/source/blender/blenkernel/intern/asset.c
@@ -49,6 +49,10 @@
 #include "BKE_report.h"
 #include "BKE_asset.h"
 
+#include "IMB_imbuf.h"
+
+#include "DNA_space_types.h"
+
 #ifdef WITH_PYTHON
 #include "BPY_extern.h"
 #endif
@@ -130,3 +134,207 @@ void BKE_asset_engine_free(AssetEngine *engine)
 		MEM_freeN(engine);
 	}
 }
+
+
+/* API helpers. */
+
+void BKE_asset_engine_load_pre(AssetEngine *engine, FileDirEntryArr *r_entries)
+{
+	if (engine->type->load_pre) {
+		FileDirEntry *en;
+		char (*uuids)[3][ASSET_UUID_LENGTH] = MEM_mallocN(sizeof(*uuids) * r_entries->nbr_entries, __func__);
+		int nbr_entries = r_entries->nbr_entries;
+		int i;
+
+		for (i = 0, en = r_entries->entries.first; en; i++, en = en->next) {
+			FileDirEntryVariant *var = BLI_findlink(&en->variants, en->act_variant);
+			char (*uuid)[3][ASSET_UUID_LENGTH] = &uuids[i];
+
+			memcpy(uuid[0], en->uuid, sizeof(*uuid[0]));
+
+			BLI_assert(var);
+			memcpy(uuid[1], var, sizeof(*uuid[1]));
+
+			memcpy(uuid[2], en->entry, sizeof(*uuid[2]));
+		}
+
+		BKE_filedir_entryarr_clear(r_entries);
+
+		engine->type->load_pre(engine, uuids, nbr_entries, r_entries);
+
+		MEM_freeN(uuids);
+	}
+}
+
+
+/* FileDirxxx handling. */
+
+#if 0 /* Unused */
+void BKE_filedir_entry_free(FileDirEntry *entry)
+{
+	if (entry->name) {
+		MEM_freeN(entry->name);
+	}
+	if (entry->description) {
+		MEM_freeN(entry->description);
+	}
+	if (entry->relpath) {
+		MEM_freeN(entry->relpath);
+	}
+	if (entry->image) {
+		IMB_freeImBuf(entry->image);
+	}
+	/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
+
+	if (!BLI_listbase_is_empty(&entry->variants)) {
+		FileDirEntryVariant *var;
+
+		for (var = entry->variants.first; var; var = var->next) {
+			if (var->name) {
+				MEM_freeN(var->name);
+			}
+			if (var->description) {
+				MEM_freeN(var->description);
+			}
+			BLI_freelistN(&var->revisions);
+		}
+
+		BLI_freelistN(&entry->variants);
+	}
+	else if (entry->entry){
+		MEM_freeN(entry->entry);
+	}
+
+	/* TODO: tags! */
+}
+
+void BKE_filedir_entry_clear(FileDirEntry *entry)
+{
+	BKE_filedir_entry_free(entry);
+	memset(entry, 0, sizeof(*entry));
+}
+#else
+static void BKE_filedir_entry_free(FileDirEntry *entry)
+{
+	if (entry->name) {
+		MEM_freeN(entry->name);
+	}
+	if (entry->description) {
+		MEM_freeN(entry->description);
+	}
+	if (entry->relpath) {
+		MEM_freeN(entry->relpath);
+	}
+	if (entry->image) {
+		IMB_freeImBuf(entry->image);
+	}
+	/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
+
+	if (!BLI_listbase_is_empty(&entry->variants)) {
+		FileDirEntryVariant *var;
+
+		for (var = entry->variants.first; var; var = var->next) {
+			if (var->name) {
+				MEM_freeN(var->name);
+			}
+			if (var->description) {
+				MEM_freeN(var->description);
+			}
+			BLI_freelistN(&var->revisions);
+		}
+
+		BLI_freelistN(&entry->variants);
+	}
+	else if (entry->entry){
+		MEM_freeN(entry->entry);
+	}
+
+	/* TODO: tags! */
+}
+#endif
+
+/** Perform and return a full (deep) duplicate of given entry. */
+FileDirEntry *BKE_filedir_entry_copy(FileDirEntry *entry)
+{
+	FileDirEntry *entry_new = MEM_dupallocN(entry);
+
+	if (entry->name) {
+		entry_new->name = MEM_dupallocN(entry->name);
+	}
+	if (entry->description) {
+		entry_new->description = MEM_dupallocN(entry->description);
+	}
+	if (entry->relpath) {
+		entry_new->relpath = MEM_dupallocN(entry->relpath);
+	}
+	if (entry->image) {
+		entry_new->image = IMB_dupImBuf(entry->image);
+	}
+	/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
+
+	if (!BLI_listbase_is_empty(&entry->variants)) {
+		FileDirEntryVariant *var;
+		int act_var;
+
+		BLI_listbase_clear(&entry_new->variants);
+		for (act_var = 0, var = entry->variants.first; var; act_var++, var = var->next) {
+			FileDirEntryVariant *var_new = MEM_dupallocN(var);
+			FileDirEntryRevision *rev;
+			const bool is_act_var = (act_var == entry->act_variant);
+			int act_rev;
+
+			if (var->name) {
+				var_new->name = MEM_dupallocN(var->name);
+			}
+			if (var->description) {
+				var_new->description = MEM_dupallocN(var->description);
+			}
+
+			BLI_listbase_clear(&var_new->revisions);
+			for (act_rev = 0, rev = var->revisions.first; rev; act_rev++, rev = rev->next) {
+				FileDirEntryRevision *rev_new = MEM_dupallocN(rev);
+				const bool is_act_rev = (act_rev == var->act_revision);
+
+				BLI_addtail(&var_new->revisions, rev_new);
+
+				if (is_act_var && is_act_rev) {
+					entry->entry = rev_new;
+				}
+			}
+
+			BLI_addtail(&entry_new->variants, var_new);
+		}
+
+	}
+	else if (entry->entry){
+		entry_new->entry = MEM_dupallocN(entry->entry);
+	}
+
+	/* TODO: tags! */
+
+	return entry_new;
+}
+
+void BKE_filedir_entryarr_clear(FileDirEntryArr *array)
+{
+	FileDirEntry *entry;
+
+	for (entry = array->entries.first; entry; entry = entry->next) {
+		BKE_filedir_entry_free(entry);
+	}
+	BLI_freelistN(&array->entries);
+    array->nbr_entries = 0;
+}
+
+bool BKE_filedir_entry_is_selected(FileDirEntry *entry, FileCheckType check)
+{
+	switch (check) {
+		case CHECK_DIRS:
+			return ((entry->typeflag & FILE_TYPE_DIR) != 0) && (entry->selflag & FILE_SEL_SELECTED);
+		case CHECK_FILES:
+			return ((entry->typeflag & FILE_TYPE_DIR) == 0) && (entry->selflag & FILE_SEL_SELECTED);
+		case CHECK_ALL:
+		default:
+			return (entry->selflag & FILE_SEL_SELECTED) != 0;
+	}
+}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index e7a6cd6..d96ded9 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -97,9 +97,6 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
 
 int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
 
-void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
-void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op);
-
 
 /* filesel.c */
 float file_shorten_string(char *string, float w, int front);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index ddf3bd2..9b3611f 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -33,9 +33,14 @@
 #include "BLI_fileops_types.h"
 #include "BLI_linklist.h"
 
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
 #include "BLO_readfile.h"
 
 #include "BKE_appdir.h"
+#include "BKE_asset.h"
 #include "BKE_context.h"
 #

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list