WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 391 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
9 changed files with 31 additions and 25 deletions
Showing only changes of commit 019a551cb6 - Show all commits

View File

@ -40,17 +40,17 @@ using OwningAssetCatalogMap = Map<CatalogID, std::unique_ptr<AssetCatalog>>;
* directory hierarchy). */ * directory hierarchy). */
class AssetCatalogService { class AssetCatalogService {
std::unique_ptr<AssetCatalogCollection> catalog_collection_; std::unique_ptr<AssetCatalogCollection> catalog_collection_;
/** /**
* Cached catalog tree storage. Lazy-created by #AssetCatalogService::catalog_tree(). * Cached catalog tree storage. Lazy-created by #AssetCatalogService::catalog_tree().
*/ */
std::unique_ptr<AssetCatalogTree> catalog_tree_; std::unique_ptr<AssetCatalogTree> catalog_tree_;
std::mutex catalog_tree_mutex_; std::mutex catalog_tree_mutex_;
CatalogFilePath asset_library_root_;
Vector<std::unique_ptr<AssetCatalogCollection>> undo_snapshots_; Vector<std::unique_ptr<AssetCatalogCollection>> undo_snapshots_;
Vector<std::unique_ptr<AssetCatalogCollection>> redo_snapshots_; Vector<std::unique_ptr<AssetCatalogCollection>> redo_snapshots_;
const CatalogFilePath asset_library_root_;
const bool is_read_only_ = false; const bool is_read_only_ = false;
public: public:
@ -59,9 +59,8 @@ class AssetCatalogService {
struct read_only_tag {}; struct read_only_tag {};
public: public:
AssetCatalogService(); explicit AssetCatalogService(const CatalogFilePath &asset_library_root = {});
explicit AssetCatalogService(read_only_tag); explicit AssetCatalogService(read_only_tag);
explicit AssetCatalogService(const CatalogFilePath &asset_library_root);
/** /**
* Set tag indicating that some catalog modifications are unsaved, which could * Set tag indicating that some catalog modifications are unsaved, which could

View File

@ -10,6 +10,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex>
#include "AS_asset_catalog.hh" #include "AS_asset_catalog.hh"
@ -69,7 +70,11 @@ class AssetLibrary {
std::unique_ptr<AssetStorage> asset_storage_; std::unique_ptr<AssetStorage> asset_storage_;
protected: protected:
/* Changing this pointer should be protected using #catalog_service_mutex_. Note that changes
* within the catalog service may still happen without the mutex being locked. They should be
* protected separately. */
std::unique_ptr<AssetCatalogService> catalog_service_; std::unique_ptr<AssetCatalogService> catalog_service_;
std::mutex catalog_service_mutex_;
std::optional<eAssetImportMethod> import_method_; std::optional<eAssetImportMethod> import_method_;
/** Assets owned by this library may be imported with a different method than set in /** Assets owned by this library may be imported with a different method than set in

View File

@ -33,8 +33,9 @@ namespace blender::asset_system {
const CatalogFilePath AssetCatalogService::DEFAULT_CATALOG_FILENAME = "blender_assets.cats.txt"; const CatalogFilePath AssetCatalogService::DEFAULT_CATALOG_FILENAME = "blender_assets.cats.txt";
AssetCatalogService::AssetCatalogService() AssetCatalogService::AssetCatalogService(const CatalogFilePath &asset_library_root)
: catalog_collection_(std::make_unique<AssetCatalogCollection>()) : catalog_collection_(std::make_unique<AssetCatalogCollection>()),
asset_library_root_(asset_library_root)
{ {
} }
@ -43,12 +44,6 @@ AssetCatalogService::AssetCatalogService(read_only_tag) : AssetCatalogService()
const_cast<bool &>(is_read_only_) = true; const_cast<bool &>(is_read_only_) = true;
} }
AssetCatalogService::AssetCatalogService(const CatalogFilePath &asset_library_root)
: AssetCatalogService()
{
asset_library_root_ = asset_library_root;
}
void AssetCatalogService::tag_has_unsaved_changes(AssetCatalog *edited_catalog) void AssetCatalogService::tag_has_unsaved_changes(AssetCatalog *edited_catalog)
{ {
BLI_assert(!is_read_only_); BLI_assert(!is_read_only_);
@ -372,8 +367,7 @@ void AssetCatalogService::load_single_file(const CatalogFilePath &catalog_defini
std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::parse_catalog_file( std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::parse_catalog_file(
const CatalogFilePath &catalog_definition_file_path) const CatalogFilePath &catalog_definition_file_path)
{ {
auto cdf = std::make_unique<AssetCatalogDefinitionFile>(); auto cdf = std::make_unique<AssetCatalogDefinitionFile>(catalog_definition_file_path);
cdf->file_path = catalog_definition_file_path;
/* TODO(Sybren): this might have to move to a higher level when supporting multiple CDFs. */ /* TODO(Sybren): this might have to move to a higher level when supporting multiple CDFs. */
Set<AssetCatalogPath> seen_paths; Set<AssetCatalogPath> seen_paths;
@ -556,8 +550,7 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::construct_cdf_in_memory( std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::construct_cdf_in_memory(
const CatalogFilePath &file_path) const const CatalogFilePath &file_path) const
{ {
auto cdf = std::make_unique<AssetCatalogDefinitionFile>(); auto cdf = std::make_unique<AssetCatalogDefinitionFile>(file_path);
cdf->file_path = file_path;
for (auto &catalog : catalog_collection_->catalogs_.values()) { for (auto &catalog : catalog_collection_->catalogs_.values()) {
cdf->add_new(catalog.get()); cdf->add_new(catalog.get());

View File

@ -151,6 +151,11 @@ std::unique_ptr<AssetCatalog> AssetCatalogDefinitionFile::parse_catalog_line(con
return std::make_unique<AssetCatalog>(catalog_id, catalog_path.cleanup(), simple_name); return std::make_unique<AssetCatalog>(catalog_id, catalog_path.cleanup(), simple_name);
} }
AssetCatalogDefinitionFile::AssetCatalogDefinitionFile(const CatalogFilePath &file_path)
: file_path(file_path)
{
}
bool AssetCatalogDefinitionFile::write_to_disk() const bool AssetCatalogDefinitionFile::write_to_disk() const
{ {
BLI_assert_msg(!this->file_path.empty(), "Writing to CDF requires its file path to be known"); BLI_assert_msg(!this->file_path.empty(), "Writing to CDF requires its file path to be known");

View File

@ -37,10 +37,10 @@ class AssetCatalogDefinitionFile {
const static std::string VERSION_MARKER; const static std::string VERSION_MARKER;
const static std::string HEADER; const static std::string HEADER;
CatalogFilePath file_path; const CatalogFilePath file_path;
public: public:
AssetCatalogDefinitionFile() = default; AssetCatalogDefinitionFile(const CatalogFilePath &file_path);
/** /**
* Write the catalog definitions to the same file they were read from. * Write the catalog definitions to the same file they were read from.

View File

@ -191,7 +191,8 @@ void AssetLibrary::load_catalogs()
{ {
auto catalog_service = std::make_unique<AssetCatalogService>(root_path()); auto catalog_service = std::make_unique<AssetCatalogService>(root_path());
catalog_service->load_from_disk(); catalog_service->load_from_disk();
this->catalog_service_ = std::move(catalog_service); std::lock_guard lock{catalog_service_mutex_};
catalog_service_ = std::move(catalog_service);
} }
AssetCatalogService &AssetLibrary::catalog_service() const AssetCatalogService &AssetLibrary::catalog_service() const

View File

@ -58,7 +58,8 @@ void AllAssetLibrary::rebuild_catalogs_from_nested(const bool reload_nested_cata
}, },
false); false);
this->catalog_service_ = std::move(new_catalog_service); std::lock_guard lock{catalog_service_mutex_};
catalog_service_ = std::move(new_catalog_service);
catalogs_dirty_ = false; catalogs_dirty_ = false;
} }

View File

@ -8,12 +8,14 @@
#pragma once #pragma once
#include <atomic>
#include "AS_asset_library.hh" #include "AS_asset_library.hh"
namespace blender::asset_system { namespace blender::asset_system {
class AllAssetLibrary : public AssetLibrary { class AllAssetLibrary : public AssetLibrary {
bool catalogs_dirty_ = true; std::atomic<bool> catalogs_dirty_ = true;
public: public:
AllAssetLibrary(); AllAssetLibrary();

View File

@ -1116,9 +1116,9 @@ class TestableAssetCatalogCollection : public AssetCatalogCollection {
{ {
return catalog_definition_file_.get(); return catalog_definition_file_.get();
} }
AssetCatalogDefinitionFile *allocate_catalog_definition_file() AssetCatalogDefinitionFile *allocate_catalog_definition_file(StringRef file_path)
{ {
catalog_definition_file_ = std::make_unique<AssetCatalogDefinitionFile>(); catalog_definition_file_ = std::make_unique<AssetCatalogDefinitionFile>(file_path);
return get_catalog_definition_file(); return get_catalog_definition_file();
} }
}; };
@ -1185,8 +1185,8 @@ TEST_F(AssetCatalogTest, cat_collection_deep_copy__nonempty_cdf)
catcoll.get_catalogs().add_new(cat2->catalog_id, std::move(cat2)); catcoll.get_catalogs().add_new(cat2->catalog_id, std::move(cat2));
catcoll.get_deleted_catalogs().add_new(cat3->catalog_id, std::move(cat3)); catcoll.get_deleted_catalogs().add_new(cat3->catalog_id, std::move(cat3));
AssetCatalogDefinitionFile *cdf = catcoll.allocate_catalog_definition_file(); AssetCatalogDefinitionFile *cdf = catcoll.allocate_catalog_definition_file(
cdf->file_path = "path/to/somewhere.cats.txt"; "path/to/somewhere.cats.txt");
cdf->add_new(cat1_ptr); cdf->add_new(cat1_ptr);
cdf->add_new(cat2_ptr); cdf->add_new(cat2_ptr);
cdf->add_new(cat3_ptr); cdf->add_new(cat3_ptr);