Assets: Add License and Copyright meta-data #105318

Merged
Harley Acheson merged 3 commits from Harley/blender:AssetMeta into blender-v3.5-release 2023-03-07 18:22:53 +01:00
5 changed files with 165 additions and 2 deletions

View File

@ -745,6 +745,8 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
layout.prop(asset_file_handle.asset_data, "description")
layout.prop(asset_file_handle.asset_data, "license")
layout.prop(asset_file_handle.asset_data, "copyright")
layout.prop(asset_file_handle.asset_data, "author")

View File

@ -44,6 +44,8 @@ AssetMetaData::~AssetMetaData()
}
MEM_SAFE_FREE(author);
MEM_SAFE_FREE(description);
MEM_SAFE_FREE(copyright);
MEM_SAFE_FREE(license);
BLI_freelistN(&tags);
}
@ -161,13 +163,19 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
if (asset_data->properties) {
IDP_BlendWrite(writer, asset_data->properties);
}
if (asset_data->author) {
BLO_write_string(writer, asset_data->author);
}
if (asset_data->description) {
BLO_write_string(writer, asset_data->description);
}
if (asset_data->copyright) {
BLO_write_string(writer, asset_data->copyright);
}
if (asset_data->license) {
BLO_write_string(writer, asset_data->license);
}
LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
BLO_write_struct(writer, AssetTag, tag);
}
@ -185,6 +193,8 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
BLO_read_data_address(reader, &asset_data->author);
BLO_read_data_address(reader, &asset_data->description);
BLO_read_data_address(reader, &asset_data->copyright);
BLO_read_data_address(reader, &asset_data->license);
BLO_read_list(reader, &asset_data->tags);
BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
}

View File

