[Bf-blender-cvs] [eafc9cb4465] blender-projects-basics: Refactor BKE project interface & implementation

Julian Eisel noreply at git.blender.org
Tue Oct 18 15:26:22 CEST 2022


Commit: eafc9cb4465d4fe244d4008fce02112203429154
Author: Julian Eisel
Date:   Tue Oct 18 15:24:56 2022 +0200
Branches: blender-projects-basics
https://developer.blender.org/rBeafc9cb4465d4fe244d4008fce02112203429154

Refactor BKE project interface & implementation

Mostly this is about more cleanly separating between `BlenderProject`
and `ProjectSettings`. Overall this is a nice improvement I think, helps
readability of interfaces and implementation a lot.

===================================================================

M	source/blender/blenkernel/BKE_blender_project.h
M	source/blender/blenkernel/BKE_blender_project.hh
M	source/blender/blenkernel/intern/blender_project.cc
M	source/blender/blenkernel/intern/blender_project_settings.cc
M	source/blender/blenkernel/intern/blender_project_test.cc
M	source/blender/editors/project/project.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_blender_project.h b/source/blender/blenkernel/BKE_blender_project.h
index 3a0e0d54d74..647730d66b5 100644
--- a/source/blender/blenkernel/BKE_blender_project.h
+++ b/source/blender/blenkernel/BKE_blender_project.h
@@ -20,7 +20,7 @@ typedef struct BlenderProject BlenderProject;
 /** See #bke::ProjectSettings::create_settings_directory(). */
 bool BKE_project_create_settings_directory(const char *project_root_path) ATTR_NONNULL();
 /** See #bke::ProjectSettings::delete_settings_directory(). */
