[Bf-blender-cvs] [243a59ba6da] asset-metadata: Add custom tag support to assets

Julian Eisel noreply at git.blender.org
Wed Jul 8 21:41:40 CEST 2020


Commit: 243a59ba6da493f3390ffbaaa52074b8995266f2
Author: Julian Eisel
Date:   Wed Jul 8 21:37:39 2020 +0200
Branches: asset-metadata
https://developer.blender.org/rB243a59ba6da493f3390ffbaaa52074b8995266f2

Add custom tag support to assets

Tags are basically a list of strings. We could optimize these in future if
needed. We could also easily add colors or icons for individual tags (e.g. like
on developer.blender.org).

Note that there's no UI for this yet. Functionality is available via Python
though.

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

M	source/blender/blenkernel/BKE_asset.h
M	source/blender/blenkernel/intern/asset.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_asset_types.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_asset.c

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

diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index 670325b9bb3..ce17acd7006 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -21,10 +21,24 @@
  * \ingroup bke
  */
 
+#include "BLI_utildefines.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct Asset;
+struct CustomTag;
+
+struct CustomTagEnsureResult {
+  struct CustomTag *tag;
+  /* Set to false if a tag of this name was already present. */
+  bool is_new;
+};
+
+struct CustomTagEnsureResult BKE_asset_tag_ensure(struct Asset *asset, const char *name);
+void BKE_asset_tag_remove(struct Asset *asset, struct CustomTag *tag);
+
 struct AssetData *BKE_asset_data_create(void);
 void BKE_asset_data_free(struct AssetData *asset_data);
 
diff --git a/source/blender/blenkernel/intern/asset.c b/source/blender/blenkernel/intern/asset.c
index b243b8a50e6..4edf35a686c 100644
--- a/source/blender/blenkernel/intern/asset.c
+++ b/source/blender/blenkernel/intern/asset.c
@@ -20,6 +20,8 @@
 
 #include <string.h>
 
+#include "BLI_listbase.h"
+#include "BLI_string.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_asset.h"
@@ -51,6 +53,7 @@ static void asset_free_data(ID *id)
   BKE_previewimg_free(&asset->preview);
 
   MEM_SAFE_FREE(asset->description);
+  BLI_freelistN(&asset->tags);
 }
 
 static void asset_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -77,6 +80,36 @@ IDTypeInfo IDType_ID_AST = {
     /* foreach_id */ asset_foreach_id,
 };
 
+struct CustomTagEnsureResult BKE_asset_tag_ensure(Asset *asset, const char *name)
+{
+  struct CustomTagEnsureResult result = {.tag = NULL};
+  if (!name[0]) {
+    return result;
+  }
+
+  CustomTag *tag = BLI_findstring(&asset->tags, name, offsetof(CustomTag, name));
+
+  if (tag) {
+    result.tag = tag;
+    result.is_new = false;
+    return result;
+  }
+
+  tag = MEM_mallocN(sizeof(*tag), __func__);
+  BLI_strncpy(tag->name, name, sizeof(tag->name));
+
+  BLI_addtail(&asset->tags, tag);
+
+  result.tag = tag;
+  result.is_new = true;
+  return result;
+}
+
+void BKE_asset_tag_remove(Asset *asset, CustomTag *tag)
+{
+  BLI_freelinkN(&asset->tags, tag);
+}
+
 AssetData *BKE_asset_data_create(void)
 {
   return MEM_callocN(sizeof(AssetData), __func__);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3272e426fa6..1d5b0fd3bff 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8077,8 +8077,10 @@ static void direct_link_asset(BlendDataReader *reader, Asset *asset)
 {
   id_fake_user_set(&asset->id);
 
+  /* Meta-data */
   asset->preview = direct_link_preview_image(reader, asset->preview);
   BLO_read_data_address(reader, &asset->description);
+  BLO_read_list(reader, &asset->tags);
 }
 
 static void lib_link_asset(BlendLibReader *reader, Asset *asset)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 994d2f87fac..a619c2a83ae 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3868,12 +3868,17 @@ static void write_asset(BlendWriter *writer, Asset *asset, const void *id_addres
     BLO_write_id_struct(writer, Asset, id_address, &asset->id);
     write_iddata(writer, &asset->id);
 
+    /* Meta-data */
     write_previews(writer, asset->preview);
     if (asset->description) {
       BLO_write_string(writer, asset->description);
     }
+    LISTBASE_FOREACH (CustomTag *, tag, &asset->tags) {
+      BLO_write_struct(writer, CustomTag, tag);
+    }
   }
 }
