diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index 0b1901c0a45..b2e0b66f068 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -197,6 +197,7 @@ class AssetLibrary { Vector all_valid_asset_library_refs(); AssetLibraryReference all_library_reference(); +AssetLibraryReference current_file_library_reference(); void all_library_reload_catalogs_if_dirty(); } // namespace blender::asset_system diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index c21b4ac76fb..19c7460c6fc 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -254,6 +254,10 @@ void asset_library_on_save_post(Main *bmain, { AssetLibrary *asset_lib = static_cast(arg); asset_lib->on_blend_save_post(bmain, pointers, num_pointers); + + if (asset_lib->library_type() == ASSET_LIBRARY_LOCAL) { + AssetLibraryService::destroy_runtime_current_file_library(); + } } } // namespace @@ -357,6 +361,14 @@ AssetLibraryReference all_library_reference() return all_library_ref; } +AssetLibraryReference current_file_library_reference() +{ + AssetLibraryReference library_ref{}; + library_ref.custom_library_index = -1; + library_ref.type = ASSET_LIBRARY_LOCAL; + return library_ref; +} + void all_library_reload_catalogs_if_dirty() { AssetLibraryService *service = AssetLibraryService::get(); diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index b4c879b0240..d4f97a75b03 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -205,6 +205,12 @@ void AssetLibraryService::reload_all_library_catalogs_if_dirty() } } +void AssetLibraryService::destroy_runtime_current_file_library() +{ + AssetLibraryService &library_service = *AssetLibraryService::get(); + library_service.current_file_library_ = nullptr; +} + AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain) { /* (Re-)load all other asset libraries. */ diff --git a/source/blender/asset_system/intern/asset_library_service.hh b/source/blender/asset_system/intern/asset_library_service.hh index 74b349dd7ec..04026fcbbb8 100644 --- a/source/blender/asset_system/intern/asset_library_service.hh +++ b/source/blender/asset_system/intern/asset_library_service.hh @@ -79,6 +79,11 @@ class AssetLibraryService { const AssetLibraryReference &library_reference); static bUserAssetLibrary *find_custom_preferences_asset_library_from_asset_weak_ref( const AssetWeakReference &asset_reference); + /** + * Call when the .blend file is saved or unloaded to destroy the runtime library. It's not + * represented as a on disk library. + */ + static void destroy_runtime_current_file_library(); AssetLibrary *get_asset_library(const Main *bmain, const AssetLibraryReference &library_reference); diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index 21d56854855..380787ac12c 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -19,6 +19,7 @@ #include "AS_asset_representation.hh" #include "BKE_context.hh" +#include "BKE_main.hh" #include "BKE_screen.hh" #include "BLI_map.hh" @@ -93,7 +94,7 @@ class AssetList : NonCopyable { void setup(); void fetch(const bContext &C); - void clear(const bContext *C); + void clear(wmWindowManager *wm); AssetHandle asset_get_by_index(int index) const; @@ -211,12 +212,12 @@ void AssetList::iterate(AssetListIterFn fn) const } } -void AssetList::clear(const bContext *C) +void AssetList::clear(wmWindowManager *wm) { /* Based on #ED_fileselect_clear() */ FileList *files = filelist_; - filelist_readjob_stop(files, CTX_wm_manager(C)); + filelist_readjob_stop(files, wm); filelist_freelib(files); filelist_clear(files); filelist_tag_force_reset(files); @@ -283,35 +284,51 @@ void AssetList::remap_id(ID * /*id_old*/, ID * /*id_new*/) const /** \name Runtime asset list cache * \{ */ +static void clear(const AssetLibraryReference *library_reference, wmWindowManager *wm); +static void on_save_post(Main *main, PointerRNA **pointers, int num_pointers, void *arg); + /** * A global asset list map, each entry being a list for a specific asset library. */ using AssetListMap = Map; +struct GlobalStorage { + AssetListMap list_map; + bCallbackFuncStore on_save_callback_store{}; + + GlobalStorage() + { + on_save_callback_store.alloc = false; + + on_save_callback_store.func = on_save_post; + BKE_callback_add(&on_save_callback_store, BKE_CB_EVT_SAVE_POST); + } +}; + /** * Wrapper for Construct on First Use idiom, to avoid the Static Initialization Fiasco. */ -static AssetListMap &global_storage() +static AssetListMap &libraries_map() { - static AssetListMap global_storage; - return global_storage; + static GlobalStorage global_storage; + return global_storage.list_map; } static AssetList *lookup_list(const AssetLibraryReference &library_ref) { - return global_storage().lookup_ptr(library_ref); + return libraries_map().lookup_ptr(library_ref); } void storage_tag_main_data_dirty() { - for (AssetList &list : global_storage().values()) { + for (AssetList &list : libraries_map().values()) { list.tag_main_data_dirty(); } } void storage_id_remap(ID *id_old, ID *id_new) { - for (AssetList &list : global_storage().values()) { + for (AssetList &list : libraries_map().values()) { list.remap_id(id_old, id_new); } } @@ -336,7 +353,7 @@ using is_new_t = bool; static std::tuple ensure_list_storage( const AssetLibraryReference &library_reference, eFileSelectType filesel_type) { - AssetListMap &storage = global_storage(); + AssetListMap &storage = libraries_map(); if (AssetList *list = storage.lookup_ptr(library_reference)) { return {*list, false}; @@ -361,6 +378,17 @@ void asset_reading_region_listen_fn(const wmRegionListenerParams *params) } } +static void on_save_post(Main *main, + PointerRNA ** /*pointers*/, + int /*num_pointers*/, + void * /*arg*/) +{ + wmWindowManager *wm = static_cast(main->wm.first); + const AssetLibraryReference current_file_library = + asset_system::current_file_library_reference(); + clear(¤t_file_library, wm); +} + /* -------------------------------------------------------------------- */ /** \name C-API * \{ */ @@ -391,14 +419,13 @@ bool is_loaded(const AssetLibraryReference *library_reference) return list->is_loaded(); } -void clear(const AssetLibraryReference *library_reference, const bContext *C) +void clear(const AssetLibraryReference *library_reference, wmWindowManager *wm) { AssetList *list = lookup_list(*library_reference); if (list) { - list->clear(C); + list->clear(wm); } - wmWindowManager *wm = CTX_wm_manager(C); LISTBASE_FOREACH (const wmWindow *, win, &wm->windows) { const bScreen *screen = WM_window_get_active_screen(win); LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { @@ -418,14 +445,20 @@ void clear(const AssetLibraryReference *library_reference, const bContext *C) /* Always clear the all library when clearing a nested one. */ if (library_reference->type != ASSET_LIBRARY_ALL) { - clear_all_library(C); + const AssetLibraryReference all_lib_ref = asset_system::all_library_reference(); + clear(&all_lib_ref, wm); } } +void clear(const AssetLibraryReference *library_reference, const bContext *C) +{ + clear(library_reference, CTX_wm_manager(C)); +} + void clear_all_library(const bContext *C) { const AssetLibraryReference all_lib_ref = asset_system::all_library_reference(); - clear(&all_lib_ref, C); + clear(&all_lib_ref, CTX_wm_manager(C)); } bool storage_has_list_for_library(const AssetLibraryReference *library_reference) @@ -489,7 +522,7 @@ int size(const AssetLibraryReference *library_reference) void storage_exit() { - global_storage().clear(); + libraries_map().clear(); } /** \} */