Merge branch 'blender-v5.0-release'

This commit is contained in:
Lukas Stockner
2025-10-16 15:39:28 +02:00
9 changed files with 71 additions and 18 deletions

View File

@@ -71,7 +71,7 @@ class AssetCatalogService {
*
* This "dirty" state is tracked per catalog, so that it's possible to gracefully load changes
* from disk. Any catalog with unsaved changes will not be overwritten by on-disk changes. */
void tag_has_unsaved_changes(AssetCatalog *edited_catalog);
void tag_has_unsaved_changes(AssetCatalog *edited_catalog = nullptr);
bool has_unsaved_changes() const;
/**
@@ -159,8 +159,15 @@ class AssetCatalogService {
*/
AssetCatalogFilter create_catalog_filter(CatalogID active_catalog_id) const;
/** Create a catalog with some sensible auto-generated catalog ID.
* The catalog will be saved to the default catalog file. */
/**
* Create a catalog with some sensible auto-generated catalog ID.
* The catalog will be saved to the default catalog file.
*
* NOTE: this does NOT mark the catalog service itself as 'has changes'. The caller is
* responsible for that.
*
* \see #tag_has_unsaved_changes()
*/
AssetCatalog *create_catalog(const AssetCatalogPath &catalog_path);
/**
@@ -228,6 +235,11 @@ class AssetCatalogService {
* will be removed from a CDF when saved to disk.
*
* This is a lower-level function than #prune_catalogs_by_path.
*
* NOTE: this does NOT mark the catalog service itself as 'has changes'. The caller is
* responsible for that.
*
* \see #tag_has_unsaved_changes()
*/
void delete_catalog_by_id_soft(CatalogID catalog_id);

View File

@@ -482,9 +482,19 @@ bool AssetCatalogService::write_to_disk_ex(const CatalogFilePath &blend_file_pat
{
/* TODO(Sybren): expand to support multiple CDFs. */
/* - Already loaded a CDF from disk? -> Always write to that file. */
/* - Already loaded a CDF from disk? -> Only write to that file when there were actual changes.
* This prevents touching the file, which can cause issues when multiple Blender instances are
* accessing the same file (like on shared storage, Syncthing, etc.). See #111576.
*/
if (catalog_collection_->catalog_definition_file_) {
/* Always sync with what's on disk. */
this->reload_catalogs();
if (!this->has_unsaved_changes() &&
catalog_collection_->catalog_definition_file_->exists_on_disk())
{
return true;
}
return catalog_collection_->catalog_definition_file_->write_to_disk();
}

View File

@@ -185,6 +185,11 @@ bool AssetCatalogDefinitionFile::write_to_disk(const CatalogFilePath &dest_file_
return true;
}
bool AssetCatalogDefinitionFile::exists_on_disk() const
{
return BLI_exists(this->file_path.c_str());
}
bool AssetCatalogDefinitionFile::write_to_disk_unsafe(const CatalogFilePath &dest_file_path) const
{
char directory[PATH_MAX];

View File

@@ -55,6 +55,11 @@ class AssetCatalogDefinitionFile {
*/
bool write_to_disk(const CatalogFilePath &dest_file_path) const;
/**
* Returns whether this file exists on disk.
*/
bool exists_on_disk() const;
bool contains(CatalogID catalog_id) const;
/** Add a catalog, overwriting the one with the same catalog ID. */
void add_overwrite(AssetCatalog *catalog);

View File

@@ -341,6 +341,7 @@ TEST_F(AssetCatalogTest, on_blendfile_save__with_existing_cdf)
TestableAssetCatalogService service(cdf_filename);
service.load_from_disk();
const AssetCatalog *cat = service.create_catalog("some/catalog/path");
service.tag_has_unsaved_changes();
const CatalogFilePath blendfilename = top_level_dir + "subdir" + SEP_STR + "some_file.blend";
ASSERT_TRUE(service.write_to_disk(blendfilename));
@@ -458,6 +459,10 @@ TEST_F(AssetCatalogTest, create_first_catalog_from_scratch)
/* Creating a new catalog should not save anything to disk yet. */
EXPECT_FALSE(BLI_exists(temp_lib_root.c_str()));
/* Creating a new catalog should not mark the asset service as 'dirty'; that's
* the caller's responsibility. */
EXPECT_FALSE(service.has_unsaved_changes());
/* Writing to disk should create the directory + the default file. */
service.write_to_disk(temp_lib_root + "phony.blend");
EXPECT_TRUE(BLI_is_dir(temp_lib_root.c_str()));
@@ -498,6 +503,7 @@ TEST_F(AssetCatalogTest, create_catalog_after_loading_file)
/* This should create a new catalog but not write to disk. */
const AssetCatalog *new_catalog = service.create_catalog("new/catalog");
const bUUID new_catalog_id = new_catalog->catalog_id;
service.tag_has_unsaved_changes();
/* Reload the on-disk catalog file. */
TestableAssetCatalogService loaded_service(temp_lib_root);
@@ -887,6 +893,7 @@ TEST_F(AssetCatalogTest, backups)
TestableAssetCatalogService service(cdf_dir);
service.load_from_disk();
service.delete_catalog_by_id_soft(UUID_POSES_ELLIE);
service.tag_has_unsaved_changes();
service.write_to_disk(cdf_dir + "phony.blend");
const CatalogFilePath backup_path = writable_cdf_file + "~";

View File

@@ -275,7 +275,9 @@ static void print_error(const char *message)
{
char buffer[256];
size_t length = BLI_string_join(buffer, sizeof(buffer), "BLI_mmap: ", message, "\n");
write(STDERR_FILENO, buffer, length);
if (write(STDERR_FILENO, buffer, length) < 0) {
/* If writing to stderr fails, there is nowhere to write an error about that. */
}
}
static bool try_map_zeros(BLI_mmap_file *file)