@ -56,13 +56,16 @@ using namespace blender::bke::idprop;
* "catalog_name": "<catalog_name>",
* "description": "<description>",
* "author": "<author>",
* "copyright": "<copyright>",
* "license": "<license>",
* "tags": ["<tag>"],
* "properties": [..]
* }]
* }
* \endcode
*
* NOTE: entries, author, description, tags and properties are optional attributes.
* NOTE: entries, author, description, copyright, license, tags and properties are optional
* attributes.
*
* NOTE: File browser uses name and idcode separate. Inside the index they are joined together like
* #ID.name.
@ -75,6 +78,8 @@ constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_ID("catalog_id");
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_NAME("catalog_name");
constexpr StringRef ATTRIBUTE_ENTRIES_DESCRIPTION("description");
constexpr StringRef ATTRIBUTE_ENTRIES_AUTHOR("author");
constexpr StringRef ATTRIBUTE_ENTRIES_COPYRIGHT("copyright");
constexpr StringRef ATTRIBUTE_ENTRIES_LICENSE("license");
constexpr StringRef ATTRIBUTE_ENTRIES_TAGS("tags");
constexpr StringRef ATTRIBUTE_ENTRIES_PROPERTIES("properties");
@ -178,6 +183,26 @@ struct AssetEntryReader {
return lookup.lookup(ATTRIBUTE_ENTRIES_AUTHOR)->as_string_value()->value();
}
bool has_copyright() const
{
return lookup.contains(ATTRIBUTE_ENTRIES_COPYRIGHT);
}
StringRefNull get_copyright() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_COPYRIGHT)->as_string_value()->value();
}
bool has_license() const
{
return lookup.contains(ATTRIBUTE_ENTRIES_LICENSE);
}
StringRefNull get_license() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_LICENSE)->as_string_value()->value();
}
StringRefNull get_catalog_name() const
{
return lookup.lookup(ATTRIBUTE_ENTRIES_CATALOG_NAME)->as_string_value()->value();
@ -267,6 +292,16 @@ struct AssetEntryWriter {
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_AUTHOR, new StringValue(author)));
}
void add_copyright(const StringRefNull copyright)
{
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_COPYRIGHT, new StringValue(copyright)));
}
void add_license(const StringRefNull license)
{
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_LICENSE, new StringValue(license)));
}
void add_tags(const ListBase /* AssetTag */ *asset_tags)
{
ArrayValue *tags = new ArrayValue();
@ -305,6 +340,12 @@ static void init_value_from_file_indexer_entry(AssetEntryWriter &result,
if (asset_data.author != nullptr) {
result.add_author(asset_data.author);
}
if (asset_data.copyright != nullptr) {
result.add_copyright(asset_data.copyright);
}
if (asset_data.license != nullptr) {
result.add_license(asset_data.license);
}
if (!BLI_listbase_is_empty(&asset_data.tags)) {
result.add_tags(&asset_data.tags);
@ -372,6 +413,18 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry,
BLI_strncpy(author_c_str, author.c_str(), author.size() + 1);
asset_data->author = author_c_str;
}
if (entry.has_copyright()) {
const StringRefNull copyright = entry.get_copyright();
char *copyright_c_str = static_cast<char *>(MEM_mallocN(copyright.size() + 1, __func__));
BLI_strncpy(copyright_c_str, copyright.c_str(), copyright.size() + 1);
asset_data->copyright = copyright_c_str;
}
if (entry.has_license()) {
const StringRefNull license = entry.get_license();
char *license_c_str = static_cast<char *>(MEM_mallocN(license.size() + 1, __func__));
BLI_strncpy(license_c_str, license.c_str(), license.size() + 1);
asset_data->license = license_c_str;
}
const StringRefNull catalog_name = entry.get_catalog_name();
BLI_strncpy(asset_data->catalog_simple_name,

View File

@ -72,6 +72,12 @@ typedef struct AssetMetaData {
/** Optional description of this asset for display in the UI. Dynamic length. */
char *description;
/** Optional copyright of this asset for display in the UI. Dynamic length. */
char *copyright;
/** Optional license of this asset for display in the UI. Dynamic length. */
char *license;
/** 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. */

View File

@ -205,6 +205,74 @@ static void rna_AssetMetaData_description_set(PointerRNA *ptr, const char *value
}
}
static void rna_AssetMetaData_copyright_get(PointerRNA *ptr, char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->copyright) {
strcpy(value, asset_data->copyright);
}
else {
value[0] = '\0';
}
}
static int rna_AssetMetaData_copyright_length(PointerRNA *ptr)
{
AssetMetaData *asset_data = ptr->data;
return asset_data->copyright ? strlen(asset_data->copyright) : 0;
}
static void rna_AssetMetaData_copyright_set(PointerRNA *ptr, const char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->copyright) {
MEM_freeN(asset_data->copyright);
}
if (value[0]) {
asset_data->copyright = BLI_strdup(value);
}
else {
asset_data->copyright = NULL;
}
}
static void rna_AssetMetaData_license_get(PointerRNA *ptr, char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->license) {
strcpy(value, asset_data->license);
}
else {
value[0] = '\0';
}
}
static int rna_AssetMetaData_license_length(PointerRNA *ptr)
{
AssetMetaData *asset_data = ptr->data;
return asset_data->license ? strlen(asset_data->license) : 0;
}
static void rna_AssetMetaData_license_set(PointerRNA *ptr, const char *value)
{
AssetMetaData *asset_data = ptr->data;
if (asset_data->license) {
MEM_freeN(asset_data->license);
}
if (value[0]) {
asset_data->license = BLI_strdup(value);
}
else {
asset_data->license = NULL;
}
}
static void rna_AssetMetaData_active_tag_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
@ -397,6 +465,30 @@ static void rna_def_asset_data(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Description", "A description of the asset to be displayed for the user");
prop = RNA_def_property(srna, "copyright", PROP_STRING, PROP_NONE);
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
RNA_def_property_string_funcs(prop,
"rna_AssetMetaData_copyright_get",
"rna_AssetMetaData_copyright_length",
"rna_AssetMetaData_copyright_set");
RNA_def_property_ui_text(
Harley marked this conversation as resolved
Review

The description isn't adding much information, but I'm also not sure what to put in there. Maybe: "Copyright notice of the asset. An empty copyright notice does not mean there are no copyrights assigned. Contact the author if any clarification is needed."

The description isn't adding much information, but I'm also not sure what to put in there. Maybe: *"Copyright notice of the asset. An empty copyright notice does not mean there are no copyrights assigned. Contact the author if any clarification is needed."*
prop,
"Copyright",
"Copyright notice for this asset. An empty copyright notice does not necessarily indicate "
"that this is copyright-free. Contact the author if any clarification is needed");
prop = RNA_def_property(srna, "license", PROP_STRING, PROP_NONE);
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
RNA_def_property_string_funcs(prop,
Harley marked this conversation as resolved
Review

Similar thing here, suggest something like: "Name of the license the asset is distributed under. An empty license name does not mean there are no licensing terms. Contact the author if any clarification is needed."

Similar thing here, suggest something like: *"Name of the license the asset is distributed under. An empty license name does not mean there are no licensing terms. Contact the author if any clarification is needed."*
"rna_AssetMetaData_license_get",
"rna_AssetMetaData_license_length",
"rna_AssetMetaData_license_set");
RNA_def_property_ui_text(prop,
"License",
"The type of license this asset is distributed under. An empty license "
"name does not necessarily indicate that this is free of licensing "
Harley marked this conversation as resolved
Review

Maybe "... that this is free of licensing terms" sounds a bit better? You decide :)

Maybe "... that this is free of licensing terms" sounds a bit better? You decide :)
"terms. Contact the author if any clarification is needed");
prop = RNA_def_property(srna, "tags", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "AssetTag");
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");