Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_file/filelist.c
| Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
| #include "BLI_threads.h" | #include "BLI_threads.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| # include "BLI_winstuff.h" | # include "BLI_winstuff.h" | ||||
| #endif | #endif | ||||
| #include "BKE_asset.h" | #include "BKE_asset.h" | ||||
| #include "BKE_asset_library.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_icons.h" | #include "BKE_icons.h" | ||||
| #include "BKE_idtype.h" | #include "BKE_idtype.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_main_idmap.h" | #include "BKE_main_idmap.h" | ||||
| #include "BKE_preferences.h" | #include "BKE_preferences.h" | ||||
| ▲ Show 20 Lines • Show All 314 Lines • ▼ Show 20 Lines | |||||
| struct FileListReadJob; | struct FileListReadJob; | ||||
| typedef struct FileList { | typedef struct FileList { | ||||
| FileDirEntryArr filelist; | FileDirEntryArr filelist; | ||||
| eFileSelectType type; | eFileSelectType type; | ||||
| /* The library this list was created for. Stored here so we know when to re-read. */ | /* The library this list was created for. Stored here so we know when to re-read. */ | ||||
| AssetLibraryReference *asset_library_ref; | AssetLibraryReference *asset_library_ref; | ||||
| struct AssetLibrary *asset_library; | |||||
| short flags; | short flags; | ||||
| short sort; | short sort; | ||||
| FileListFilter filter_data; | FileListFilter filter_data; | ||||
| struct FileListIntern filelist_intern; | struct FileListIntern filelist_intern; | ||||
| ▲ Show 20 Lines • Show All 1,354 Lines • ▼ Show 20 Lines | void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection) | ||||
| filelist_intern_free(&filelist->filelist_intern); | filelist_intern_free(&filelist->filelist_intern); | ||||
| filelist_direntryarr_free(&filelist->filelist); | filelist_direntryarr_free(&filelist->filelist); | ||||
| if (do_selection && filelist->selection_state) { | if (do_selection && filelist->selection_state) { | ||||
| BLI_ghash_clear(filelist->selection_state, NULL, NULL); | BLI_ghash_clear(filelist->selection_state, NULL, NULL); | ||||
| } | } | ||||
| if (filelist->asset_library != NULL) { | |||||
| /* There is no way to refresh the catalogs stored by the AssetLibrary struct, so instead of | |||||
| * "clearing" it, the entire struct is freed. It will be reallocated when needed. */ | |||||
| BKE_asset_library_free(filelist->asset_library); | |||||
| filelist->asset_library = NULL; | |||||
| } | |||||
| } | } | ||||
| void filelist_clear(struct FileList *filelist) | void filelist_clear(struct FileList *filelist) | ||||
| { | { | ||||
| filelist_clear_ex(filelist, true, true); | filelist_clear_ex(filelist, true, true); | ||||
| } | } | ||||
| void filelist_free(struct FileList *filelist) | void filelist_free(struct FileList *filelist) | ||||
| ▲ Show 20 Lines • Show All 1,360 Lines • ▼ Show 20 Lines | typedef struct FileListReadJob { | ||||
| Main *current_main; | Main *current_main; | ||||
| struct FileList *filelist; | struct FileList *filelist; | ||||
| /** Shallow copy of #filelist for thread-safe access. | /** Shallow copy of #filelist for thread-safe access. | ||||
| * | * | ||||
| * The job system calls #filelist_readjob_update which moves any read file from #tmp_filelist | * The job system calls #filelist_readjob_update which moves any read file from #tmp_filelist | ||||
| * into #filelist in a thread-safe way. | * into #filelist in a thread-safe way. | ||||
| * | * | ||||
| * #tmp_filelist also keeps an `AssetLibrary *` so that it can be loaded in the same thread, and | |||||
| * moved to #filelist once all categories are loaded. | |||||
| * | |||||
| * NOTE: #tmp_filelist is freed in #filelist_readjob_free, so any copied pointers need to be set | * NOTE: #tmp_filelist is freed in #filelist_readjob_free, so any copied pointers need to be set | ||||
| * to NULL to avoid double-freeing them. */ | * to NULL to avoid double-freeing them. */ | ||||
| struct FileList *tmp_filelist; | struct FileList *tmp_filelist; | ||||
| } FileListReadJob; | } FileListReadJob; | ||||
| static void filelist_readjob_do(const bool do_lib, | static void filelist_readjob_do(const bool do_lib, | ||||
| FileListReadJob *job_params, | FileListReadJob *job_params, | ||||
| const short *stop, | const short *stop, | ||||
| ▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | static void filelist_readjob_do(const bool do_lib, | ||||
| /* If we were interrupted by stop, stack may not be empty and we need to free | /* If we were interrupted by stop, stack may not be empty and we need to free | ||||
| * pending dir paths. */ | * pending dir paths. */ | ||||
| while (!BLI_stack_is_empty(todo_dirs)) { | while (!BLI_stack_is_empty(todo_dirs)) { | ||||
| td_dir = BLI_stack_peek(todo_dirs); | td_dir = BLI_stack_peek(todo_dirs); | ||||
| MEM_freeN(td_dir->dir); | MEM_freeN(td_dir->dir); | ||||
| BLI_stack_discard(todo_dirs); | BLI_stack_discard(todo_dirs); | ||||
| } | } | ||||
| BLI_stack_free(todo_dirs); | BLI_stack_free(todo_dirs); | ||||
| /* Check whether assets catalogs need to be loaded. */ | |||||
| if (job_params->filelist->asset_library_ref != NULL) { | |||||
| /* Load asset catalogs, into the temp filelist for thread-safety. | |||||
| * #filelist_readjob_endjob() will move it into the real filelist. */ | |||||
| job_params->tmp_filelist->asset_library = BKE_asset_library_load(filelist->filelist.root); | |||||
| } | |||||
| } | } | ||||
| static void filelist_readjob_dir(FileListReadJob *job_params, | static void filelist_readjob_dir(FileListReadJob *job_params, | ||||
| short *stop, | short *stop, | ||||
| short *do_update, | short *do_update, | ||||
| float *progress) | float *progress) | ||||
| { | { | ||||
| filelist_readjob_do(false, job_params, stop, do_update, progress); | filelist_readjob_do(false, job_params, stop, do_update, progress); | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update, float *progress) | ||||
| FileListReadJob *flrj = flrjv; | FileListReadJob *flrj = flrjv; | ||||
| // printf("START filelist reading (%d files, main thread: %d)\n", | // printf("START filelist reading (%d files, main thread: %d)\n", | ||||
| // flrj->filelist->filelist.nbr_entries, BLI_thread_is_main()); | // flrj->filelist->filelist.nbr_entries, BLI_thread_is_main()); | ||||
| BLI_mutex_lock(&flrj->lock); | BLI_mutex_lock(&flrj->lock); | ||||
| BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist); | BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist); | ||||
| BLI_assert_msg(flrj->filelist->asset_library == NULL, | |||||
| "Asset library should not yet be assigned at start of read job"); | |||||
| flrj->tmp_filelist = MEM_dupallocN(flrj->filelist); | flrj->tmp_filelist = MEM_dupallocN(flrj->filelist); | ||||
| BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries); | BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries); | ||||
| flrj->tmp_filelist->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; | flrj->tmp_filelist->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; | ||||
| flrj->tmp_filelist->filelist_intern.filtered = NULL; | flrj->tmp_filelist->filelist_intern.filtered = NULL; | ||||
| BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries); | BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries); | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| static void filelist_readjob_endjob(void *flrjv) | static void filelist_readjob_endjob(void *flrjv) | ||||
| { | { | ||||
| FileListReadJob *flrj = flrjv; | FileListReadJob *flrj = flrjv; | ||||
| /* In case there would be some dangling update... */ | /* In case there would be some dangling update... */ | ||||
| filelist_readjob_update(flrjv); | filelist_readjob_update(flrjv); | ||||
| /* Move ownership of the asset library from the temporary list to the true filelist. */ | |||||
| BLI_assert_msg(flrj->filelist->asset_library == NULL, | |||||
| "asset library should not already have been allocated"); | |||||
| flrj->filelist->asset_library = flrj->tmp_filelist->asset_library; | |||||
| flrj->tmp_filelist->asset_library = NULL; /* MUST be NULL to avoid double-free. */ | |||||
| flrj->filelist->flags &= ~FL_IS_PENDING; | flrj->filelist->flags &= ~FL_IS_PENDING; | ||||
| flrj->filelist->flags |= FL_IS_READY; | flrj->filelist->flags |= FL_IS_READY; | ||||
| } | } | ||||
| static void filelist_readjob_free(void *flrjv) | static void filelist_readjob_free(void *flrjv) | ||||
| { | { | ||||
| FileListReadJob *flrj = flrjv; | FileListReadJob *flrj = flrjv; | ||||
| ▲ Show 20 Lines • Show All 78 Lines • Show Last 20 Lines | |||||