+
 /* Keep it last of write_foodata functions. */
 static void write_libraries(WriteData *wd, Main *main)
 {
diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h
index bf5e5276cc4..f49108d035c 100644
--- a/source/blender/makesdna/DNA_asset_types.h
+++ b/source/blender/makesdna/DNA_asset_types.h
@@ -30,11 +30,25 @@ typedef struct Asset {
   struct PreviewImage *preview;
   /** Optional description of this asset for display in the UI. Dynamic length. */
   char *description;
+  /** User defined tags for this asset. The asset manager uses these for filtering, but how they
+   * function exactly (e.g. how they are registered to provide a list of searchable available tags)
+   * is up to the asset-engine. */
+  ListBase tags; /* CustomTag */
 
   /** The ID this asset was created for. */
   ID *referenced_id;
 } Asset;
 
+/**
+ * \brief User defined tag.
+ * Currently only used by assets, could be used more often at some point.
+ * Maybe add a custom icon and color to these in future?
+ */
+typedef struct CustomTag {
+  struct CustomTag *next, *prev;
+  char name[64]; /* MAX_NAME */
+} CustomTag;
+
 /* TODO unused, keeping in case it's useful later. */
 typedef struct AssetData {
   int dummy;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 1e7033e2a13..6413264caf3 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -206,6 +206,7 @@ extern StructRNA RNA_CurveModifier;
 extern StructRNA RNA_CurvePoint;
 extern StructRNA RNA_CurveProfile;
 extern StructRNA RNA_CurveProfilePoint;
+extern StructRNA RNA_CustomTag;
 extern StructRNA RNA_DampedTrackConstraint;
 extern StructRNA RNA_DataTransferModifier;
 extern StructRNA RNA_DecimateModifier;
diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c
index cad608d096d..5542e0d9bac 100644
--- a/source/blender/makesrna/intern/rna_asset.c
+++ b/source/blender/makesrna/intern/rna_asset.c
@@ -29,6 +29,39 @@
 
 #ifdef RNA_RUNTIME
 
+#  include "BKE_asset.h"
+
+#  include "RNA_access.h"
+
+static CustomTag *rna_Asset_tag_new(Asset *asset, ReportList *reports, const char *name)
+{
+  struct CustomTagEnsureResult result = BKE_asset_tag_ensure(asset, name);
+
+  if (!result.is_new) {
+    BKE_reportf(reports,
+                RPT_WARNING,
+                "Tag '%s' already present in asset '%s'",
+                result.tag->name,
+                asset->id.name + 2);
+    /* Report, but still return valid item. */
+  }
+
+  return result.tag;
+}
+
+static void rna_Asset_tag_remove(Asset *asset, ReportList *reports, PointerRNA *tag_ptr)
+{
+  CustomTag *tag = tag_ptr->data;
+  if (BLI_findindex(&asset->tags, tag) == -1) {
+    BKE_reportf(
+        reports, RPT_ERROR, "Tag '%s' not found in asset '%s'", tag->name, asset->id.name + 2);
+    return;
+  }
+
+  BKE_asset_tag_remove(asset, tag);
+  RNA_POINTER_INVALIDATE(tag_ptr);
+}
+
 static void rna_Asset_description_get(PointerRNA *ptr, char *value)
 {
   Asset *asset = ptr->data;
@@ -65,6 +98,51 @@ static void rna_Asset_description_set(PointerRNA *ptr, const char *value)
 
 #else
 
+static void rna_def_custom_tag(BlenderRNA *brna)
+{
+  StructRNA *srna;
+  PropertyRNA *prop;
+
+  srna = RNA_def_struct(brna, "CustomTag", NULL);
+  RNA_def_struct_ui_text(srna, "Custom Tag", "User defined tag (name token)");
+
+  prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+  RNA_def_property_string_maxlength(prop, MAX_NAME);
+  RNA_def_property_ui_text(prop, "Name", "The identifier that makes up this tag");
+  RNA_def_struct_name_property(srna, prop);
+}
+
+static void rna_def_asset_custom_tags_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+  StructRNA *srna;
+
+  FunctionRNA *func;
+  PropertyRNA *parm;
+
+  RNA_def_property_srna(cprop, "CustomTags");
+  srna = RNA_def_struct(brna, "CustomTags", NULL);
+  RNA_def_struct_sdna(srna, "Asset");
+  RNA_def_struct_ui_text(srna, "Asset Tags", "Collection of custom asset tags");
+
+  /* Tag collection */
+  func = RNA_def_function(srna, "new", "rna_Asset_tag_new");
+  RNA_def_function_ui_description(func, "Add a new tag to this asset");
+  RNA_def_function_flag(func, FUNC_USE_REPORTS);
+  parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+  /* return type */
+  parm = RNA_def_pointer(func, "tag", "CustomTag", "", "New tag");
+  RNA_def_function_return(func, parm);
+
+  func = RNA_def_function(srna, "remove", "rna_Asset_tag_remove");
+  RNA_def_function_ui_description(func, "Remove an existing tag from this asset");
+  RNA_def_function_flag(func, FUNC_USE_REPORTS);
+  /* tag to remove */
+  parm = RNA_def_pointer(func, "tag", "CustomTag", "", "Removed tag");
+  RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+  RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
+}
+
 static void rna_def_asset(BlenderRNA *brna)
 {
   StructRNA *srna;
@@ -81,11 +159,25 @@ static void rna_def_asset(BlenderRNA *brna)
                                 "rna_Asset_description_set");
   RNA_def_property_ui_text(
       prop, "Description", "A description of the asset to be displayed for the user");
+
+  prop = RNA_def_property(srna, "tags", PROP_COLLECTION, PROP_NONE);
+  RNA_def_property_struct_type(prop, "CustomTag");
+  RNA_def_property_flag(prop, PROP_EDITABLE);
+  RNA_def_property_ui_text(prop,
+                           "Tags",
+                           "Custom tags (name tokens) for the asset, used for filtering and "
+                           "general asset management");
+  rna_def_asset_custom_tags_api(brna, prop);
 }
 
 void RNA_def_asset(BlenderRNA *brna)
 {
+  RNA_define_animate_sdna(false);
+
+  rna_def_custom_tag(brna);
   rna_def_asset(brna);
+
+  RNA_define_animate_sdna(true);
 }
 
 #endif



More information about the Bf-blender-cvs mailing list