[Bf-blender-cvs] [cb0272c] asset-experiments: Full rework of job (background) filereading code.

Bastien Montagne noreply at git.blender.org
Thu Dec 11 20:12:30 CET 2014


Commit: cb0272ceabf8854282a3860e71b9036ba6ea9fe0
Author: Bastien Montagne
Date:   Thu Dec 11 17:33:16 2014 +0100
Branches: asset-experiments
https://developer.blender.org/rBcb0272ceabf8854282a3860e71b9036ba6ea9fe0

Full rework of job (background) filereading code.

Now it works reasonably OK for filesystem, and also for .blend libs.

Code is even quite simpler than previous one. Now it needs some serious cleanup,
and find where (new) memleak comes from too.

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

M	source/blender/blenlib/BLI_fileops.h
M	source/blender/blenlib/intern/storage.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/space_file.c
M	source/blender/windowmanager/WM_api.h
M	tests/gtests/blenlib/BLI_path_util_test.cc

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

diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 4f451a6..260827f 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -89,6 +89,7 @@ double BLI_dir_free_space(const char *dir);
 char  *BLI_current_working_dir(char *dir, const size_t maxlen);
 
 unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
+void BLI_duplicate_filelist(struct direntry **dest_filelist, struct direntry *src_filelist, unsigned int nrentries);
 void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries);
 
 /* Files */
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index c062d62..3ed3b07 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -409,7 +409,34 @@ unsigned int BLI_dir_contents(const char *dirname,  struct direntry **filelist)
 	return dir_ctx.nrfiles;
 }
 
-/* frees storage for an array of direntries, including the array itself. */
+/**
+ * Deep-duplicate of an array of direntries, including the array itself.
+ */
+void BLI_duplicate_filelist(struct direntry **dest_filelist, struct direntry *src_filelist, unsigned int nrentries)
+{
+	unsigned int i;
+
+	*dest_filelist = malloc(sizeof(**dest_filelist) * (size_t)(nrentries));
+	for (i = 0; i < nrentries; ++i) {
+		struct direntry * const src = &src_filelist[i];
+		struct direntry *dest = &(*dest_filelist)[i];
+		*dest = *src;
+		if (dest->image) {
+			dest->image = IMB_dupImBuf(src->image);
+		}
+		if (dest->relname) {
+			dest->relname = MEM_dupallocN(src->relname);
+		}
+		if (dest->path) {
+			dest->path = MEM_dupallocN(src->path);
+		}
+		/* entry->poin assumed not needing any handling here. */
+	}
+}
+
+/**
+ * frees storage for an array of direntries, including the array itself.
+ */
 void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
 {
 	unsigned int i;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 3651b9f..8964f71 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -67,8 +67,9 @@
 
 #include "DNA_space_types.h"
 
-#include "ED_fileselect.h"
 #include "ED_datafiles.h"
+#include "ED_fileselect.h"
+#include "ED_screen.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -112,9 +113,12 @@ typedef struct FileList {
 	short prv_h;
 
 	bool force_reset;
+	bool force_refresh;
 	bool filelist_ready;
+	bool filelist_pending;
 	bool need_sorting;
 
+	short sort;
 	FileListFilter filter_data;
 
 	struct BlendHandle *libfiledata;
@@ -128,7 +132,7 @@ typedef struct FileList {
 	short recursion_level;
 } FileList;
 
-#define FILELIST_MAX_RECURSION 1
+#define FILELIST_MAX_RECURSION 3
 
 #define FILENAME_IS_BREADCRUMBS(_n) \
 	(((_n)[0] == '.' && (_n)[1] == '\0') || ((_n)[0] == '.' && (_n)[1] == '.' && (_n)[2] == '\0'))
@@ -779,11 +783,26 @@ bool filelist_is_ready(struct FileList *filelist)
 	return filelist->filelist_ready;
 }
 
+bool filelist_pending(struct FileList *filelist)
+{
+	return filelist->filelist_pending;
+}
+
 bool filelist_need_sorting(struct FileList *filelist)
 {
 	return filelist->need_sorting;
 }
 
