[Bf-blender-cvs] [bc9eac28bab] ui-asset-view-template: Initial AssetList API & use it to load assets for the asset view tempate
Julian Eisel
noreply at git.blender.org
Mon Mar 1 17:11:30 CET 2021
Commit: bc9eac28bab696de3cbfed8c2dfddd63271edd3f
Author: Julian Eisel
Date: Mon Mar 1 16:45:42 2021 +0100
Branches: ui-asset-view-template
https://developer.blender.org/rBbc9eac28bab696de3cbfed8c2dfddd63271edd3f
Initial AssetList API & use it to load assets for the asset view tempate
Lots of hacks and temporary code here. I wanted a first working version to find
possible pain points before getting into details.
Basic idea is to store each asset library in an `AssetList`, with a globally
accessible storage. Internally the list uses the File Browser's `FileList`
which already does a fair amount of heavy lifting (threaded file & external
asset reading, lazy loading of visible previews, ...). The File Browser could
access the global asset-list storage as well.
The asset view template uses the new asset list to load and display the assets.
Current state: {F9856940}
Open TODOs: https://developer.blender.org/maniphest/query/M6RWFxFSDor3/#R
===================================================================
M release/scripts/startup/bl_ui/space_view3d.py
M source/blender/blenloader/intern/versioning_290.c
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/include/ED_asset.h
M source/blender/editors/include/UI_interface.h
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_template_asset_view.cc
M source/blender/editors/interface/interface_templates.c
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/editors/space_file/filesel.c
M source/blender/makesdna/DNA_asset_types.h
M source/blender/makesdna/DNA_screen_types.h
M source/blender/makesdna/DNA_space_types.h
M source/blender/makesdna/DNA_view3d_defaults.h
M source/blender/makesdna/DNA_view3d_types.h
M source/blender/makesrna/intern/rna_asset.c
M source/blender/makesrna/intern/rna_internal.h
M source/blender/makesrna/intern/rna_space.c
M source/blender/makesrna/intern/rna_ui_api.c
M source/blender/windowmanager/intern/wm_init_exit.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 3f4a082ed2e..5ebeca590dd 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -6992,7 +6992,9 @@ class VIEW3D_PT_asset_testing(Panel):
def draw(self, context):
layout = self.layout
- layout.template_asset_view()
+ v3d = context.space_data
+
+ layout.template_asset_view(v3d, "active_asset_library")
# Grease Pencil Object - Multiframe falloff tools
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 29041f4ae9d..fedc003e4ff 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1755,4 +1755,21 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
/* Keep this block, even when empty. */
}
+
+ {
+ if (!DNA_struct_elem_find(
+ fd->filesdna, "View3D", "AssetLibraryReference", "active_asset_library")) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) {
+ if (space->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)space;
+ v3d->active_asset_library.type = ASSET_LIBRARY_LOCAL;
+ v3d->active_asset_library.custom_library_index = -1;
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
index 8c5f91561b7..ec917aa625a 100644
--- a/source/blender/editors/asset/CMakeLists.txt
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC_SYS
set(SRC
asset_edit.cc
+ asset_list.cc
asset_ops.cc
)
diff --git a/source/blender/editors/asset/asset_edit.cc b/source/blender/editors/asset/asset_edit.cc
index d20de4141cb..2f9bd60edcb 100644
--- a/source/blender/editors/asset/asset_edit.cc
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -23,6 +23,7 @@
#include "BKE_lib_id.h"
#include "DNA_ID.h"
+#include "DNA_asset_types.h"
#include "UI_interface_icons.h"
@@ -65,3 +66,56 @@ bool ED_asset_can_make_single_from_context(const bContext *C)
/* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != nullptr;
}
+
+/* TODO better place? */
+/* TODO What about the setter and the itemf? */
+#include "BKE_preferences.h"
+#include "DNA_asset_types.h"
+#include "DNA_userdef_types.h"
+int ED_asset_library_reference_to_enum_value(const AssetLibraryReference *library)
+{
+ /* Simple case: Predefined repo, just set the value. */
+ if (library->type < ASSET_LIBRARY_CUSTOM) {
+ return library->type;
+ }
+
+ /* Note that the path isn't checked for validity here. If an invalid library path is used, the
+ * Asset Browser can give a nice hint on what's wrong. */
+ const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
+ &U, library->custom_library_index);
+ if (user_library) {
+ return ASSET_LIBRARY_CUSTOM + library->custom_library_index;
+ }
+
+ BLI_assert(0);
+ return ASSET_LIBRARY_LOCAL;
+}
+
+AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
+{
+ AssetLibraryReference library;
+
+ /* Simple case: Predefined repo, just set the value. */
+ if (value < ASSET_LIBRARY_CUSTOM) {
+ library.type = value;
+ library.custom_library_index = -1;
+ BLI_assert(ELEM(value, ASSET_LIBRARY_LOCAL));
+ return library;
+ }
+
+ const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
+ &U, value - ASSET_LIBRARY_CUSTOM);
+
+ /* Note that the path isn't checked for validity here. If an invalid library path is used, the
+ * Asset Browser can give a nice hint on what's wrong. */
+ const bool is_valid = (user_library->name[0] && user_library->path[0]);
+ if (!user_library) {
+ library.type = ASSET_LIBRARY_LOCAL;
+ library.custom_library_index = -1;
+ }
+ else if (user_library && is_valid) {
+ library.custom_library_index = value - ASSET_LIBRARY_CUSTOM;
+ library.type = ASSET_LIBRARY_CUSTOM;
+ }
+ return library;
+}
diff --git a/source/blender/editors/asset/asset_list.cc b/source/blender/editors/asset/asset_list.cc
new file mode 100644
index 00000000000..1f60d69e335
--- /dev/null
+++ b/source/blender/editors/asset/asset_list.cc
@@ -0,0 +1,347 @@
+/*
+ * 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 "BLI_function_ref.hh"
+#include "BLI_hash.hh"
+#include "BLI_map.hh"
+
+#include "DNA_asset_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_preferences.h"
+
+#include "ED_asset.h"
+#include "ED_fileselect.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.
+ */
+struct AssetLibraryReferenceWrapper {
+ const AssetLibraryReference &reference_;
+
+ AssetLibraryReferenceWrapper(const AssetLibraryReference &reference) : reference_(reference)
+ {
+ }
+ ~AssetLibraryReferenceWrapper() = default;
+
+ friend 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 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.
+ * \{ */
+
+#include "BKE_context.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
+class AssetList {
+ static void filelist_free_wrapper(FileList *list)
+ {
+ filelist_free(list);
+ MEM_freeN(list);
+ }
+
+ using FileList_Ptr = std::unique_ptr<FileList, decltype(&filelist_free_wrapper)>;
+ FileList_Ptr filelist_;
+ AssetLibraryReference library_ref_;
+
+ struct wmTimer *previews_timer = nullptr;
+
+ public:
+ AssetList() = delete;
+ AssetList(eFileSelectType filesel_type, const AssetLibraryReference &asset_library_ref)
+ : filelist_(filelist_new(filesel_type), filelist_free_wrapper),
+ library_ref_(asset_library_ref)
+ {
+ }
+ AssetList(AssetList &&other)
+ : filelist_(std::move(other.filelist_)), library_ref_(other.library_ref_)
+ {
+ }
+ AssetList(const AssetList &) = delete;
+ ~AssetList() = default;
+
+ void setup()
+ {
+ FileList *files = filelist_.get();
+
+ /* TODO there should only be one. */
+ 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 = NULL;
+
+ /* 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);
+ }
+
+ char path[FILE_MAXDIR] = "";
+ if (user_library) {
+ BLI_strncpy(path, user_library->path, sizeof(path));
+ filelist_setdir(files, path);
+ }
+ else {
+ filelist_setdir(files, path);
+ }
+
+ /* 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);
+ filelist_setfilter_options(
+ files,
+ true,
+ true,
+ true, /* Just always hide parent, prefer to not add an extra user option for this. */
+ FILE_TYPE_BLENDERLIB,
+ FILTER_ID_ALL,
+ true,
+ "",
+ "");
+ }
+
+ void fetch(const bContext &C)
+ {
+ FileList *files = filelist_.get();
+
+ if (filelist_needs_reading(files)) {
+ if (!filelist_pending(files)) {
+ filelist_readjob_start(files, &C);
+ }
+ }
+ filelist_sort(files);
+ filelist_filter(files);
+ }
+
+ void iterate(AssetListIterFn fn)
+ {
+ FileList *files = filelist_.get();
+ int numfiles = filelist_files_ensure(files);
+
+ for (int i = 0; i < numfiles; i++) {
+ FileDirEntry *file = filelist_file(files, i);
+ if (!fn(*file)) {
+ break;
+ }
+ }
+ }
+
+ void ensurePreview
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list