[Bf-blender-cvs] [25e0d0d] asset-experiments: Filelisting: switch from mere arrays to listbases.

Bastien Montagne noreply at git.blender.org
Fri Feb 27 19:19:37 CET 2015


Commit: 25e0d0d63d84419968ecafd62e090b36e1fd994c
Author: Bastien Montagne
Date:   Fri Feb 27 19:11:33 2015 +0100
Branches: asset-experiments
https://developer.blender.org/rB25e0d0d63d84419968ecafd62e090b36e1fd994c

Filelisting: switch from mere arrays to listbases.

Was not sure about that (adds two pointers to entries, variants **and** revisions :/ ),
but with the incremental process of listing we are using now, it makes things sooooo
much easy to handle (and also avoids tons of (deep)copy and mem (re)alloc), that it's
definitively worth it.

And since most (if not all) of 'public' access to filelist is done through filtered ones,
we can easily keep this a mere array of pointers, and hence keep quick index lookup.

Also, quite noticiably simplified the whole listing code (less functions, less levels of subcalls...).

Note: for now we stick to mere alloc, we may benefit from either memarena or mempool,
but those are not threadsafe (which means we could not so easily pass mem from worker
thread to main one), so not quite sure it would be worth it.

Note: thumbnail stuff is to be reworked from scratch too, have the feeling it's not yet
100% thread safe, and using a job here is probably way overkill, since we do not show
any progress in UI.

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

M	source/blender/editors/space_file/file_draw.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/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 852570a..479d107 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -443,6 +443,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
 	View2D *v2d = &ar->v2d;
 	struct FileList *files = sfile->files;
 	struct FileDirEntry *file;
+	const char *root = filelist_dir(files);
 	ImBuf *imb;
 	uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
 	int numfiles;
@@ -491,8 +492,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
 
 		file = filelist_file(files, i);
 
-		BLI_join_dirfile(path, sizeof(path), file->root, file->relpath);
-		name = fileentry_uiname(file, dir);
+		BLI_join_dirfile(path, sizeof(path), root, file->relpath);
+		name = fileentry_uiname(root, file, dir);
 
 		UI_ThemeColor4(TH_TEXT);
 
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 910d2cc..c6b076e 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -200,17 +200,6 @@ ListBase *folderlist_duplicate(ListBase *folderlist)
 
 /* ------------------FILELIST------------------------ */
 