-bool BKE_project_delete_settings_directory(const BlenderProject *project) ATTR_NONNULL();
+bool BKE_project_delete_settings_directory(BlenderProject *project) ATTR_NONNULL();
 
 BlenderProject *BKE_project_active_get(void) ATTR_WARN_UNUSED_RESULT;
 /**
@@ -38,18 +38,6 @@ bool BKE_project_is_path_project_root(const char *path) ATTR_WARN_UNUSED_RESULT
  * referenced file/directory is a project root directory).
  */
 bool BKE_project_contains_path(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-/**
- * Attempt to load project based on the given path and return it. This should never become the
- * active project, which should be loaded with #BKE_project_active_load_from_path() instead
- * (because the active project uses unique_ptr without the guarded allocator, unlike this C-API
- * function). The returned project pointer is owning and needs freeing with #BKE_project_free().
- */
-BlenderProject *BKE_project_load_from_path(const char *path) ATTR_WARN_UNUSED_RESULT
-    ATTR_NONNULL();
-/**
- * Free a project allocated by #BKE_project_load_from_path() and null the pointer to it.
- */
-void BKE_project_free(BlenderProject **project) ATTR_NONNULL();
 
 /**
  * Attempt to load and activate a project based on the given path. If the path doesn't lead
diff --git a/source/blender/blenkernel/BKE_blender_project.hh b/source/blender/blenkernel/BKE_blender_project.hh
index 41531ee382c..bbf80303305 100644
--- a/source/blender/blenkernel/BKE_blender_project.hh
+++ b/source/blender/blenkernel/BKE_blender_project.hh
@@ -24,24 +24,67 @@ class ProjectSettings;
 struct CustomAssetLibraries;
 
 /**
- * The active project (if there is one) is stored in static memory here too, and can be queried
- * using #BlenderProject::get_active().
+ * Entry point / API for core Blender project management.
+ *
+ * Responsibilities:
+ * - Own and give access to the active project.
+ * - Manage the .blender_project/ directory.
+ * - Store and manage (including reading & writing) of the .blender_project/settings.json file. The
+ *   implementation of this can be found in the internal #ProjectSettings class.
+ * - Tag for unsaved changes as needed.
  */
 class BlenderProject {
   friend class ProjectSettings;
 
+  /* Path to the project root using native slashes plus a trailing slash. */
+  std::string root_path_;
   std::unique_ptr<ProjectSettings> settings_;
 
+ public:
+  inline static const StringRefNull SETTINGS_DIRNAME = ".blender_project";
+  inline static const StringRefNull SETTINGS_FILENAME = "settings.json";
+
  public:
   static auto get_active [[nodiscard]] () -> BlenderProject *;
-  static auto set_active_from_settings(std::unique_ptr<ProjectSettings> settings)
-      -> BlenderProject *;
+  static auto set_active(std::unique_ptr<BlenderProject> settings) -> BlenderProject *;
+
+  /**
+   * Read project settings from the given \a path, which may point to some directory or file inside
+   * of the project directory. Both Unix and Windows style slashes are allowed. Path is expected to
+   * be normalized.
+   *
+   * Attempt to read project data from the given \a project_path, which may be either a project
+   * root directory or the .blender_project directory, and load it into runtime data. Letting the
+   * returned #unique_pointer run out of scope cleanly destructs the runtime project data.
+   *
+   * \note Does NOT set the loaded project active.
+   *
+   * \return The loaded project or null on failure.
+   */
+  static auto load_from_path(StringRef project_path) -> std::unique_ptr<BlenderProject>;
+
+  /**
+   * Initializes a blender project by creating a .blender_project directory at the given \a
+   * project_root_path.
+   * Both Unix and Windows style slashes are allowed.
+   *
+   * \return True if the settings directory was created, or already existed. False on failure.
+   */
+  static auto create_settings_directory(StringRef project_root_path) -> bool;
+  /**
+   * Remove the .blender_project directory with all of its contents at the given \a
+   * project_root_path. If this is the path of the active project, it is marked as having changed
+   * but it is not unloaded. Runtime project data is still valid at this point.
+   *
+   * \return True on success.
+   */
+  static auto delete_settings_directory(StringRef project_root_path) -> bool;
 
   /**
    * Check if the directory given by \a path contains a .blender_project directory and should thus
    * be considered a project root directory.
    */
-  static bool path_is_project_root(StringRef path);
+  static auto path_is_project_root(StringRef path) -> bool;
 
   /**
    * Check if \a path points into a project and return the root directory path of that project (the
@@ -49,51 +92,60 @@ class BlenderProject {
    * the first project found, so if a project is nested inside another one, the nested project is
    * used.
    * Both Unix and Windows style slashes are allowed.
-   * \return the project root path or an empty path if not found.
+   *
+   * \return The project root path or an empty path if not found. The referenced string points into
+   *         the input \a path, so slashes are not converted in the returned value.
    */
   static auto project_root_path_find_from_path [[nodiscard]] (StringRef path) -> StringRef;
 
-  explicit BlenderProject(std::unique_ptr<ProjectSettings> settings);
+  /* --- Non-static member functions. --- */
 
-  auto get_settings [[nodiscard]] () const -> ProjectSettings &;
+  BlenderProject(StringRef project_root_path, std::unique_ptr<ProjectSettings> settings);
 
- private:
-  static std::unique_ptr<BlenderProject> &active_project_ptr();
-};
+  /**
+   * Version of the static #delete_settings_directory() that deletes the settings directory of this
+   * project. Always tags as having unsaved changes after successful deletion.
+   */
+  auto delete_settings_directory() -> bool;
 
-struct CustomAssetLibraries : NonCopyable {
-  ListBase asset_libraries = {nullptr, nullptr}; /* CustomAssetLibraryDefinition */
+  auto root_path [[nodiscard]] () const -> StringRefNull;
+  auto get_settings [[nodiscard]] () const -> ProjectSettings &;
 
-  CustomAssetLibraries() = default;
-  CustomAssetLibraries(ListBase asset_libraries);
-  CustomAssetLibraries(CustomAssetLibraries &&);
-  ~CustomAssetLibraries();
-  auto operator=(CustomAssetLibraries &&) -> CustomAssetLibraries &;
+ private:
+  static auto active_project_ptr() -> std::unique_ptr<BlenderProject> &;
+  /**
+   * Get the project root path from a path that is either already the project root, or the
+   * .blender_project directory. Returns the path with native slashes plus a trailing slash.
+   */
+  static auto project_path_to_native_project_root_path(StringRef project_path) -> std::string;
+  /**
+   * Get the .blender_project directory path from a project root path. Returns the path with native
+   * slashes plus a trailing slash. Assumes the path already ends with a native trailing slash.
+   */
+  static auto project_root_path_to_settings_path(StringRef project_root_path) -> std::string;
+  /**
+   * Returns the path with native slashes.
+   * Assumes the path already ends with a native trailing slash.
+   */
+  static auto project_root_path_to_settings_filepath(StringRef project_root_path) -> std::string;
 };
 
+/**
+ * Runtime representation of the project settings (`.blender_project/settings.json`) with IO
+ * functionality.
+ */
 class ProjectSettings {
-  /* Path to the project root using slashes in the OS native format. */
-  std::string project_root_path_;
   std::string project_name_;
-  CustomAssetLibraries asset_libraries_ = {};
+  std::unique_ptr<CustomAssetLibraries> asset_libraries_;
+
   bool has_unsaved_changes_ = false;
 
  public:
-  inline static const StringRefNull SETTINGS_DIRNAME = ".blender_project";
-  inline static const StringRefNull SETTINGS_FILENAME = "settings.json";
-
-  /**
-   * Initializes a blender project by creating a .blender_project directory at the given \a
-   * project_root_path.
-   * Both Unix and Windows style slashes are allowed.
-   * \return True if the settings directory was created, or already existed. False on failure.
-   */
-  static auto create_settings_directory(StringRef project_root_path) -> bool;
-
   /**
    * Read project settings from the given \a project_path, which may be either a project root
    * directory or the .blender_project directory.
    * Both Unix and Windows style slashes are allowed. Path is expected to be normalized.
+   *
    * \return The read project settings or null in case of failure.
    */
   static auto load_from_disk [[nodiscard]] (StringRef project_path)
@@ -102,27 +154,26 @@ class ProjectSettings {
    * Read project settings from the given \a path, which may point to some directory or file inside
    * of the project directory. Both Unix and Windows style slashes are allowed. Path is expected to
    * be normalized.
+   *
    * \return The read project settings or null in case of failure.
    */
   static auto load_from_path [[nodiscard]] (StringRef path) -> std::unique_ptr<ProjectSettings>;
+
+  /** Explicit constructor and destructor needed to manage the CustomAssetLibraries unique_ptr. */
+  ProjectSettings();
+  /* Implementation defaulted. */
+  ~ProjectSettings();
+
   /**
    * Write project settings to the given \a project_path, which may be either a project root
    * directory or the .blender_project directory. The .blender_project directory must exist.
    * Both Unix and Windows style slashes are allowed. Path is expected to be normalized.
-   * \return True on success. If the .blender_project directory doesn't exist, that's treated as
-   *         failure.
+   *
+   * \return True on

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list