[Bf-blender-cvs] [b71eb3a105b] master: Asset System: Data-block asset metadata storage, reading and API

Julian Eisel noreply at git.blender.org
Tue Dec 15 17:04:34 CET 2020


Commit: b71eb3a105b8f7fb216a48082386215a6ea81cc4
Author: Julian Eisel
Date:   Fri Dec 11 18:15:25 2020 +0100
Branches: master
https://developer.blender.org/rBb71eb3a105b8f7fb216a48082386215a6ea81cc4

Asset System: Data-block asset metadata storage, reading and API

Asset metadata is what turns a regular data-block into an asset. It is a small
data-structure, but a key part of the technical design of the asset system.

The design foresees that asset data-blocks store an `ID.asset_data` pointer of
type `AssetMetaData`. This data **must not** have dependencies on other
data-blocks or data-block data, it must be an independent unit. That way we can
read asset-metadata from .blends without reading anything else from the file.
The Asset Browser will use this metadata (together with the data-block name,
preview and file path) to represent assets in the file list.

Includes:
* New `ID.asset_data` for asset metadata.
* Asset tags, description and custom properties.
* BKE code to manage asset meta-data and asset tags.
* Code to read asset data from files, without reading IDs.
* RNA for asset metadata (including tags)

Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1
project milestone on developer.blender.org.

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

Reviewed by: Bastien Montagne, Brecht Van Lommel

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

M	source/blender/CMakeLists.txt
A	source/blender/blenkernel/BKE_asset.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/asset.c
M	source/blender/blenkernel/intern/lib_id.c
M	source/blender/blenkernel/intern/lib_id_delete.c
M	source/blender/blenloader/BLO_readfile.h
M	source/blender/blenloader/intern/readblenentry.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/readfile.h
M	source/blender/makesdna/DNA_ID.h
A	source/blender/makesdna/DNA_asset_defaults.h
A	source/blender/makesdna/DNA_asset_types.h
M	source/blender/makesdna/intern/CMakeLists.txt
M	source/blender/makesdna/intern/dna_defaults.c
M	source/blender/makesdna/intern/makesdna.c
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/CMakeLists.txt
M	source/blender/makesrna/intern/makesrna.c
M	source/blender/makesrna/intern/rna_ID.c
A	source/blender/makesrna/intern/rna_asset.c
M	source/blender/makesrna/intern/rna_internal.h

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

diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index c38da14be96..efd30ba8509 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -23,6 +23,7 @@ set(SRC_DNA_INC
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_action_types.h
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_anim_types.h
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_armature_types.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_asset_types.h
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_boid_types.h
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_brush_enums.h
   ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_brush_types.h
diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
new file mode 100644
index 00000000000..edd49dd9851
--- /dev/null
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __BKE_ASSET_H__
+#define __BKE_ASSET_H__
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct BlendWriter;
+struct BlendDataReader;
+struct ID;
+struct PreviewImage;
+
+struct AssetMetaData *BKE_asset_metadata_create(void);
+void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
+
+struct AssetTagEnsureResult {
+  struct AssetTag *tag;
+  /* Set to false if a tag of this name was already present. */
+  bool is_new;
+};
+
+struct AssetTag *BKE_asset_metadata_tag_add(struct AssetMetaData *asset_data, const char *name);
+struct AssetTagEnsureResult BKE_asset_metadata_tag_ensure(struct AssetMetaData *asset_data,
+                                                          const char *name);
+void BKE_asset_metadata_tag_remove(struct AssetMetaData *asset_data, struct AssetTag *tag);
+
+void BKE_asset_metadata_write(struct BlendWriter *writer, struct AssetMetaData *asset_data);
+void BKE_asset_metadata_read(struct BlendDataReader *reader, struct AssetMetaData *asset_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_ASSET_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index d440d3e4d64..156d731d4a7 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -77,6 +77,7 @@ set(SRC
   intern/armature.c
   intern/armature_deform.c
   intern/armature_update.c
+  intern/asset.c
   intern/attribute.c
   intern/attribute_access.cc
   intern/autoexec.c
@@ -271,6 +272,7 @@ set(SRC
   BKE_attribute.h
   BKE_attribute_access.hh
   BKE_autoexec.h
+  BKE_asset.h
   BKE_blender.h
   BKE_blender_copybuffer.h
   BKE_blender_undo.h
diff --git a/source/blender/blenkernel/intern/asset.c b/source/blender/blenkernel/intern/asset.c
new file mode 100644
index 00000000000..92400d10fe5
--- /dev/null
+++ b/source/blender/blenkernel/intern/asset.c
@@ -0,0 +1,143 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_asset.h"
+#include "BKE_icons.h"
+#include "BKE_idprop.h"
+
+#include "DNA_ID.h"
+#include "DNA_asset_types.h"
+#include "DNA_defaults.h"
+
+#include "BLO_read_write.h"
+
+#include "MEM_guardedalloc.h"
+
+AssetMetaData *BKE_asset_metadata_create(void)
+{
+  AssetMetaData *asset_data = MEM_callocN(sizeof(*asset_data), __func__);
+  memcpy(asset_data, DNA_struct_default_get(AssetMetaData), sizeof(*asset_data));
+  return asset_data;
+}
+
+void BKE_asset_metadata_free(AssetMetaData **asset_data)
+{
+  if ((*asset_data)->properties) {
+    IDP_FreeProperty((*asset_data)->properties);
+  }
+  MEM_SAFE_FREE((*asset_data)->description);
+  BLI_freelistN(&(*asset_data)->tags);
+
+  MEM_SAFE_FREE(*asset_data);
+}
+
+static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
+{
+  AssetTag *tag = MEM_callocN(sizeof(*tag), __func__);
+  BLI_strncpy(tag->name, name, sizeof(tag->name));
+
+  BLI_addtail(&asset_data->tags, tag);
+  asset_data->tot_tags++;
+  /* Invariant! */
+  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
+
+  return tag;
+}
+
+AssetTag *BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name)
+{
+  AssetTag *tag = asset_metadata_tag_add(asset_data, name);
+  BLI_uniquename(&asset_data->tags, tag, name, '.', offsetof(AssetTag, name), sizeof(tag->name));
+  return tag;
+}
+
+/**
+ * Make sure there is a tag with name \a name, create one if needed.
+ */
+struct AssetTagEnsureResult BKE_asset_metadata_tag_ensure(AssetMetaData *asset_data,
+                                                          const char *name)
+{
+  struct AssetTagEnsureResult result = {.tag = NULL};
+  if (!name[0]) {
+    return result;
+  }
+
+  AssetTag *tag = BLI_findstring(&asset_data->tags, name, offsetof(AssetTag, name));
+
+  if (tag) {
+    result.tag = tag;
+    result.is_new = false;
+    return result;
+  }
+
+  tag = asset_metadata_tag_add(asset_data, name);
+
+  result.tag = tag;
+  result.is_new = true;
+  return result;
+}
+
+void BKE_asset_metadata_tag_remove(AssetMetaData *asset_data, AssetTag *tag)
+{
+  BLI_assert(BLI_findindex(&asset_data->tags, tag) >= 0);
+  BLI_freelinkN(&asset_data->tags, tag);
+  asset_data->tot_tags--;
+  /* Invariant! */
+  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
+}
+
+/* .blend file API -------------------------------------------- */
+
+void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
+{
+  BLO_write_struct(writer, AssetMetaData, asset_data);
+
+  if (asset_data->properties) {
+    IDP_BlendWrite(writer, asset_data->properties);
+  }
+
+  if (asset_data->description) {
+    BLO_write_string(writer, asset_data->description);
+  }
+  LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
+    BLO_write_struct(writer, AssetTag, tag);
+  }
+}
+
+void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
+{
+  /* asset_data itself has been read already. */
+
+  if (asset_data->properties) {
+    BLO_read_data_address(reader, &asset_data->properties);
+    IDP_BlendDataRead(reader, &asset_data->properties);
+  }
+
+  BLO_read_data_address(reader, &asset_data->description);
+  BLO_read_list(reader, &asset_data->tags);
+  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
+}
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 8113417b55f..61b5e6f85bb 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -56,6 +56,7 @@
 
 #include "BKE_anim_data.h"
 #include "BKE_armature.h"
+#include "BKE_asset.h"
 #include "BKE_bpath.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
@@ -2362,6 +2363,10 @@ void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
 
 void BKE_id_blend_write(BlendWriter *writer, ID *id)
 {
+  if (id->asset_data) {
+    BKE_asset_metadata_write(writer, id->asset_data);
+  }
+
   /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
   if (id->properties && !ELEM(GS(id->name), ID_WM)) {
     IDP_BlendWrite(writer, id->properties);
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index 1e45a3c1163..7199bd0f13c 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -31,6 +31,7 @@
 #include "BLI_listbase.h"
 
 #include "BKE_anim_data.h"
+#include "BKE_asset.h"
 #include "BKE_idprop.h"
 #include "BKE_idtype.h"
 #include "BKE_key.h"
@@ -64,6 +65,10 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
     id->override_library = NULL;
   }
 
+  if (id->asset_data) {
+    BKE_asset_metadata_free(&id->asset_data);
+  }
+
   BKE_animdata_free(id, do_id_user);
 }
 
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 0ab9a5e9e14..1d7c5d8a1d3 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -119,12 +119,20 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
 /** \name BLO Blend File Handle API
  * \{ */
 
+struct BLODataBlockInfo {
+  char name[64]; /* MAX_NAME */
+  struct AssetMetaData *asset_data;
+};
+
 BlendHandle *BLO_blendhandle_from_file(const char *filepath, struct ReportList *reports);
 BlendHandle *BLO_blendhandle_from_memory(const void *mem, int memsize);
 
 struct LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
                                                      int ofblocktype,
                                                      int *tot_names);
+struct LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
+                 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list