-struct FileList;
-
-typedef struct FileImage {
-	struct FileImage *next, *prev;
-	char path[FILE_MAX];
-	unsigned int flags;
-	int index;
-	short done;
-	ImBuf *img;
-} FileImage;
-
 typedef struct FileListFilter {
 	bool hide_dot;
 	bool hide_parent;
@@ -236,7 +225,7 @@ typedef struct FileList {
 	bool need_sorting;
 
 	FileListFilter filter_data;
-	int *fidx;  /* Also used to detect when we need to filter! */
+	FileDirEntry **filtered;
 	int numfiltered;
 
 	bool need_thumbnails;
@@ -347,8 +336,9 @@ static int compare_direntry_generic(const FileDirEntry *entry1, const FileDirEnt
 	return 0;
 }
 
-static int compare_name(const void *a1, const void *a2)
+static int compare_name(void *user_data, const void *a1, const void *a2)
 {
+	const char *root = user_data;
 	const FileDirEntry *entry1 = a1;
 	const FileDirEntry *entry2 = a2;
 	char dir1[FILE_MAX_LIBEXTRA], dir2[FILE_MAX_LIBEXTRA];
@@ -359,14 +349,15 @@ static int compare_name(const void *a1, const void *a2)
 		return ret;
 	}
 
-	name1 = fileentry_uiname(entry1, dir1);
-	name2 = fileentry_uiname(entry2, dir2);
+	name1 = fileentry_uiname(root, entry1, dir1);
+	name2 = fileentry_uiname(root, entry2, dir2);
 
 	return BLI_natstrcmp(name1, name2);
 }
 
-static int compare_date(const void *a1, const void *a2)	
+static int compare_date(void *user_data, const void *a1, const void *a2)
 {
+	const char *root = user_data;
 	const FileDirEntry *entry1 = a1;
 	const FileDirEntry *entry2 = a2;
 	char dir1[FILE_MAX_LIBEXTRA], dir2[FILE_MAX_LIBEXTRA];
@@ -380,14 +371,15 @@ static int compare_date(const void *a1, const void *a2)
 	if (entry1->entry->time < entry2->entry->time) return 1;
 	if (entry1->entry->time > entry2->entry->time) return -1;
 
-	name1 = fileentry_uiname(entry1, dir1);
-	name2 = fileentry_uiname(entry2, dir2);
+	name1 = fileentry_uiname(root, entry1, dir1);
+	name2 = fileentry_uiname(root, entry2, dir2);
 
 	return BLI_natstrcmp(name1, name2);
 }
 
-static int compare_size(const void *a1, const void *a2)	
+static int compare_size(void *user_data, const void *a1, const void *a2)
 {
+	const char *root = user_data;
 	const FileDirEntry *entry1 = a1;
 	const FileDirEntry *entry2 = a2;
 	char dir1[FILE_MAX_LIBEXTRA], dir2[FILE_MAX_LIBEXTRA];
@@ -401,14 +393,15 @@ static int compare_size(const void *a1, const void *a2)
 	if (entry1->entry->size < entry2->entry->size) return 1;
 	if (entry1->entry->size > entry2->entry->size) return -1;
 
-	name1 = fileentry_uiname(entry1, dir1);
-	name2 = fileentry_uiname(entry2, dir2);
+	name1 = fileentry_uiname(root, entry1, dir1);
+	name2 = fileentry_uiname(root, entry2, dir2);
 
 	return BLI_natstrcmp(name1, name2);
 }
 
-static int compare_extension(const void *a1, const void *a2)
+static int compare_extension(void *user_data, const void *a1, const void *a2)
 {
+	const char *root = user_data;
 	const FileDirEntry *entry1 = a1;
 	const FileDirEntry *entry2 = a2;
 	const char *sufix1, *sufix2;
@@ -434,9 +427,9 @@ static int compare_extension(const void *a1, const void *a2)
 		char *group1, *group2, *name1, *name2;
 		int grp_comp;
 
-		BLI_join_dirfile(abspath, sizeof(abspath), entry1->root, entry1->relpath);
+		BLI_join_dirfile(abspath, sizeof(abspath), root, entry1->relpath);
 		BLO_library_path_explode(abspath, lib1, &group1, &name1);
-		BLI_join_dirfile(abspath, sizeof(abspath), entry2->root, entry2->relpath);
+		BLI_join_dirfile(abspath, sizeof(abspath), root, entry2->relpath);
 		BLO_library_path_explode(abspath, lib2, &group2, &name2);
 
 		BLI_assert(group1);
@@ -471,16 +464,16 @@ void filelist_sort(struct FileList *filelist)
 
 		switch (filelist->sort) {
 			case FILE_SORT_ALPHA:
-				qsort(filelist->filelist.entries, filelist->filelist.nbr_entries, sizeof(*filelist->filelist.entries), compare_name);
+				BLI_listbase_sort_r(&filelist->filelist.entries, filelist->filelist.root, compare_name);
 				break;
 			case FILE_SORT_TIME:
-				qsort(filelist->filelist.entries, filelist->filelist.nbr_entries, sizeof(*filelist->filelist.entries), compare_date);
+				BLI_listbase_sort_r(&filelist->filelist.entries, filelist->filelist.root, compare_date);
 				break;
 			case FILE_SORT_SIZE:
-				qsort(filelist->filelist.entries, filelist->filelist.nbr_entries, sizeof(*filelist->filelist.entries), compare_size);
+				BLI_listbase_sort_r(&filelist->filelist.entries, filelist->filelist.root, compare_size);
 				break;
 			case FILE_SORT_EXTENSION:
-				qsort(filelist->filelist.entries, filelist->filelist.nbr_entries, sizeof(*filelist->filelist.entries), compare_extension);
+				BLI_listbase_sort_r(&filelist->filelist.entries, filelist->filelist.root, compare_extension);
 				break;
 			case FILE_SORT_NONE:  /* Should never reach this point! */
 			default:
@@ -631,7 +624,7 @@ static bool is_filtered_main(FileDirEntry *file, const char *UNUSED(dir), FileLi
 
 static void filelist_filter_clear(FileList *filelist)
 {
-	MEM_SAFE_FREE(filelist->fidx);
+	MEM_SAFE_FREE(filelist->filtered);
 	filelist->numfiltered = 0;
 }
 
@@ -639,14 +632,13 @@ void filelist_filter(FileList *filelist)
 {
 	int num_filtered = 0;
 	const int num_files = filelist->filelist.nbr_entries;
-	int *fidx_tmp;
-	int i;
+	FileDirEntry **filtered_tmp, *file;
 
-	if (!filelist->filelist.entries) {
+	if (BLI_listbase_is_empty(&filelist->filelist.entries)) {
 		return;
 	}
 
-	if (filelist->fidx) {
+	if (filelist->filtered) {
 		/* Assume it has already been filtered, nothing else to do! */
 		return;
 	}
@@ -661,23 +653,21 @@ void filelist_filter(FileList *filelist)
 		}
 	}
 
-	fidx_tmp = MEM_mallocN(sizeof(*fidx_tmp) * (size_t)num_files, __func__);
+	filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__);
 
 	/* Filter remap & count how many files are left after filter in a single loop. */
-	for (i = 0; i < num_files; ++i) {
-		FileDirEntry *file = &filelist->filelist.entries[i];
-
+	for (file = filelist->filelist.entries.first; file; file = file->next) {
 		if (filelist->filterf(file, filelist->filelist.root, &filelist->filter_data)) {
-			fidx_tmp[num_filtered++] = i;
+			filtered_tmp[num_filtered++] = file;
 		}
 	}
 
 	/* Note: maybe we could even accept filelist->fidx to be filelist->numfiles -len allocated? */
-	filelist->fidx = MEM_mallocN(sizeof(*filelist->fidx) * (size_t)num_filtered, __func__);
-	memcpy(filelist->fidx, fidx_tmp, sizeof(*filelist->fidx) * (size_t)num_filtered);
+	filelist->filtered = MEM_mallocN(sizeof(*filelist->filtered) * (size_t)num_filtered, __func__);
+	memcpy(filelist->filtered, filtered_tmp, sizeof(*filelist->filtered) * (size_t)num_filtered);
 	filelist->numfiltered = num_filtered;
 
-	MEM_freeN(fidx_tmp);
+	MEM_freeN(filtered_tmp);
 }
 
 void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
@@ -955,43 +945,6 @@ static void filelist_checkdir_main(struct FileList *filelist, char *r_dir)
 	filelist_checkdir_lib(filelist, r_dir);
 }
 
-static void filelist_entry_deepdup(FileDirEntry *dst, FileDirEntry *src, const char *root)
-{
-	dst->root = root;
-	if (src->relpath) {
-		dst->relpath = MEM_dupallocN(src->relpath);
-	}
-	if (src->image) {
-		dst->image = IMB_dupImBuf(src->image);
-	}
-
-	if (src->variants) {
-		int i = src->nbr_variants;
-
-		BLI_assert(MEM_allocN_len(src->variants) == sizeof(*src->variants) * i);
-		dst->variants = MEM_dupallocN(src->variants);
-
-		while (i--) {
-			int j = src->variants[i].nbr_revisions;
-			const bool is_act_variant = (i == src->act_variant);
-
-			BLI_assert(MEM_allocN_len(src->variants[i].revisions) == sizeof(*src->variants[i].revisions) * j);
-			dst->variants[i].revisions = MEM_dupallocN(src->variants[i].revisions);
-
-			while (j--) {
-				if (is_act_variant && (j == src->variants[i].act_revision)) {
-					dst->entry = &dst->variants[i].revisions[j];
-				}
-			}
-		}
-
-		/* TODO: tags! */
-	}
-	else if (src->entry){
-		dst->entry = MEM_dupallocN(src->entry);
-	}
-}
-
 static void filelist_entry_free(FileDirEntry *entry, const bool clear)
 {
 	if (entry->relpath) {
@@ -1002,16 +955,16 @@ static void filelist_entry_free(FileDirEntry *entry, const bool clear)
 	}
 	/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
 
-	if (entry->variants) {
-		int i = entry->nbr_variants;
+	if (!BLI_listbase_is_empty(&entry->variants)) {
+		FileDirEntryVariant *var;
 
-		while (i--) {
-			MEM_SAFE_FREE(entry->variants[i].revisions);
+		for (var = entry->variants.first; var; var = var->next) {
+			BLI_freelistN(&var->revisions);
 		}
 
 		/* TODO: tags! */
 
-		MEM_freeN(entry->variants);
+		BLI_freelistN(&entry->variants);
 	}
 	else if (entry->entry){
 		MEM_freeN(entry->entry);
@@ -1021,29 +974,15 @@ static void filelist_entry_free(FileDirEntry *entry, const bool clear)
 	}
 }
 
-static void filelist_dupalloc(FileDirEntry **dst, FileDirEntry *src, const int nbr_entries, const char *root)
-{
-	int i = nbr_entries;
-
-	BLI_assert(*dst == NULL);
-	/* Note src may have more

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list