[Bf-blender-cvs] [e5e8db73df8] master: Refactor BKE_bpath module.

Bastien Montagne noreply at git.blender.org
Mon Nov 29 14:23:16 CET 2021


Commit: e5e8db73df86ee04260c5f2bd2c61dfa8eb7943f
Author: Bastien Montagne
Date:   Mon Nov 29 14:20:58 2021 +0100
Branches: master
https://developer.blender.org/rBe5e8db73df86ee04260c5f2bd2c61dfa8eb7943f

Refactor BKE_bpath module.

The main goal of this refactor is to make BPath module use `IDTypeInfo`,
and move each ID-specific part of the `foreach_path` looper into their
own IDTypeInfo struct, using a new `foreach_path` callback.

Additionally, following improvements/cleanups are included:
* Attempt to get better, more consistent namings.
** In particular, move from `path_visitor` to more standard `foreach_path`.
* Update and extend documentation.
** API doc was moved to header, according to recent discussions on this
   topic.
* Remove `BKE_bpath_relocate_visitor` from API, this is specific
  callback that belongs in `lib_id.c` user code.

NOTE: This commit is expected to be 100% non-behavioral-change. This
implies that several potential further changes were only noted as
comments (like using a more generic solution for
`lib_id_library_local_paths`, addressing inconsistencies like path of
packed libraries always being skipped, regardless of the
`BKE_BPATH_FOREACH_PATH_SKIP_PACKED` `eBPathForeachFlag` flag value,
etc.).

NOTE: basic unittests were added to master already in
rBdcc500e5a265093bc9cc.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D13381

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

M	source/blender/blenkernel/BKE_bpath.h
M	source/blender/blenkernel/BKE_idtype.h
M	source/blender/blenkernel/intern/action.c
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenkernel/intern/blendfile.c
M	source/blender/blenkernel/intern/bpath.c
M	source/blender/blenkernel/intern/bpath_test.cc
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/cachefile.c
M	source/blender/blenkernel/intern/camera.c
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/image.c
M	source/blender/blenkernel/intern/ipo.c
M	source/blender/blenkernel/intern/key.c
M	source/blender/blenkernel/intern/lattice.c
M	source/blender/blenkernel/intern/lib_id.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/light.c
M	source/blender/blenkernel/intern/lightprobe.c
M	source/blender/blenkernel/intern/linestyle.c
M	source/blender/blenkernel/intern/mask.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/mball.c
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/movieclip.c
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/object.cc
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/pointcloud.cc
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenkernel/intern/screen.c
M	source/blender/blenkernel/intern/simulation.cc
M	source/blender/blenkernel/intern/sound.c
M	source/blender/blenkernel/intern/speaker.c
M	source/blender/blenkernel/intern/text.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/blenkernel/intern/vfont.c
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/blenkernel/intern/world.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/asset/intern/asset_ops.cc
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/python/intern/bpy.c
M	source/blender/windowmanager/intern/wm.c

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

diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h
index 3ec5409ca7f..984c7f609f6 100644
--- a/source/blender/blenkernel/BKE_bpath.h
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -16,10 +16,14 @@
 
 /** \file
  * \ingroup bke
- * \attention Based on ghash, difference is ghash is not a fixed size,
- *   so for BPath we don't need to malloc
+ *
+ * \warning All paths manipulated by this API are assumed to be either constant char buffers of
+ * `FILE_MAX` size, or allocated char buffers not bigger than `FILE_MAX`.
  */
 
+/* TODO: Make this module handle a bit more safely string length, instead of assuming buffers are
+ * FILE_MAX len etc. */
+
 #pragma once
 
 #ifdef __cplusplus
@@ -31,66 +35,175 @@ struct ListBase;
 struct Main;
 struct ReportList;
 
