Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/asset_catalog.cc')
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc147
1 files changed, 113 insertions, 34 deletions
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index 4f1de09e148..b65ae12e5a7 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -64,6 +64,17 @@ AssetCatalog *AssetCatalogService::find_catalog(CatalogID catalog_id)
return catalog_uptr_ptr->get();
}
+AssetCatalog *AssetCatalogService::find_catalog_by_path(const CatalogPath &path) const
+{
+ for (auto &catalog : catalogs_.values()) {
+ if (catalog->path == path) {
+ return catalog.get();
+ }
+ }
+
+ return nullptr;
+}
+
void AssetCatalogService::delete_catalog(CatalogID catalog_id)
{
std::unique_ptr<AssetCatalog> *catalog_uptr_ptr = this->catalogs_.lookup_ptr(catalog_id);
@@ -104,6 +115,12 @@ AssetCatalog *AssetCatalogService::create_catalog(const CatalogPath &catalog_pat
catalog_definition_file_->add_new(catalog_ptr);
}
+ /* The tree may not exist; this happens when no catalog definition file has been loaded yet. When
+ * the tree is created any in-memory catalogs will be added, so it doesn't need to happen now. */
+ if (catalog_tree_) {
+ catalog_tree_->insert_item(*catalog_ptr);
+ }
+
return catalog_ptr;
}
@@ -268,34 +285,7 @@ std::unique_ptr<AssetCatalogTree> AssetCatalogService::read_into_tree()
/* Go through the catalogs, insert each path component into the tree where needed. */
for (auto &catalog : catalogs_.values()) {
- const AssetCatalogTreeItem *parent = nullptr;
- AssetCatalogTreeItem::ChildMap *insert_to_map = &tree->children_;
-
- BLI_assert_msg(!ELEM(catalog->path[0], '/', '\\'),
- "Malformed catalog path; should not start with a separator");
-
- const char *next_slash_ptr;
- /* Looks more complicated than it is, this just iterates over path components. E.g.
- * "just/some/path" iterates over "just", then "some" then "path". */
- for (const char *name_begin = catalog->path.data(); name_begin && name_begin[0];
- /* Jump to one after the next slash if there is any. */
- name_begin = next_slash_ptr ? next_slash_ptr + 1 : nullptr) {
- next_slash_ptr = BLI_path_slash_find(name_begin);
-
- /* Note that this won't be null terminated. */
- StringRef component_name = next_slash_ptr ?
- StringRef(name_begin, next_slash_ptr - name_begin) :
- /* Last component in the path. */
- name_begin;
-
- /* Insert new tree element - if no matching one is there yet! */
- auto [item, was_inserted] = insert_to_map->emplace(
- component_name, AssetCatalogTreeItem(component_name, parent));
-
- /* Walk further into the path (no matter if a new item was created or not). */
- parent = &item->second;
- insert_to_map = &item->second.children_;
- }
+ tree->insert_item(*catalog);
}
return tree;
@@ -306,9 +296,18 @@ void AssetCatalogService::rebuild_tree()
this->catalog_tree_ = read_into_tree();
}
-AssetCatalogTreeItem::AssetCatalogTreeItem(StringRef name, const AssetCatalogTreeItem *parent)
- : name_(name), parent_(parent)
+/* ---------------------------------------------------------------------- */
+
+AssetCatalogTreeItem::AssetCatalogTreeItem(StringRef name,
+ CatalogID catalog_id,
+ const AssetCatalogTreeItem *parent)
+ : name_(name), catalog_id_(catalog_id), parent_(parent)
+{
+}
+
+CatalogID AssetCatalogTreeItem::get_catalog_id() const
{
+ return catalog_id_;
}
StringRef AssetCatalogTreeItem::get_name() const
@@ -334,20 +333,100 @@ int AssetCatalogTreeItem::count_parents() const
return i;
}
-void AssetCatalogTree::foreach_item(const AssetCatalogTreeItem::ItemIterFn callback) const
+bool AssetCatalogTreeItem::has_children() const
+{
+ return !children_.empty();
+}
+
+/* ---------------------------------------------------------------------- */
+
+/**
+ * Iterate over path components, calling \a callback for each component. E.g. "just/some/path"
+ * iterates over "just", then "some" then "path".
+ */
+static void iterate_over_catalog_path_components(
+ const CatalogPath &path,
+ FunctionRef<void(StringRef component_name, bool is_last_component)> callback)
+{
+ const char *next_slash_ptr;
+
+ for (const char *path_component = path.data(); path_component && path_component[0];
+ /* Jump to one after the next slash if there is any. */
+ path_component = next_slash_ptr ? next_slash_ptr + 1 : nullptr) {
+ next_slash_ptr = BLI_path_slash_find(path_component);
+
+ const bool is_last_component = next_slash_ptr == nullptr;
+ /* Note that this won't be null terminated. */
+ const StringRef component_name = is_last_component ?
+ path_component :
+ StringRef(path_component,
+ next_slash_ptr - path_component);
+
+ callback(component_name, is_last_component);
+ }
+}
+
+void AssetCatalogTree::insert_item(const AssetCatalog &catalog)
+{
+ const AssetCatalogTreeItem *parent = nullptr;
+ /* The children for the currently iterated component, where the following component should be
+ * added to (if not there yet). */
+ AssetCatalogTreeItem::ChildMap *current_item_children = &root_items_;
+
+ BLI_assert_msg(!ELEM(catalog.path[0], '/', '\\'),
+ "Malformed catalog path; should not start with a separator");
+
+ const CatalogID nil_id{};
+
+ iterate_over_catalog_path_components(
+ catalog.path, [&](StringRef component_name, const bool is_last_component) {
+ /* Insert new tree element - if no matching one is there yet! */
+ auto [key_and_item, was_inserted] = current_item_children->emplace(
+ component_name,
+ AssetCatalogTreeItem(
+ component_name, is_last_component ? catalog.catalog_id : nil_id, parent));
+ AssetCatalogTreeItem &item = key_and_item->second;
+
+ /* If full path of this catalog already exists as parent path of a previously read catalog,
+ * we can ensure this tree item's UUID is set here. */
+ if (is_last_component && BLI_uuid_is_nil(item.catalog_id_)) {
+ item.catalog_id_ = catalog.catalog_id;
+ }
+
+ /* Walk further into the path (no matter if a new item was created or not). */
+ parent = &item;
+ current_item_children = &item.children_;
+ });
+}
+
+void AssetCatalogTree::foreach_item(AssetCatalogTreeItem::ItemIterFn callback)
{
- AssetCatalogTreeItem::foreach_item_recursive(children_, callback);
+ AssetCatalogTreeItem::foreach_item_recursive(root_items_, callback);
}
-void AssetCatalogTreeItem::foreach_item_recursive(const AssetCatalogTreeItem::ChildMap &children,
+void AssetCatalogTreeItem::foreach_item_recursive(AssetCatalogTreeItem::ChildMap &children,
const ItemIterFn callback)
{
- for (const auto &[key, item] : children) {
+ for (auto &[key, item] : children) {
callback(item);
foreach_item_recursive(item.children_, callback);
}
}
+void AssetCatalogTree::foreach_root_item(const ItemIterFn callback)
+{
+ for (auto &[key, item] : root_items_) {
+ callback(item);
+ }
+}
+
+void AssetCatalogTreeItem::foreach_child(const ItemIterFn callback)
+{
+ for (auto &[key, item] : children_) {
+ callback(item);
+ }
+}
+
AssetCatalogTree *AssetCatalogService::get_catalog_tree()
{
return catalog_tree_.get();