Blender V4.3
AS_asset_catalog.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include <memory>
12#include <mutex>
13#include <set>
14#include <string>
15
16#include "BLI_function_ref.hh"
17#include "BLI_map.hh"
18#include "BLI_set.hh"
19#include "BLI_uuid.h"
20#include "BLI_vector.hh"
21
23
25
26class AssetCatalog;
31
33using CatalogPathComponent = std::string;
34/* Would be nice to be able to use `std::filesystem::path` for this, but it's currently not
35 * available on the minimum macOS target version. */
36using CatalogFilePath = std::string;
38
39/* Manages the asset catalogs of a single asset library (i.e. of catalogs defined in a single
40 * directory hierarchy). */
42 std::unique_ptr<AssetCatalogCollection> catalog_collection_;
43
47 std::unique_ptr<AssetCatalogTree> catalog_tree_;
48 std::mutex catalog_tree_mutex_;
49
52
53 const CatalogFilePath asset_library_root_;
54 const bool is_read_only_ = false;
55
56 public:
58
59 struct read_only_tag {};
60
61 public:
62 explicit AssetCatalogService(const CatalogFilePath &asset_library_root = {});
63 explicit AssetCatalogService(read_only_tag);
64
72 void tag_has_unsaved_changes(AssetCatalog *edited_catalog);
73 bool has_unsaved_changes() const;
74
80 bool is_read_only() const;
81
83 void load_from_disk();
85 void load_from_disk(const CatalogFilePath &file_or_directory_path);
86
94 void add_from_existing(const AssetCatalogService &other_service,
95 FunctionRef<void(const AssetCatalog &existing,
96 const AssetCatalog &to_be_ignored)> on_duplicate_items);
97
115 bool write_to_disk(const CatalogFilePath &blend_file_path);
116
125
134 void reload_catalogs();
135
137 AssetCatalog *find_catalog(CatalogID catalog_id) const;
138
146
150 bool is_catalog_known(CatalogID catalog_id) const;
151
158 AssetCatalogFilter create_catalog_filter(CatalogID active_catalog_id) const;
159
162 AssetCatalog *create_catalog(const AssetCatalogPath &catalog_path);
163
168
173 void prune_catalogs_by_id(CatalogID catalog_id);
174
178 void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path);
179
184
186 bool is_empty() const;
187
191 void undo_push();
196 void undo();
197 bool is_undo_possbile() const;
201 void redo();
202 bool is_redo_possbile() const;
203
204 protected:
205 void load_directory_recursive(const CatalogFilePath &directory_path);
206 void load_single_file(const CatalogFilePath &catalog_definition_file_path);
207
209 bool write_to_disk_ex(const CatalogFilePath &blend_file_path);
212
220 void purge_catalogs_not_listed(const Set<CatalogID> &catalogs_to_keep);
221
230 void delete_catalog_by_id_soft(CatalogID catalog_id);
231
235 void delete_catalog_by_id_hard(CatalogID catalog_id);
236
237 std::unique_ptr<AssetCatalogDefinitionFile> parse_catalog_file(
238 const CatalogFilePath &catalog_definition_file_path);
239
243 std::unique_ptr<AssetCatalogDefinitionFile> construct_cdf_in_memory(
244 const CatalogFilePath &file_path) const;
245
253 const CatalogFilePath &blend_file_path);
254
255 std::unique_ptr<AssetCatalogTree> read_into_tree() const;
262
267
272
273 /* For access by subclasses, as those will not be marked as friend by #AssetCatalogCollection. */
275 const OwningAssetCatalogMap &get_catalogs() const;
277};
278
288 public:
298 std::string simple_name;
299
300 struct Flags {
301 /* Treat this catalog as deleted. Keeping deleted catalogs around is necessary to support
302 * merging of on-disk changes with in-memory changes. */
303 bool is_deleted = false;
304
305 /* Sort this catalog first when there are multiple catalogs with the same catalog path. This
306 * ensures that in a situation where missing catalogs were auto-created, and then
307 * load-and-merged with a file that also has these catalogs, the first one in that file is
308 * always sorted first, regardless of the sort order of its UUID. */
309 bool is_first_loaded = false;
310
311 /* Merging on-disk changes into memory will not overwrite this catalog.
312 * For example, when a catalog was renamed (i.e. changed path) in this Blender session,
313 * reloading the catalog definition file should not overwrite that change.
314 *
315 * Note that this flag is ignored when is_deleted=true; deleted catalogs that are still in
316 * memory are considered "unsaved" by definition. */
319
320 public:
321 AssetCatalog() = delete;
323
330 static std::unique_ptr<AssetCatalog> from_path(const AssetCatalogPath &path);
331
333 void simple_name_refresh();
334
335 protected:
337 static std::string sensible_simple_name_for_path(const AssetCatalogPath &path);
338};
339
342 bool operator()(const AssetCatalog *lhs, const AssetCatalog *rhs) const
343 {
344 if (lhs->path != rhs->path) {
345 return lhs->path < rhs->path;
346 }
347
348 if (lhs->flags.is_first_loaded != rhs->flags.is_first_loaded) {
349 return lhs->flags.is_first_loaded;
350 }
351
352 return lhs->catalog_id < rhs->catalog_id;
353 }
354};
355
359using AssetCatalogOrderedSet = std::set<const AssetCatalog *, AssetCatalogLessThan>;
360using MutableAssetCatalogOrderedSet = std::set<AssetCatalog *, AssetCatalogLessThan>;
361
368 const Set<CatalogID> matching_catalog_ids_;
369 const Set<CatalogID> known_catalog_ids_;
370
371 friend AssetCatalogService;
372
373 public:
374 bool contains(CatalogID asset_catalog_id) const;
375
376 /* So that all unknown catalogs can be shown under "Unassigned". */
377 bool is_known(CatalogID asset_catalog_id) const;
378
379 protected:
380 explicit AssetCatalogFilter(Set<CatalogID> &&matching_catalog_ids,
381 Set<CatalogID> &&known_catalog_ids);
382};
383
384} // namespace blender::asset_system
struct bUUID bUUID
Universally Unique Identifier according to RFC4122.
AssetCatalogFilter(Set< CatalogID > &&matching_catalog_ids, Set< CatalogID > &&known_catalog_ids)
void load_single_file(const CatalogFilePath &catalog_definition_file_path)
AssetCatalogFilter create_catalog_filter(CatalogID active_catalog_id) const
AssetCatalog * find_catalog_by_path(const AssetCatalogPath &path) const
AssetCatalog * find_catalog(CatalogID catalog_id) const
bool write_to_disk(const CatalogFilePath &blend_file_path)
std::unique_ptr< AssetCatalogTree > read_into_tree() const
void purge_catalogs_not_listed(const Set< CatalogID > &catalogs_to_keep)
std::unique_ptr< AssetCatalogDefinitionFile > parse_catalog_file(const CatalogFilePath &catalog_definition_file_path)
std::unique_ptr< AssetCatalogDefinitionFile > construct_cdf_in_memory(const CatalogFilePath &file_path) const
AssetCatalogService(const CatalogFilePath &asset_library_root={})
AssetCatalog * create_catalog(const AssetCatalogPath &catalog_path)
void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path)
void add_from_existing(const AssetCatalogService &other_service, FunctionRef< void(const AssetCatalog &existing, const AssetCatalog &to_be_ignored)> on_duplicate_items)
static CatalogFilePath find_suitable_cdf_path_for_writing(const CatalogFilePath &blend_file_path)
bool write_to_disk_ex(const CatalogFilePath &blend_file_path)
void load_directory_recursive(const CatalogFilePath &directory_path)
bool is_catalog_known_with_unsaved_changes(CatalogID catalog_id) const
static const CatalogFilePath DEFAULT_CATALOG_FILENAME
const AssetCatalogDefinitionFile * get_catalog_definition_file() const
static std::unique_ptr< AssetCatalog > from_path(const AssetCatalogPath &path)
static std::string sensible_simple_name_for_path(const AssetCatalogPath &path)
struct blender::asset_system::AssetCatalog::Flags flags
local_group_size(16, 16) .push_constant(Type rhs
std::set< AssetCatalog *, AssetCatalogLessThan > MutableAssetCatalogOrderedSet
std::set< const AssetCatalog *, AssetCatalogLessThan > AssetCatalogOrderedSet
Universally Unique Identifier according to RFC4122.
bool operator()(const AssetCatalog *lhs, const AssetCatalog *rhs) const