122 return hasher(file_path_);
129 return std::string(filename);
134 return file_path_.
c_str();
145 char idcode_prefix[2];
147 *((
short *)idcode_prefix) = idcode;
148 std::string name_with_idcode = std::string(idcode_prefix,
sizeof(idcode_prefix)) + name;
164 if (
const char *description = asset_data.
description) {
167 if (
const char *author = asset_data.
author) {
170 if (
const char *copyright = asset_data.
copyright) {
173 if (
const char *license = asset_data.
license) {
194 auto entries = std::make_shared<ArrayValue>();
208 if (entries->elements().is_empty()) {
248 for (
const std::shared_ptr<Value> &item : array_value->elements()) {
263 if (entries ==
nullptr) {
267 int num_entries_read = 0;
268 for (
const std::shared_ptr<Value> &element : entries->
elements()) {
274 num_entries_read += 1;
277 return num_entries_read;
336 BLI_path_append(index_path,
sizeof(index_path),
"asset-library-indices");
338 std::stringstream ss;
339 ss << std::setfill(
'0') << std::setw(16) << std::hex <<
hash() <<
SEP_STR;
342 this->indices_base_path = std::string(index_path);
352 std::stringstream ss;
354 ss << std::setfill(
'0') << std::setw(16) << std::hex << asset_file.
hash() <<
"_"
365 const char *index_path = this->indices_base_path.c_str();
371 for (
int i = 0; i < dir_entries_num; i++) {
374 this->preexisting_file_indices.add_as(std::string(entry->
path));
396 if (
BLI_delete(filename.c_str(),
false,
false) == 0) {
397 this->preexisting_file_indices.remove(filename);
412 int num_files_deleted = 0;
416 for (
auto preexisting_index : this->preexisting_file_indices.items()) {
417 if (preexisting_index.value.is_used) {
421 const std::string &file_path = preexisting_index.key;
422 CLOG_INFO(&
LOG, 2,
"Remove unused index file [%s].", file_path.c_str());
423 files_to_remove.
add(preexisting_index.key);
426 for (
StringRef file_to_remove : files_to_remove) {
432 return num_files_deleted;
476 std::unique_ptr<DictionaryValue> root = std::make_unique<DictionaryValue>();
480 this->contents = std::move(root);
492 if (root ==
nullptr) {
513 return num_entries_read;
568 is.open(this->filename);
571 std::unique_ptr<Value> read_data = formatter.
deserialize(is);
576 return std::make_unique<AssetIndex>(read_data);
593 os.open(this->filename, std::ios::out | std::ios::trunc);
594 formatter.
serialize(os, *content.contents);
619 tm_from.tm_year = 2022 - 1900;
620 tm_from.tm_mon = 11 - 1;
623 tm_from.tm_year = 2022 - 1900;
624 tm_from.tm_mon = 12 - 1;
626 std::time_t timestamp_from = std::mktime(&tm_from);
627 std::time_t timestamp_to = std::mktime(&tm_to);
632 if (
IN_RANGE(stat.st_mtime, timestamp_from, timestamp_to)) {
633 CLOG_INFO(&
LOG, 2,
"Remove potentially broken index file [%s].", index_path.c_str());
634 files_to_remove.
add(index_path);
638 int num_files_deleted = 0;
639 for (
StringRef filepath : files_to_remove) {
645 return num_files_deleted;
650 int *r_read_entries_len,
657 if (!asset_index_file.
exists()) {
671 "Asset index file [%s] needs to be refreshed as it is older than the asset file [%s].",
680 "Asset file index is to small to contain any entries. [%s]",
682 *r_read_entries_len = 0;
686 std::unique_ptr<AssetIndex> contents = asset_index_file.
read_contents();
688 CLOG_INFO(&
LOG, 3,
"Asset file index is ignored; failed to read contents.");
692 if (!contents->is_latest_version()) {
695 "Asset file index is ignored; expected version %d but file is version %d [%s].",
697 contents->get_version(),
702 const int read_entries_len = contents->extract_into(*entries);
703 CLOG_INFO(&
LOG, 1,
"Read %d entries from asset index for [%s].", read_entries_len, filename);
704 *r_read_entries_len = read_entries_len;
716 "Update asset index for [%s] store index in [%s].",
724static void *
init_user_data(
const char *root_directory,
size_t root_directory_maxncpy)
730 return library_index;
742 if (num_indices_removed > 0) {
743 CLOG_INFO(&
LOG, 1,
"Removed %d unused indices.", num_indices_removed);
bool BKE_appdir_folder_caches(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
AssetMetaData * BKE_asset_metadata_create()
AssetTag * BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name) ATTR_NONNULL(1
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_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
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)
bool BLI_file_ensure_parent_dir_exists(const char *filepath) ATTR_NONNULL(1)
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)
#define BLI_SCOPED_DEFER(function_to_defer)
size_t BLI_path_append(char *__restrict dst, size_t dst_maxncpy, const char *__restrict file) ATTR_NONNULL(1
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int bool bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define IN_RANGE(a, b, c)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
@ FILE_INDEXER_ENTRIES_LOADED
@ FILE_INDEXER_NEEDS_UPDATE
void copy(char *dst, int64_t dst_size) const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr const char * data() const
constexpr const char * c_str() const
virtual ~AbstractFile()=default
size_t get_file_size() const
virtual const char * get_file_path() const =0
AssetLibraryIndex & library_index
bool ensure_parent_path_exists() const
bool constains_entries() const
const char * get_file_path() const override
AssetIndexFile(AssetLibraryIndex &library_index, BlendFile &asset_filename)
std::unique_ptr< AssetIndex > read_contents() const
bool is_older_than(const BlendFile &asset_file) const
void write_contents(AssetIndex &content)
const size_t MIN_FILE_SIZE_WITH_ENTRIES
AssetIndexFile(AssetLibraryIndex &library_index, StringRef index_file_path)
Reference to a blend file that can be indexed.
BlendFile(StringRefNull file_path)
const char * get_file_path() const override
std::string get_filename() const
Span< std::shared_ptr< Value > > elements() const
std::shared_ptr< ArrayValue > append_array()
void append_str(std::string value)
const std::shared_ptr< Value > * lookup(const StringRef key) const
const ArrayValue * lookup_array(const StringRef key) const
std::optional< int64_t > lookup_int(const StringRef key) const
std::optional< StringRefNull > lookup_str(const StringRef key) const
void *(* MEM_callocN)(size_t len, const char *str)
std::unique_ptr< blender::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")
static void * init_user_data(const char *root_directory, size_t root_directory_maxncpy)
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_ID("catalog_id")
static int init_indexer_entries_from_value(FileIndexerEntries &indexer_entries, const DictionaryValue &value)
constexpr StringRef ATTRIBUTE_ENTRIES_DESCRIPTION("description")
constexpr StringRef ATTRIBUTE_ENTRIES_PROPERTIES("properties")
const FileIndexerType file_indexer_asset
static void filelist_finished(void *user_data)
static eFileIndexerResult read_index(const char *filename, FileIndexerEntries *entries, int *r_read_entries_len, void *user_data)
constexpr StringRef ATTRIBUTE_ENTRIES_LICENSE("license")
constexpr StringRef ATTRIBUTE_VERSION("version")
Indexer for asset libraries.
static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry, const DictionaryValue &entry)
static void init_value_from_file_indexer_entry(DictionaryValue &result, const FileIndexerEntry *indexer_entry)
constexpr StringRef ATTRIBUTE_ENTRIES("entries")
static void add_id_name(DictionaryValue &result, const short idcode, const StringRefNull name)
add id + name to the attributes.
static void init_value_from_file_indexer_entries(DictionaryValue &result, const FileIndexerEntries &indexer_entries)
constexpr StringRef ATTRIBUTE_ENTRIES_COPYRIGHT("copyright")
constexpr StringRef ATTRIBUTE_ENTRIES_AUTHOR("author")
constexpr FileIndexerType asset_indexer()
static void update_index(const char *filename, FileIndexerEntries *entries, void *user_data)
uint64_t get_default_hash(const T &v)
unsigned __int64 uint64_t
User defined tag. Currently only used by assets, could be used more often at some point....
AssetMetaData * asset_data
BLODataBlockInfo datablock_info
FileIndexerUpdateIndexFunc update_index
FileIndexerFinishedFunc filelist_finished
FileIndexerReadIndexFunc read_index
FileIndexerFreeUserDataFunc free_user_data
FileIndexerInitUserDataFunc init_user_data
AssetIndex(std::unique_ptr< Value > &value)
bool is_latest_version() const
int extract_into(FileIndexerEntries &indexer_entries) const
AssetIndex(const FileIndexerEntries &indexer_entries)
const int UNKNOWN_VERSION
static const int CURRENT_VERSION
Version to store in new index files.
std::unique_ptr< Value > contents
References the asset library directory.
void mark_as_used(const std::string &filename)
int remove_unused_index_files()
int remove_broken_index_files()
AssetLibraryIndex(const StringRef library_path)
std::string index_file_path(const BlendFile &asset_file) const
void collect_preexisting_file_indices()
Map< std::string, PreexistingFileIndexInfo > preexisting_file_indices
bool delete_file_index(const std::string &filename)
void init_indices_base_path()
Initializes AssetLibraryIndex.indices_base_path.
std::string indices_base_path
Absolute path where the indices of library are stored.
StringRefNull get_library_file_path() const