+bool filelist_need_refresh(struct FileList *filelist)
+{
+	return (!filelist->filelist || !filelist->fidx || filelist->force_reset || filelist->force_refresh || filelist->need_sorting);
+}
+
+void filelist_clear_refresh(struct FileList *filelist)
+{
+	filelist->force_refresh = false;
+}
+
 static struct direntry *filelist_geticon_get_file(struct FileList *filelist, const int index)
 {
 	BLI_assert(G.background == false);
@@ -1145,14 +1164,12 @@ int ED_file_extension_icon(const char *path)
 	return ICON_FILE_BLANK;
 }
 
-static void filelist_setfiletypes(struct FileList *filelist)
+static void filelist_setfiletypes(const char *root, struct direntry *files, const int numfiles, const char *filter_glob)
 {
 	struct direntry *file;
 	int num;
-	
-	file = filelist->filelist;
-	
-	for (num = 0; num < filelist->numfiles; num++, file++) {
+
+	for (num = 0, file = files; num < numfiles; num++, file++) {
 		if (file->flags & BLENDERLIB) {
 			continue;
 		}
@@ -1163,23 +1180,20 @@ static void filelist_setfiletypes(struct FileList *filelist)
 			continue;
 		}
 #endif
-		file->flags = file_extension_type(filelist->dir, file->relname);
+		file->flags = file_extension_type(root, file->relname);
 
-		if (filelist->filter_data.filter_glob[0] &&
-		    BLI_testextensie_glob(file->relname, filelist->filter_data.filter_glob))
-		{
+		if (filter_glob[0] && BLI_testextensie_glob(file->relname, filter_glob)) {
 			file->flags = OPERATORFILE;
 		}
-		
 	}
 }
 
-static void filelist_merge_sublist(struct direntry *filelist_org, struct direntry **filelist_buff, int *filelist_buff_size, int *filelist_used_size,
-                                   const char *root, struct FileList *sublist)
+static void filelist_merge_sublist_ex(struct direntry **filelist_buff, int *filelist_buff_size, int *filelist_used_size,
+                                      const char *root, const char *subdir, struct direntry *subfiles, const int num_subfiles, const bool ignore_breadcrumbs)
 {
-	if (sublist->numfiles) {
+	if (num_subfiles) {
 		struct direntry *f;
-		int new_numfiles = sublist->numfiles + *filelist_used_size;
+		int new_numfiles = num_subfiles + *filelist_used_size;
 		char dir[FILE_MAX];
 		int i, j;
 
@@ -1190,19 +1204,17 @@ static void filelist_merge_sublist(struct direntry *filelist_org, struct direntr
 			new_filelist = malloc(sizeof(*new_filelist) * (size_t)*filelist_buff_size);
 			if (*filelist_buff && *filelist_used_size) {
 				memcpy(new_filelist, *filelist_buff, sizeof(*new_filelist) * (size_t)*filelist_used_size);
-				if (*filelist_buff != filelist_org) {
-					free(*filelist_buff);
-				}
+				free(*filelist_buff);
 			}
 			*filelist_buff = new_filelist;
 		}
-		for (i = *filelist_used_size, j = 0, f = sublist->filelist; j < sublist->numfiles; j++, f++) {
-			if (FILENAME_IS_BREADCRUMBS(f->relname)) {
+		for (i = *filelist_used_size, j = 0, f = subfiles; j < num_subfiles; j++, f++) {
+			if (ignore_breadcrumbs && FILENAME_IS_BREADCRUMBS(f->relname)) {
 				/* Ignore 'inner' breadcrumbs! */
 				new_numfiles--;
 				continue;
 			}
-			BLI_join_dirfile(dir, sizeof(dir), sublist->dir, f->relname);
+			BLI_join_dirfile(dir, sizeof(dir), subdir, f->relname);
 			BLI_cleanup_file(root, dir);
 			BLI_path_rel(dir, root);
 			(*filelist_buff)[i] = *f;
@@ -1218,6 +1230,13 @@ static void filelist_merge_sublist(struct direntry *filelist_org, struct direntr
 	}
 }
 
+static void filelist_merge_sublist(struct direntry *UNUSED(filelist_org), struct direntry **filelist_buff, int *filelist_buff_size, int *filelist_used_size,
+                                   const char *root, struct FileList *sublist)
+{
+	filelist_merge_sublist_ex(filelist_buff, filelist_buff_size, filelist_used_size, root,
+	                          sublist->dir, sublist->filelist, sublist->numfiles, true);
+}
+
 static void filelist_read_dir(struct FileList *filelist)
 {
 	/* only used if recursing, will contain all non-immediate children then. */
@@ -1236,7 +1255,7 @@ static void filelist_read_dir(struct FileList *filelist)
 	BLI_cleanup_dir(G.main->name, filelist->dir);
 	filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
 
-	filelist_setfiletypes(filelist);
+	filelist_setfiletypes(filelist->dir, filelist->filelist, filelist->numfiles, filelist->filter_data.filter_glob);
 
 	if (filelist->use_recursion && filelist->recursion_level < FILELIST_MAX_RECURSION) {
 		FileList *fl = filelist_new(FILE_UNIX);
@@ -1348,7 +1367,7 @@ static void filelist_read_library(struct FileList *filelist)
 
 		BLI_assert(is_lib);
 
-		filelist_setfiletypes(filelist);
+	filelist_setfiletypes(filelist->dir, filelist->filelist, filelist->numfiles, filelist->filter_data.filter_glob);
 
 		if (group) {
 			/* We are at lowest possible level, nothing else to do. */
@@ -1371,7 +1390,7 @@ static void filelist_read_library(struct FileList *filelist)
 			filelist_setdir(fl, dir);
 			BLI_cleanup_dir(G.main->name, fl->dir);
 			filelist_from_library(fl, false, false);
-			filelist_setfiletypes(fl);
+			filelist_setfiletypes(fl->dir, fl->filelist, fl->numfiles, fl->filter_data.filter_glob);
 
 			filelist_merge_sublist(NULL, &new_filelist, &new_filelist_buffsize, &new_filelist_size, filelist->dir, fl);
 
@@ -1403,7 +1422,7 @@ void filelist_readdir(struct FileList *filelist)
 }
 
 int filelist_empty(struct FileList *filelist)
-{	
+{
 	return filelist->filelist == NULL;
 }
 
@@ -1475,10 +1494,10 @@ bool filelist_is_selected(struct FileList *filelist, int index, FileCheckType ch
 	}
 }
 
-void filelist_sort(struct FileList *filelist, short sort)
+void filelist_sort(struct FileList *filelist)
 {
 	if (filelist->need_sorting) {
-		switch (sort) {
+		switch (filelist->sort) {
 			case FILE_SORT_ALPHA:
 				qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
 				break;
@@ -1491,8 +1510,24 @@ void filelist_sort(struct FileList *filelist, short sort)
 			case FILE_SORT_EXTENSION:
 				qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
 				break;
+			case FILE_SORT_NONE:
+			default:
+				break;
 		}
 		filelist->need_sorting = false;
+		if (filelist->fidx) {
+			MEM_freeN(filelist->fidx);
+			filelist->fidx = NULL;
+			filelist->numfiltered = 0;
+		}
+	}
+}
+
+void filelist_setsorting(struct FileList *filelist, const short sort)
+{
+	if (filelist->sort != sort) {
+		filelist->sort = sort;
+		filelist->need_sorting = true;
 	}
 }
 
@@ -1581,65 +1616,59 @@ static unsigned int groupname_to_filter_id(const char *group)
 	}
 }
  
-static void filelist_from_library(struct FileList *filelist, const bool add_parent, const bool use_filter)
+static void filelist_from_library_ex(const char *root, struct direntry **files, int *num_files)
 {
 	LinkNode *l, *names, *previews;
 	struct ImBuf *ima;
 	int ok, i, nprevs, nnames, idcode = 0;
-	char filename[FILE_MAX];
+	//~ char filename[FILE_MAX];
 	char dir[FILE_MAX], *group;
-	
+
+	struct BlendHandle *libfil

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list