UI: Asset Shelf (Experimental Feature) #104831

Closed
Julian Eisel wants to merge 399 commits from asset-shelf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 69 additions and 50 deletions
Showing only changes of commit 693be95b2d - Show all commits

View File

@ -44,12 +44,23 @@ bool AS_asset_library_has_any_unsaved_catalogs(void);
* remapped on change (or assets removed as IDs gets removed). */ * remapped on change (or assets removed as IDs gets removed). */
void AS_asset_library_remap_ids(const struct IDRemapper *mappings); void AS_asset_library_remap_ids(const struct IDRemapper *mappings);
/** Attempt to build a full path to an asset based on the currently available (not necessary /**
* loaded) asset libraries. The path is not guaranteed to exist. * Attempt to resolve a full path to an asset based on the currently available (not necessary
* loaded) asset libraries, and split it into it's directory, ID group and ID name components. The
* path is not guaranteed to exist on disk. On failure to resolve the reference, return arguments
* will point to null.
*
* \note Only works for asset libraries on disk (others can't be resolved). * \note Only works for asset libraries on disk (others can't be resolved).
* *
* \param r_path: Returns the resolved path with native slashes, or an empty string if the path * \param r_path_buffer: Buffer to hold the result in on success. Will be the full path with null
* could not be resolved. Must be at least #FILE_MAX_LIBEXTRA long. */ * terminators instead of slashes separating the directory, group and name
* components.
* \param r_dir: Returns the .blend file path with native slashes on success. Optional (passing
* null is allowed).
* \param r_group: Returns the ID group such as "Object", "Material" or "Brush". Optional (passing
* null is allowed).
* \param r_name: Returns the ID name on success. Optional (passing null is allowed).
*/
void AS_asset_full_path_explode_from_weak_ref(const struct AssetWeakReference *asset_reference, void AS_asset_full_path_explode_from_weak_ref(const struct AssetWeakReference *asset_reference,
char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */], char r_path_buffer[1090 /* FILE_MAX_LIBEXTRA */],
char **r_dir, char **r_dir,

View File

@ -134,11 +134,10 @@ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_re
char **r_name) char **r_name)
{ {
AssetLibraryService *service = AssetLibraryService::get(); AssetLibraryService *service = AssetLibraryService::get();
StringRef dir, group, name; std::optional<AssetLibraryService::ExplodedPath> exploded =
std::string full_path = service->asset_weak_reference_library_path_explode( service->resolve_asset_weak_reference_to_exploded_path(*asset_reference);
*asset_reference, dir, group, name);
if (full_path.length() == 0) { if (!exploded) {
if (r_dir) { if (r_dir) {
*r_dir = nullptr; *r_dir = nullptr;
} }
@ -151,26 +150,28 @@ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_re
return; return;
} }
BLI_assert(!group.is_empty() && !name.is_empty()); BLI_assert(!exploded->group_component.is_empty());
BLI_assert(!exploded->name_component.is_empty());
BLI_strncpy(r_path_buffer, full_path.c_str(), 1090 /* FILE_MAX_LIBEXTRA */); BLI_strncpy(r_path_buffer, exploded->full_path.c_str(), 1090 /* FILE_MAX_LIBEXTRA */);
if (!dir.is_empty()) { if (!exploded->dir_component.is_empty()) {
r_path_buffer[dir.size()] = '\0'; r_path_buffer[exploded->dir_component.size()] = '\0';
r_path_buffer[dir.size() + 1 + group.size()] = '\0'; r_path_buffer[exploded->dir_component.size() + 1 + exploded->group_component.size()] = '\0';
if (r_dir) { if (r_dir) {
*r_dir = r_path_buffer; *r_dir = r_path_buffer;
} }
if (r_group) { if (r_group) {
*r_group = r_path_buffer + dir.size() + 1; *r_group = r_path_buffer + exploded->dir_component.size() + 1;
} }
if (r_name) { if (r_name) {
*r_name = r_path_buffer + dir.size() + 1 + group.size() + 1; *r_name = r_path_buffer + exploded->dir_component.size() + 1 +
exploded->group_component.size() + 1;
} }
} }
else { else {
r_path_buffer[group.size()] = '\0'; r_path_buffer[exploded->group_component.size()] = '\0';
if (r_dir) { if (r_dir) {
*r_dir = nullptr; *r_dir = nullptr;
@ -179,7 +180,7 @@ void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_re
*r_group = r_path_buffer; *r_group = r_path_buffer;
} }
if (r_name) { if (r_name) {
*r_name = r_path_buffer + group.size() + 1; *r_name = r_path_buffer + exploded->group_component.size() + 1;
} }
} }
} }

