43using namespace blender::asset_system;
44using namespace blender::io::serialize;
45using namespace blender::bke::idprop;
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;
273 num_entries_read += 1;
276 return num_entries_read;
322 return this->library_path;
335 BLI_path_append(index_path,
sizeof(index_path),
"asset-library-indices");
337 std::stringstream ss;
338 ss << std::setfill(
'0') << std::setw(16) << std::hex <<
hash() <<
SEP_STR;
341 this->indices_base_path = std::string(index_path);
351 std::stringstream ss;
352 ss << this->indices_base_path;
353 ss << std::setfill(
'0') << std::setw(16) << std::hex << asset_file.
hash() <<
"_"
364 const char *index_path = this->indices_base_path.c_str();
370 for (
int i = 0;
i < dir_entries_num;
i++) {
373 this->preexisting_file_indices.add_as(std::string(entry->
path));
395 if (
BLI_delete(filename.c_str(),
false,
false) == 0) {
396 this->preexisting_file_indices.remove(filename);
411 int num_files_deleted = 0;
415 for (
auto preexisting_index : this->preexisting_file_indices.items()) {
416 if (preexisting_index.value.is_used) {
420 const std::string &file_path = preexisting_index.key;
421 CLOG_DEBUG(&
LOG,
"Remove unused index file \"%s\".", file_path.c_str());
422 files_to_remove.
add(preexisting_index.key);
425 for (
StringRef file_to_remove : files_to_remove) {
431 return num_files_deleted;
475 std::unique_ptr<DictionaryValue> root = std::make_unique<DictionaryValue>();
479 this->contents = std::move(root);
491 if (root ==
nullptr) {
512 return num_entries_read;
567 is.open(this->filename);
570 std::unique_ptr<Value> read_data = formatter.
deserialize(is);
575 return std::make_unique<AssetIndex>(read_data);
592 os.open(this->filename, std::ios::out | std::ios::trunc);
618 tm_from.tm_year = 2022 - 1900;
619 tm_from.tm_mon = 11 - 1;
622 tm_from.tm_year = 2022 - 1900;
623 tm_from.tm_mon = 12 - 1;
625 std::time_t timestamp_from = std::mktime(&tm_from);
626 std::time_t timestamp_to = std::mktime(&tm_to);
631 if (
IN_RANGE(stat.st_mtime, timestamp_from, timestamp_to)) {
632 CLOG_DEBUG(&
LOG,
"Remove potentially broken index file \"%s\".", index_path.c_str());
633 files_to_remove.
add(index_path);
637 int num_files_deleted = 0;
638 for (
StringRef filepath : files_to_remove) {
644 return num_files_deleted;
649 int *r_read_entries_len,
656 if (!asset_index_file.
exists()) {
669 "Asset index file \"%s\" needs to be refreshed as it is older than the asset file \"%s\".",
677 "Asset file index is to small to contain any entries. \"%s\"",
679 *r_read_entries_len = 0;
683 std::unique_ptr<AssetIndex> contents = asset_index_file.
read_contents();
685 CLOG_DEBUG(&
LOG,
"Asset file index is ignored; failed to read contents.");
689 if (!contents->is_latest_version()) {
691 "Asset file index is ignored; expected version %d but file is version %d \"%s\".",
693 contents->get_version(),
698 const int read_entries_len = contents->extract_into(*entries);
699 CLOG_INFO(&
LOG,
"Read %d entries for \"%s\".", read_entries_len, filename);
700 *r_read_entries_len = read_entries_len;
711 "Update for \"%s\" store index in \"%s\".",
719static void *
init_user_data(
const char *root_directory,
size_t root_directory_maxncpy)
725 return library_index;
737 if (num_indices_removed > 0) {
738 CLOG_INFO(&
LOG,
"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)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#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_DEBUG(clg_ref,...)
#define CLOG_INFO(clg_ref,...)
ID and Library types, which are fundamental for SDNA.
@ FILE_INDEXER_ENTRIES_LOADED
@ FILE_INDEXER_NEEDS_UPDATE
ATTR_WARN_UNUSED_RESULT const void * element
unsigned long long int uint64_t
constexpr StringRef substr(int64_t start, int64_t size) const
void copy_utf8_truncated(char *dst, int64_t dst_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
void append_str(std::string value)
const std::shared_ptr< Value > * lookup(StringRef key) const
std::optional< StringRefNull > lookup_str(StringRef key) const
std::optional< int64_t > lookup_int(StringRef key) const
const ArrayValue * lookup_array(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, const Args &...args)
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