113 return hasher(file_path_);
120 return std::string(filename);
125 return file_path_.
c_str();
151 const StringRefNull name_with_idcode = get_name_with_idcode();
152 return GS(name_with_idcode.
c_str());
157 const StringRefNull name_with_idcode = get_name_with_idcode();
158 return name_with_idcode.
substr(2);
188 const std::string &catalog_id =
197 if (value_ptr ==
nullptr) {
204 const StringRefNull tag_name = item->as_string_value()->value();
214 if (value_ptr ==
nullptr) {
218 const Value &value = *(value_ptr->get());
240 char idcode_prefix[2];
242 *((
short *)idcode_prefix) = idcode;
243 std::string name_with_idcode = std::string(idcode_prefix,
sizeof(idcode_prefix)) + name;
284 if (value ==
nullptr) {
305 if (asset_data.
author !=
nullptr) {
335 items.append_as(entry_value);
340 if (items.is_empty()) {
354 const std::string &name = entry.
get_name();
363 char *description_c_str =
static_cast<char *
>(
MEM_mallocN(description.length() + 1, __func__));
364 BLI_strncpy(description_c_str, description.c_str(), description.length() + 1);
368 const std::string &author = entry.
get_author();
369 char *author_c_str =
static_cast<char *
>(
MEM_mallocN(author.length() + 1, __func__));
370 BLI_strncpy(author_c_str, author.c_str(), author.length() + 1);
371 asset_data->
author = author_c_str;
376 catalog_name.c_str(),
392 if (entries_value ==
nullptr) {
396 int num_entries_read = 0;
397 const ArrayValue::Items elements = (*entries_value)->as_array_value()->elements();
406 num_entries_read += 1;
409 return num_entries_read;
439 init_indices_base_path();
445 return hasher(get_library_file_path());
463 BLI_path_append(index_path,
sizeof(index_path),
"asset-library-indices");
465 std::stringstream ss;
466 ss << std::setfill(
'0') << std::setw(16) <<
std::hex <<
hash() <<
"/";
469 indices_base_path = std::string(index_path);
479 std::stringstream ss;
480 ss << indices_base_path;
481 ss << std::setfill(
'0') << std::setw(16) <<
std::hex << asset_file.
hash() <<
"_"
491 const char *index_path = indices_base_path.c_str();
495 struct direntry *dir_entries =
nullptr;
497 for (
int i = 0; i < dir_entries_num; i++) {
498 struct direntry *entry = &dir_entries[i];
500 unused_file_indices.
add_as(std::string(entry->
path));
509 unused_file_indices.
remove(filename);
514 int num_files_deleted = 0;
515 for (
const std::string &unused_index : unused_file_indices) {
516 const char *file_path = unused_index.c_str();
517 CLOG_INFO(&
LOG, 2,
"Remove unused index file [%s].", file_path);
522 return num_files_deleted;
544 static const int CURRENT_VERSION = 1;
549 const int UNKNOWN_VERSION = -1;
566 std::unique_ptr<DictionaryValue> root = std::make_unique<DictionaryValue>();
571 contents = std::move(root);
585 if (root ==
nullptr) {
586 return UNKNOWN_VERSION;
590 if (version_value ==
nullptr) {
591 return UNKNOWN_VERSION;
598 return get_version() == CURRENT_VERSION;
610 return num_entries_read;
621 const size_t MIN_FILE_SIZE_WITH_ENTRIES = 32;
625 : library_index(library_index), filename(library_index.index_file_path(asset_filename))
636 return filename.c_str();
652 const size_t file_size = get_file_size();
653 return file_size >= MIN_FILE_SIZE_WITH_ENTRIES;
661 std::unique_ptr<Value> read_data = formatter.
deserialize(is);
664 return std::make_unique<AssetIndex>(read_data);
677 if (!ensure_parent_path_exists()) {
678 CLOG_ERROR(&
LOG,
"Index not created: couldn't create folder [%s].", get_file_path());
691 int *r_read_entries_len,
698 if (!asset_index_file.
exists()) {
712 "Asset index file [%s] needs to be refreshed as it is older than the asset file [%s].",
721 "Asset file index is to small to contain any entries. [%s]",
723 *r_read_entries_len = 0;
727 std::unique_ptr<AssetIndex> contents = asset_index_file.
read_contents();
728 if (!contents->is_latest_version()) {
731 "Asset file index is ignored; expected version %d but file is version %d [%s].",
733 contents->get_version(),
738 const int read_entries_len = contents->extract_into(*entries);
739 CLOG_INFO(&
LOG, 1,
"Read %d entries from asset index for [%s].", read_entries_len, filename);
740 *r_read_entries_len = read_entries_len;
752 "Update asset index for [%s] store index in [%s].",
760 static void *
init_user_data(
const char *root_directory,
size_t root_directory_maxlen)
765 return library_index;
777 if (num_indices_removed > 0) {
778 CLOG_INFO(&
LOG, 1,
"Removed %d unused indices.", num_indices_removed);
bool BKE_appdir_folder_caches(char *r_path, size_t path_len)
struct AssetMetaData * BKE_asset_metadata_create(void)
struct AssetTag * BKE_asset_metadata_tag_add(struct AssetMetaData *asset_data, const char *name)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
bool BLI_make_existing_file(const char *name)
void BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file) ATTR_NONNULL()
void BLI_split_file_part(const char *string, char *file, size_t filelen)
size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
void BLI_uuid_format(char *buffer, bUUID uuid) ATTR_NONNULL()
#define CLOG_ERROR(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
@ FILE_INDEXER_ENTRIES_LOADED
@ FILE_INDEXER_NEEDS_UPDATE
const FileIndexerType file_indexer_asset
ATTR_WARN_UNUSED_RESULT const void * element
const Value * lookup_ptr(const Key &key) const
bool add_as(ForwardKey &&key)
bool remove(const Key &key)
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr const char * c_str() const
virtual ~AbstractFile()=default
virtual const char * get_file_path() const =0
size_t get_file_size() const
AssetLibraryIndex & library_index
bool ensure_parent_path_exists() const
bool constains_entries() const
std::unique_ptr< AssetIndex > read_contents() const
bool is_older_than(BlendFile &asset_file) const
AssetIndexFile(AssetLibraryIndex &library_index, BlendFile &asset_filename)
const char * get_file_path() const override
void write_contents(AssetIndex &content)
Reference to a blend file that can be indexed.
const char * get_file_path() const override
BlendFile(StringRefNull file_path)
std::string get_filename() const
const Container & elements() const
std::shared_ptr< Value > LookupValue
const Lookup create_lookup() const
const ArrayValue * as_array_value() const
const IntValue * as_int_value() const
const DictionaryValue * as_dictionary_value() const
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
GAttributeReader lookup(const void *owner, const AttributeIDRef &attribute_id)
std::unique_ptr< io::serialize::ArrayValue > convert_to_serialize_values(const IDProperty *properties)
Convert the given properties to Value objects for serialization.
IDProperty * convert_from_serialize_value(const blender::io::serialize::Value &value)
Convert the given value to an IDProperty.
static void free_user_data(void *user_data)
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_NAME("catalog_name")
constexpr StringRef ATTRIBUTE_ENTRIES_TAGS("tags")
constexpr StringRef ATTRIBUTE_ENTRIES_NAME("name")
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_ID("catalog_id")
static int init_indexer_entries_from_value(FileIndexerEntries &indexer_entries, const DictionaryValue &value)
static void * init_user_data(const char *root_directory, size_t root_directory_maxlen)
constexpr StringRef ATTRIBUTE_ENTRIES_DESCRIPTION("description")
constexpr StringRef ATTRIBUTE_ENTRIES_PROPERTIES("properties")
static void filelist_finished(void *user_data)
static void init_value_from_file_indexer_entry(AssetEntryWriter &result, const FileIndexerEntry *indexer_entry)
static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry, const AssetEntryReader &entry)
static eFileIndexerResult read_index(const char *filename, FileIndexerEntries *entries, int *r_read_entries_len, void *user_data)
constexpr StringRef ATTRIBUTE_VERSION("version")
Indexer for asset libraries.
constexpr StringRef ATTRIBUTE_ENTRIES("entries")
static void init_value_from_file_indexer_entries(DictionaryValue &result, const FileIndexerEntries &indexer_entries)
constexpr StringRef ATTRIBUTE_ENTRIES_AUTHOR("author")
constexpr FileIndexerType asset_indexer()
static void update_index(const char *filename, FileIndexerEntries *entries, void *user_data)
PrimitiveValue< int64_t, eValueType::Int > IntValue
ContainerValue< Vector< std::shared_ptr< Value > >, eValueType::Array > ArrayValue
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
unsigned __int64 uint64_t
User defined tag. Currently only used by assets, could be used more often at some point....
struct AssetMetaData * asset_data
struct LinkNode * entries
struct BLODataBlockInfo datablock_info
FileIndexerUpdateIndexFunc update_index
FileIndexerFinishedFunc filelist_finished
FileIndexerReadIndexFunc read_index
FileIndexerFreeUserDataFunc free_user_data
FileIndexerInitUserDataFunc init_user_data
Universally Unique Identifier according to RFC4122.
Single entry inside a #AssetIndexFile for reading.
void add_properties_to_meta_data(AssetMetaData *asset_data) const
StringRefNull get_author() const
StringRefNull get_description() const
CatalogID get_catalog_id() const
void add_tags_to_meta_data(AssetMetaData *asset_data) const
ID_Type get_idcode() const
StringRefNull get_catalog_name() const
bool has_description() const
StringRef get_name() const
AssetEntryReader(const DictionaryValue &entry)
AssetEntryWriter(DictionaryValue &entry)
void add_author(const StringRefNull author)
void add_tags(const ListBase *asset_tags)
void add_catalog_id(const CatalogID &catalog_id)
void add_catalog_name(const StringRefNull catalog_name)
void add_id_name(const short idcode, const StringRefNull name)
add id + name to the attributes.
void add_properties(const IDProperty *properties)
void add_description(const StringRefNull description)
AssetIndex(std::unique_ptr< Value > &value)
bool is_latest_version() const
int extract_into(FileIndexerEntries &indexer_entries) const
AssetIndex(const FileIndexerEntries &indexer_entries)
static const int CURRENT_VERSION
Version to store in new index files.
std::unique_ptr< Value > contents
References the asset library directory.
Set< std::string > unused_file_indices
void mark_as_used(const std::string &filename)
AssetLibraryIndex(const StringRef library_path)
std::string index_file_path(const BlendFile &asset_file) const
void init_unused_index_files()
void init_indices_base_path()
Initializes #AssetLibraryIndex.indices_base_path.
std::string indices_base_path
Absolute path where the indices of library are stored.
int remove_unused_index_files() const
StringRefNull get_library_file_path() const
static const char hex[17]