[Bf-blender-cvs] [bab93fc3df9] temp-asset-browser-poselib-merge: Assets: Initial Asset List as part of the Asset System design
Julian Eisel
noreply at git.blender.org
Wed Jul 14 22:53:09 CEST 2021
Commit: bab93fc3df9f92d535106711d48093315b11830f
Author: Julian Eisel
Date: Fri Jul 9 12:56:26 2021 +0200
Branches: temp-asset-browser-poselib-merge
https://developer.blender.org/rBbab93fc3df9f92d535106711d48093315b11830f
Assets: Initial Asset List as part of the Asset System design
Implements a basic, WIP version of the asset list. This is needed to
give the asset view UI template asset reading and displaying
functionality.
See:
* Asset System: Data Storage, Reading & UI Access - https://developer.blender.org/T88184
Especially the asset list internals should change. It uses the
File/Asset Browser's `FileList` API, which isn't really meant for access
from outside the File Browser. But as explained in T88184, it does a lot
of the stuff we currently need, so we (Sybren Stüvel and I) decided to
go this route for now. Work on a file-list rewrite which integrates well
with the asset system started in the `asset-system-filelist` branch.
Further includes:
* Operator to reload the asset list.
* New `bpy.types.AssetHandle.get_full_library_path()` function, which
gets the full path of the asset via the asset-list.
* Changes to preview loading to prevent the preview loading job to run
eternally for asset views. File Browsers have this issue too, but
should be fixed separately.
===================================================================
M source/blender/editors/asset/CMakeLists.txt
M source/blender/editors/asset/asset_edit.cc
A source/blender/editors/asset/asset_list.cc
M source/blender/editors/asset/asset_ops.cc
M source/blender/editors/include/ED_asset.h
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/editors/undo/ed_undo.c
M source/blender/editors/util/ed_util.c
M source/blender/editors/util/ed_util_ops.cc
M source/blender/makesdna/DNA_asset_types.h
M source/blender/makesrna/intern/rna_asset.c
M source/blender/makesrna/intern/rna_space.c
M source/blender/makesrna/intern/rna_workspace.c
M source/blender/windowmanager/WM_types.h
M source/blender/windowmanager/intern/wm_event_system.c
M source/blender/windowmanager/intern/wm_init_exit.c
===================================================================
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
index 794e64fa420..d87879bea2a 100644
--- a/source/blender/editors/asset/CMakeLists.txt
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -31,11 +31,13 @@ set(INC_SYS
set(SRC
asset_edit.cc
+ asset_list.cc
asset_ops.cc
)
set(LIB
bf_blenloader
+ bf_blenkernel
)
blender_add_lib(bf_editor_asset "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/asset/asset_edit.cc b/source/blender/editors/asset/asset_edit.cc
index 949dc1890ad..0937af0dbf1 100644
--- a/source/blender/editors/asset/asset_edit.cc
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -18,10 +18,15 @@
* \ingroup edasset
*/
+#include <memory>
+#include <string>
+
#include "BKE_asset.h"
#include "BKE_context.h"
#include "BKE_lib_id.h"
+#include "BLO_readfile.h"
+
#include "DNA_ID.h"
#include "DNA_asset_types.h"
#include "DNA_space_types.h"
@@ -32,6 +37,8 @@
#include "ED_asset.h"
+using namespace blender;
+
bool ED_asset_mark_id(const bContext *C, ID *id)
{
if (id->asset_data) {
@@ -47,6 +54,9 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
+ /* Important for asset storage to update properly! */
+ ED_assetlist_storage_tag_main_data_dirty();
+
return true;
}
@@ -59,6 +69,9 @@ bool ED_asset_clear_id(ID *id)
/* Don't clear fake user here, there's no guarantee that it was actually set by
* #ED_asset_mark_id(), it might have been something/someone else. */
+ /* Important for asset storage to update properly! */
+ ED_assetlist_storage_tag_main_data_dirty();
+
return true;
}
@@ -125,3 +138,18 @@ const char *ED_asset_handle_get_name(const AssetHandle *asset)
{
return asset->file_data->name;
}
+
+void ED_asset_handle_get_full_library_path(const bContext *C,
+ const AssetLibraryReference *asset_library,
+ const AssetHandle *asset,
+ char r_full_lib_path[FILE_MAX_LIBEXTRA])
+{
+ *r_full_lib_path = '\0';
+
+ std::string asset_path = ED_assetlist_asset_filepath_get(C, *asset_library, *asset);
+ if (asset_path.empty()) {
+ return;
+ }
+
+ BLO_library_path_explode(asset_path.c_str(), r_full_lib_path, nullptr, nullptr);
+}
diff --git a/source/blender/editors/asset/asset_list.cc b/source/blender/editors/asset/asset_list.cc
new file mode 100644
index 00000000000..1ea948d97d4
--- /dev/null
+++ b/source/blender/editors/asset/asset_list.cc
@@ -0,0 +1,637 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edasset
+ *
+ * Abstractions to manage runtime asset lists with a global cache for multiple UI elements to
+ * access.
+ * Internally this uses the #FileList API and structures from `filelist.c`. This is just because it
+ * contains most necessary logic already and there's not much time for a more long-term solution.
+ */
+
+#include <optional>
+#include <string>
+
+#include "BKE_asset.h"
+#include "BKE_context.h"
+#include "BKE_screen.h"
+
+#include "BLI_function_ref.hh"
+#include "BLI_hash.hh"
+#include "BLI_map.hh"
+#include "BLI_path_util.h"
+#include "BLI_utility_mixins.hh"
+
+#include "DNA_asset_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_preferences.h"
+
+#include "ED_asset.h"
+#include "ED_fileselect.h"
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* XXX uses private header of file-space. */
+#include "../space_file/filelist.h"
+
+using namespace blender;
+
+/**
+ * Wrapper to add logic to the AssetLibraryReference DNA struct.
+ */
+class AssetLibraryReferenceWrapper {
+ const AssetLibraryReference reference_;
+
+ public:
+ /* Intentionally not `explicit`, allow implicit conversion for convienience. Might have to be
+ * NOLINT */
+ AssetLibraryReferenceWrapper(const AssetLibraryReference &reference);
+ ~AssetLibraryReferenceWrapper() = default;
+
+ friend bool operator==(const AssetLibraryReferenceWrapper &a,
+ const AssetLibraryReferenceWrapper &b);
+ uint64_t hash() const;
+};
+
+AssetLibraryReferenceWrapper::AssetLibraryReferenceWrapper(const AssetLibraryReference &reference)
+ : reference_(reference)
+{
+}
+
+bool operator==(const AssetLibraryReferenceWrapper &a, const AssetLibraryReferenceWrapper &b)
+{
+ return (a.reference_.type == b.reference_.type) && (a.reference_.type == ASSET_LIBRARY_CUSTOM) ?
+ (a.reference_.custom_library_index == b.reference_.custom_library_index) :
+ true;
+}
+
+uint64_t AssetLibraryReferenceWrapper::hash() const
+{
+ uint64_t hash1 = DefaultHash<decltype(reference_.type)>{}(reference_.type);
+ if (reference_.type != ASSET_LIBRARY_CUSTOM) {
+ return hash1;
+ }
+
+ uint64_t hash2 = DefaultHash<decltype(reference_.custom_library_index)>{}(
+ reference_.custom_library_index);
+ return hash1 ^ (hash2 * 33); /* Copied from DefaultHash for std::pair. */
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Asset list API
+ *
+ * Internally re-uses #FileList from the File Browser. It does all the heavy lifting already.
+ * \{ */
+
+/**
+ * RAII wrapper for `FileList`
+ */
+class FileListWrapper {
+ static void filelist_free_fn(FileList *list)
+ {
+ filelist_free(list);
+ MEM_freeN(list);
+ }
+
+ std::unique_ptr<FileList, decltype(&filelist_free_fn)> file_list_;
+
+ public:
+ explicit FileListWrapper(eFileSelectType filesel_type)
+ : file_list_(filelist_new(filesel_type), filelist_free_fn)
+ {
+ }
+ FileListWrapper(FileListWrapper &&other) = default;
+ FileListWrapper &operator=(FileListWrapper &&other) = default;
+ ~FileListWrapper()
+ {
+ /* Destructs the owned pointer. */
+ file_list_ = nullptr;
+ }
+
+ operator FileList *() const
+ {
+ return file_list_.get();
+ }
+};
+
+class PreviewTimer {
+ /* Non-owning! The Window-Manager registers and owns this. */
+ wmTimer *timer_ = nullptr;
+
+ public:
+ void ensureRunning(const bContext *C)
+ {
+ if (!timer_) {
+ timer_ = WM_event_add_timer_notifier(
+ CTX_wm_manager(C), CTX_wm_window(C), NC_ASSET | ND_ASSET_LIST_PREVIEW, 0.01);
+ }
+ }
+
+ void stop(const bContext *C)
+ {
+ if (timer_) {
+ WM_event_remove_timer_notifier(CTX_wm_manager(C), CTX_wm_window(C), timer_);
+ timer_ = nullptr;
+ }
+ }
+};
+
+class AssetList : NonCopyable {
+ FileListWrapper filelist_;
+ AssetLibraryReference library_ref_;
+ PreviewTimer previews_timer_;
+
+ public:
+ AssetList() = delete;
+ AssetList(eFileSelectType filesel_type, const AssetLibraryReference &asset_library_ref);
+ AssetList(AssetList &&other) = default;
+ ~AssetList() = default;
+
+ void setup(const AssetFilterSettings *filter_settings = nullptr);
+ void fetch(const bContext &C);
+ void ensurePreviewsJob(bContext *C);
+ void clear(bContext *C);
+
+ bool needsRefetch() const;
+ void iterate(AssetListIterFn fn) const;
+ bool listen(const wmNotifier ¬ifier) const;
+ int size() const;
+ void tagMainDataDirty() const;
+ void remapID(ID *id_old, ID *id_new) const;
+ StringRef filepath() const;
+};
+
+AssetList::AssetList(eFileSelectType filesel_type, const AssetLibraryReference &asset_library_ref)
+ : filelist_(filesel_type), library_ref_(asset_library_ref)
+{
+}
+
+void AssetList::setup(const AssetFilterSettings *filter_settings)
+{
+ FileList *files = filelist_;
+
+ /* TODO there should only be one (FileSelectAssetLibraryUID vs. AssetLibraryReference). */
+ FileSelectAssetLibraryUID file_asset_lib_ref;
+ file_asset_lib_ref.type = library_ref_.type;
+ file_asset_lib_ref.custom_library_index = library_ref_.custom_library_index;
+
+ bUserAssetLibrary *user_library = nullptr;
+
+ /* Ensure valid repository, or fall-back to local one. */
+ if (library_ref_.type == ASSET_LIBRARY_CUSTOM) {
+ BLI_assert(library_ref_.custom_library_index >= 0);
+
+ user_library = BKE_preferences_asset_library_find_from_index(
+ &U, library_ref_.custom_library_index);
+ }
+
+ /* Relevant bits from file_refresh(). */
+ /* TODO pass options properly. */
+ filelist_setrecursion(files, 1);
+ filelist_setsorting(files, FILE_SORT_ALPHA, false);
+ filelist_setlibrary(files, &file_asset_lib_ref);
+ /* TODO different filtering settings require the list to be reread. That's a no-go for when we
+ * want to allow showing the same asset library with different filter settings (as in,
+ * different ID types). The filelist needs to be made smarter somehow, maybe goes together with
+ * the plan to separate the view (preview caching, filtering, etc. ) from the data. */
+ filelist_setfilter_options(
+ files,
+ filter_settings != nullptr,
+ true,
+ true, /* Just always hide parent, prefer to not add an extra user option for this. */
+ FILE_TYPE_BLENDERLIB,
+ filter_settings ? filter_settings->id_types : FILTER_ID_ALL,
+ true,
+ "",
+ "");
+
+ char path[FILE_MAXDIR] = "";
+ if (user_library) {
+ BLI_strncpy(path, user_library->path, sizeof(path));
+ filelist_setdir(files, path);
+ }
+ else {
+ filelist_setdir(files, path);
+ }
+}
+
+void AssetList::fetch(const bContext &C)
+{
+ FileList *files = filelist_;
+
+ if (filelist_needs_force_reset(files)) {
+ filelist_readjob_stop(files, CTX_wm_manager(&C));
+ filelist_clear(files);
+ }
+
+ if (filelist_needs_reading(files)) {
+ if (!f
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list