View File

@ -295,51 +295,45 @@ std::string AssetLibraryService::resolve_asset_weak_reference_to_full_path(
} }
std::string library_path = resolve_asset_weak_reference_to_library_path(asset_reference); std::string library_path = resolve_asset_weak_reference_to_library_path(asset_reference);
if (library_path.empty()) {
return "";
}
std::string normalized_full_path = utils::normalize_path( std::string normalized_full_path = utils::normalize_path(
library_path + SEP_STR + asset_reference.relative_asset_identifier); library_path + SEP_STR + asset_reference.relative_asset_identifier);
return normalized_full_path; return normalized_full_path;
} }
std::string AssetLibraryService::asset_weak_reference_library_path_explode( std::optional<AssetLibraryService::ExplodedPath> AssetLibraryService::
const AssetWeakReference &asset_reference, resolve_asset_weak_reference_to_exploded_path(const AssetWeakReference &asset_reference)
StringRef &r_dir,
StringRef &r_group,
StringRef &r_name)
{ {
std::string full_path = "";
r_dir = full_path;
r_group = full_path;
r_name = full_path;
if (asset_reference.relative_asset_identifier[0] == '\0') { if (asset_reference.relative_asset_identifier[0] == '\0') {
return full_path; return {};
} }
switch (eAssetLibraryType(asset_reference.asset_library_type)) { switch (eAssetLibraryType(asset_reference.asset_library_type)) {
case ASSET_LIBRARY_LOCAL: { case ASSET_LIBRARY_LOCAL: {
full_path = utils::normalize_path(asset_reference.relative_asset_identifier); std::string path_in_file = utils::normalize_path(asset_reference.relative_asset_identifier);
r_dir = r_group = r_name = full_path; const int64_t group_len = int64_t(path_in_file.find(SEP));
const int64_t group_len = int64_t(full_path.find(SEP)); ExplodedPath exploded{};
r_dir = r_dir.substr(0, 0); exploded.full_path = path_in_file;
r_group = r_group.substr(0, group_len); exploded.group_component = StringRef(exploded.full_path).substr(0, group_len);
r_name = r_name.substr(group_len + 1); exploded.name_component = StringRef(exploded.full_path).substr(group_len + 1);
return full_path; return exploded;
} }
case ASSET_LIBRARY_CUSTOM: case ASSET_LIBRARY_CUSTOM:
case ASSET_LIBRARY_ESSENTIALS: { case ASSET_LIBRARY_ESSENTIALS: {
std::string full_path = resolve_asset_weak_reference_to_full_path(asset_reference); std::string full_path = resolve_asset_weak_reference_to_full_path(asset_reference);
r_dir = r_group = r_name = full_path;
if (full_path.empty()) { if (full_path.empty()) {
return full_path; return {};
} }
const std::vector<std::string> blendfile_extensions = {".blend/", ".blend.gz/", ".ble/"}; const std::vector<std::string> blendfile_extensions = {".blend/", ".blend.gz/", ".ble/"};
size_t blendfile_extension_pos = std::string::npos; size_t blendfile_extension_pos = std::string::npos;
for (std::string blendfile_ext : blendfile_extensions) { for (const std::string &blendfile_ext : blendfile_extensions) {
size_t ext_pos = full_path.rfind(blendfile_ext); size_t ext_pos = full_path.rfind(blendfile_ext);
if (ext_pos != std::string::npos && if (ext_pos != std::string::npos &&
(blendfile_extension_pos < ext_pos || blendfile_extension_pos == std::string::npos)) { (blendfile_extension_pos < ext_pos || blendfile_extension_pos == std::string::npos)) {
@ -356,20 +350,21 @@ std::string AssetLibraryService::asset_weak_reference_library_path_explode(
const int64_t dir_len = int64_t(group_pos); const int64_t dir_len = int64_t(group_pos);
const int64_t group_len = int64_t(name_pos - group_pos - 1); const int64_t group_len = int64_t(name_pos - group_pos - 1);
r_dir = r_dir.substr(0, dir_len);
r_group = r_group.substr(dir_len + 1, group_len);
r_name = r_name.substr(dir_len + 1 + group_len + 1);
std::cout << full_path << "\n"; ExplodedPath exploded{};
std::cout << r_dir << "\t\t" << r_group << "\t\t" << r_name << "\n"; exploded.full_path = full_path;
StringRef full_path_ref = exploded.full_path;
exploded.dir_component = full_path_ref.substr(0, dir_len);
exploded.group_component = full_path_ref.substr(dir_len + 1, group_len);
exploded.name_component = full_path_ref.substr(dir_len + 1 + group_len + 1);
return full_path; return exploded;
} }
case ASSET_LIBRARY_ALL: case ASSET_LIBRARY_ALL:
return full_path; return {};
} }
return full_path; return {};
} }
bUserAssetLibrary *AssetLibraryService::find_custom_asset_library_from_library_ref( bUserAssetLibrary *AssetLibraryService::find_custom_asset_library_from_library_ref(

View File

@ -6,6 +6,8 @@
#pragma once #pragma once
#include <optional>
#include "AS_asset_library.hh" #include "AS_asset_library.hh"
#include "BLI_function_ref.hh" #include "BLI_function_ref.hh"
@ -83,13 +85,23 @@ class AssetLibraryService {
const AssetWeakReference &asset_reference); const AssetWeakReference &asset_reference);
/* See #AS_asset_full_path_resolve_from_weak_ref(). */ /* See #AS_asset_full_path_resolve_from_weak_ref(). */
std::string resolve_asset_weak_reference_to_full_path(const AssetWeakReference &asset_reference); std::string resolve_asset_weak_reference_to_full_path(const AssetWeakReference &asset_reference);
/** Struct to hold results from path explosion functions
* (#resolve_asset_weak_reference_to_exploded_path()). */
struct ExplodedPath {
/* The string buffer containing the fully resolved path, if resolving was successful. */
std::string full_path = "";
/* Reference into the part of #full_path that is the directory path. */
StringRef dir_component = "";
/* Reference into the part of #full_path that is the ID group name ("Object", "Brush", ...). */
StringRef group_component = "";
/* Reference into the part of #full_path that is the ID name. */
StringRef name_component = "";
};
/** Similar to #BKE_blendfile_library_path_explode, returns the full path as /** Similar to #BKE_blendfile_library_path_explode, returns the full path as
* #resolve_asset_weak_reference_to_library_path, with StringRefs to the `dir` (i.e. blendfile * #resolve_asset_weak_reference_to_library_path, with StringRefs to the `dir` (i.e. blendfile
* path), `group` (i.e. ID type) and `name` (i.e. ID name) parts. */ * path), `group` (i.e. ID type) and `name` (i.e. ID name) parts. */
std::string asset_weak_reference_library_path_explode(const AssetWeakReference &asset_reference, std::optional<ExplodedPath> resolve_asset_weak_reference_to_exploded_path(
StringRef &r_dir, const AssetWeakReference &asset_reference);
StringRef &r_group,
StringRef &r_name);
/** Returns whether there are any known asset libraries with unsaved catalog edits. */ /** Returns whether there are any known asset libraries with unsaved catalog edits. */
bool has_any_unsaved_catalogs() const; bool has_any_unsaved_catalogs() const;