-/* Function that does something with an ID's file path. Should return 1 if the
- * path has changed, and in that case, should write the result to pathOut. */
-typedef bool (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src);
-/* Executes 'visit' for each path associated with 'id'. */
-void BKE_bpath_traverse_id(struct Main *bmain,
-                           struct ID *id,
-                           BPathVisitor visit_cb,
-                           const int flag,
-                           void *bpath_user_data);
-void BKE_bpath_traverse_id_list(struct Main *bmain,
-                                struct ListBase *lb,
-                                BPathVisitor visit_cb,
-                                const int flag,
-                                void *bpath_user_data);
-void BKE_bpath_traverse_main(struct Main *bmain,
-                             BPathVisitor visit_cb,
-                             const int flag,
-                             void *bpath_user_data);
-bool BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
-
-/* Functions for temp backup/restore of paths, path count must NOT change */
-void *BKE_bpath_list_backup(struct Main *bmain, const int flag);
-void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
-void BKE_bpath_list_free(void *ls_handle);
-
-enum {
-  /* convert paths to absolute */
-  BKE_BPATH_TRAVERSE_ABS = (1 << 0),
-  /* skip library paths */
-  BKE_BPATH_TRAVERSE_SKIP_LIBRARY = (1 << 1),
-  /* skip packed data */
-  BKE_BPATH_TRAVERSE_SKIP_PACKED = (1 << 2),
-  /* skip paths where a single dir is used with an array of files, eg.
-   * sequence strip images and pointcache. in this case only use the first
-   * file, this is needed for directory manipulation functions which might
-   * otherwise modify the same directory multiple times */
-  BKE_BPATH_TRAVERSE_SKIP_MULTIFILE = (1 << 3),
-  /* reload data (when the path is edited) */
-  BKE_BPATH_TRAVERSE_RELOAD_EDITED = (1 << 4),
-};
-
-/* high level funcs */
-
-/* creates a text file with missing files if there are any */
+/** \name Core `foreach_path` API.
+ * \{ */
+
+typedef enum eBPathForeachFlag {
+  /** Flags controlling the behavior of the generic BPath API. */
+
+  /** Ensures the `absolute_base_path` member of #BPathForeachPathData is initialized properly with
+   * the path of the current .blend file. This can be used by the callbacks to convert relative
+   * paths to absolute ones. */
+  BKE_BPATH_FOREACH_PATH_ABSOLUTE = (1 << 0),
+  /** Skip paths of linked IDs. */
+  BKE_BPATH_FOREACH_PATH_SKIP_LINKED = (1 << 1),
+  /** Skip paths when their matching data is packed. */
+  BKE_BPATH_FOREACH_PATH_SKIP_PACKED = (1 << 2),
+
+  /** Flags not affecting the generic BPath API. Those may be used by specific IDTypeInfo
+   * `foreach_path` implementations and/or callbacks to implement specific behaviors. */
+
+  /** Skip paths where a single dir is used with an array of files, eg. sequence strip images or
+   * pointcaches. In this case only use the first file path is processed.
+   *
+   * This is needed for directory manipulation callbacks which might otherwise modify the same
+   * directory multiple times. */
+  BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE = (1 << 8),
+  /** Reload data (when the path is edited).
+   *  \note Ony used by Image IDType currently. */
+  BKE_BPATH_FOREACH_PATH_RELOAD_EDITED = (1 << 9),
+} eBPathForeachFlag;
+
+struct BPathForeachPathData;
+
+/** Callback used to iterate over an ID's file paths.
+ *
+ * \note `path`s parameters should be considered as having a maximal `FILE_MAX` string length.
+ *
+ * \return `true` if the path has been changed, and in that case, result should be written into
+ * `r_path_dst`. */
+typedef bool (*BPathForeachPathFunctionCallback)(struct BPathForeachPathData *bpath_data,
+                                                 char *r_path_dst,
+                                                 const char *path_src);
+
+/** Storage for common data needed accross the BPath 'foreach_path' code. */
+typedef struct BPathForeachPathData {
+  struct Main *bmain;
+
+  BPathForeachPathFunctionCallback callback_function;
+  eBPathForeachFlag flag;
+
+  void *user_data;
+
+  /* 'Private' data, caller don't need to set those. */
+
+  /** The root to use as base for relative paths. Only set if `BKE_BPATH_FOREACH_PATH_ABSOLUTE`
+   * flag is set, NULL otherwise. */
+  const char *absolute_base_path;
+} BPathForeachPathData;
+
+/** Run `bpath_data.callback_function` on all paths contained in `id`. */
+void BKE_bpath_foreach_path_id(BPathForeachPathData *bpath_data, struct ID *id);
+
+/** Run `bpath_data.callback_function` on all paths of all IDs in `bmain`. */
+void BKE_bpath_foreach_path_main(BPathForeachPathData *bpath_data);
+
+/** \} */
+
+/** \name Helpers to handle common cases from `IDTypeInfo`'s `foreach_path` functions.
+ * \{ */
+
+/* TODO: Investigate using macros around those calls to check a bit better about actual
+ * strings/buffers length (e,g, with static asserts). */
+
+/**
+ * Run the callback on a path, replacing the content of the string as needed.
+ *
+ * \param path: A fixed, FILE_MAX-sized char buffer.
+ *
+ * \return true is \a path was modified, false otherwise.
+ */
+bool BKE_bpath_foreach_path_fixed_process(struct BPathForeachPathData *bpath_data, char *path);
+
+/**
+ * Run the callback on a (directory + file) path, replacing the content of the two strings as
+ * needed.
+ *
+ * \param path_dir: A fixed, FILE_MAXDIR-sized char buffer.
+ * \param path_file: A fixed, FILE_MAXFILE-sized char buffer.
+ *
+ * \return true is \a path_dir and/or \a path_file were modified, false otherwise.
+ */
+bool BKE_bpath_foreach_path_dirfile_fixed_process(struct BPathForeachPathData *bpath_data,
+                                                  char *path_dir,
+                                                  char *path_file);
+
+/**
+ * Run the callback on a path, replacing the content of the string as needed.
+ *
+ * \param path: A pointer to a MEM-allocated string. If modified, it will be freed and replaced by
+ * a new allocated string.
+ * \note path is expected to be FILE_MAX size or smaller.
+ *
+ * \return true is \a path was modified and re-allocated, false otherwise.
+ */
+bool BKE_bpath_foreach_path_allocated_process(struct BPathForeachPathData *bpath_data,
+                                              char **path);
+
+/** \} */
+
+/** \name High level features.
+ * \{ */
+
+/** Check for missing files. */
 void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
+
+/** Recursively search into given search directory, for all file paths of all IDs in given \a
+ * bmain, and replace existing paths as needed.
+ *
+ * \note The search will happen into the whole search directory tree recursively (with a limit of
+ * MAX_DIR_RECURSE), if several files are found matching a searched filename, the biggest one will
+ * be used. This is so that things like thumbnails don't get selected instead of the actual image
+ * e.g.
+ *
+ * \param searchpath: The root directory in which the new filepaths should be searched for.
+ * \param find_all: If `true`, also search for files which current path is still valid, if `false`
+ *                  skip those still valid paths.
+ * */
 void BKE_bpath_missing_files_find(struct Main *bmain,
                                   const char *searchpath,
                                   struct ReportList *reports,
                                   const bool find_all);
+
+/** Rebase all relative file paths in given \a bmain from \a basedir_src to \a basedir_dst. */
 void BKE_bpath_relative_rebase(struct Main *bmain,
                                const char *basedir_src,
                                const char *basedir_dst,
                                struct ReportList *reports);
+
+/** Make all absolute file paths in given \a bmain relative to given \a basedir. */
 void BKE_bpath_relative_convert(struct Main *bmain,
                                 const char *basedir,
                                 struct ReportList *reports);
+
+/** Make all relative file paths in given \a bmain absolute, using given \a basedir as root. */
 void BKE_bpath_absolute_convert(struct Main *bmain,
                                 const char *basedir,
                                 struct ReportList *reports);
 
+/** Temp backup of paths from all IDs in given \a bmain.
+ *
+ *  \return An opaque handle to pass to #BKE_bpath_list_restore and #BKE_bpath_list_free.
+ */
+void *BKE_bpath_list_backup(struct Main *bmain, const eBPathForeachFlag flag);
+
+/** Restore the temp backup of paths from \a path_list_handle into all IDs in given \a bmain.
+ *
+ * \note This function assumes that the data in given Main did not change (no
+ * addition/deletion/re-ordering of IDs, or their file paths) since the call to
+ * #BKE_bpath_list_backup that generated the given \a path_list_handle. */
+void BKE_bpath_list_restore(struct Main *bmain,
+                            const eBPathForeachFlag flag,
+                            void *path_list_handle);
+
+/** Free the temp backup of paths in \a path_list_handle.
+ *
+ * \note This function assumes that the path list has already been restored with a call to
+ * #BKE_bpath_list_restore, and is therefore empty. */
+void BKE_bpath_list_free(void *path_list

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list