[Bf-blender-cvs] [9e87069c3ec] tmp-static-override-insertion: Static override: initial work for generating 'insertion' in collections.
Bastien Montagne
noreply at git.blender.org
Wed May 2 11:38:15 CEST 2018
Commit: 9e87069c3ec4c4327f0d2e8c2c450436cd7866a0
Author: Bastien Montagne
Date: Tue May 1 15:24:17 2018 +0200
Branches: tmp-static-override-insertion
https://developer.blender.org/rB9e87069c3ec4c4327f0d2e8c2c450436cd7866a0
Static override: initial work for generating 'insertion' in collections.
Does not yet support applying those operations, only detecting
insertions and generating matching rules was already rather complicated.
Also got rid of ;ost rna_path string allocation in collection diffing
code, could help a bit with speed too.
===================================================================
M source/blender/makesrna/RNA_types.h
M source/blender/makesrna/intern/rna_object.c
M source/blender/makesrna/intern/rna_pose.c
M source/blender/makesrna/intern/rna_rna.c
===================================================================
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 77d9aabd661..5d6f309ad65 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -158,7 +158,7 @@ typedef enum PropertySubType {
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31
- * FREE FLAGS: 9, 11, 13, 14, 15, 30 */
+ * FREE FLAGS: 11, 13, 14, 15, 30 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@@ -178,6 +178,8 @@ typedef enum PropertyFlag {
/* Means the property can be overriden by a local 'proxy' of some linked datablock. */
PROP_OVERRIDABLE_STATIC = (1 << 2),
+ /* The property supports insertion (collections only). */
+ PROP_OVERRIDABLE_STATIC_INSERTION = (1 << 9),
/* Forbid usage of this property in comparison (& hence override) code.
* Useful e.g. for collections of data like mesh's geometry, particles, etc. */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 464fcc3856e..0fec39f9676 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2067,13 +2067,13 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Modifier");
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the object");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
rna_def_object_modifiers(brna, prop);
/* constraints */
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Constraint");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
RNA_def_property_ui_text(prop, "Constraints", "Constraints affecting the transformation of the object");
/* RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "constraints__add", "constraints__remove"); */
rna_def_object_constraints(brna, prop);
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index a2005dbb161..df1e7a63bd9 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -806,7 +806,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* Bone Constraints */
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Constraint");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel");
rna_def_pose_channel_constraints(brna, prop);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 448d0882fb3..bdb5c215da2 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -106,6 +106,7 @@ const EnumPropertyItem rna_enum_property_unit_items[] = {
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
+#include "BLI_string.h"
#include "BKE_library_override.h"
@@ -1093,39 +1094,129 @@ static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key
/* Default override (and compare) callbacks. */
-/* Used for both Pointer and Collection properties. */
-static int rna_property_override_diff_propptr(
- PointerRNA *propptr_a, PointerRNA *propptr_b, eRNACompareMode mode, const bool no_ownership,
- IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
+/* Ensures it makes sense to go inside the pointers to compare their content
+ * (if they are IDs, or have different names or RNA type, then this would be meaningless). */
+static bool rna_property_override_diff_propptr_validate_diffing(
+ PointerRNA *propptr_a, PointerRNA *propptr_b,
+ bool *r_is_id, bool *r_is_null, bool *r_is_type_diff,
+ char **r_propname_a, char *propname_a_buff, size_t propname_a_buff_size,
+ char **r_propname_b, char *propname_b_buff, size_t propname_b_buff_size)
{
- const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
+ BLI_assert(propptr_a != NULL);
- bool is_id = false;
- bool is_type_null = false;
+ bool is_valid_for_diffing = true;
+ const bool do_force_name = r_propname_a != NULL;
+
+ if (do_force_name) {
+ BLI_assert(r_propname_a != NULL);
+ BLI_assert(r_propname_b != NULL);
+ }
+
+ *r_is_id = *r_is_null = *r_is_type_diff = false;
/* Beware, PointerRNA_NULL has no type and is considered a 'blank page'! */
if (propptr_a->type == NULL) {
- if (propptr_b->type == NULL) {
- if (r_override_changed) {
- *r_override_changed = false;
- }
- return 0;
+ if (propptr_b == NULL || propptr_b->type == NULL) {
+ *r_is_null = true;
}
- is_id = RNA_struct_is_ID(propptr_b->type);
- is_type_null = true;
+ else {
+ *r_is_id = RNA_struct_is_ID(propptr_b->type);
+ *r_is_null = true;
+ *r_is_type_diff = true;
+ }
+ is_valid_for_diffing = false;
}
else {
- is_id = RNA_struct_is_ID(propptr_a->type);
- is_type_null = (propptr_b->type == NULL);
+ *r_is_id = RNA_struct_is_ID(propptr_a->type);
+ *r_is_null = *r_is_type_diff = (ELEM(NULL, propptr_b, propptr_b->type));
+ is_valid_for_diffing = !(*r_is_id || *r_is_null);
}
- if (is_id) {
+ if (propptr_b == NULL || propptr_a->type != propptr_b->type) {
+ *r_is_type_diff = true;
+ is_valid_for_diffing = false;
+// printf("%s: different pointer RNA types\n", rna_path ? rna_path : "<UNKNOWN>");
+ }
+
+ /* We do a generic quick first comparison checking for "name" and/or "type" properties.
+ * We assume that is any of those are false, then we are not handling the same data.
+ * This helps a lot in static override case, especially to detect inserted items in collections. */
+ if (is_valid_for_diffing || do_force_name) {
+ PropertyRNA *nameprop_a = RNA_struct_name_property(propptr_a->type);
+ PropertyRNA *nameprop_b = (propptr_b != NULL) ? RNA_struct_name_property(propptr_b->type) : NULL;
+
+ int propname_a_len = 0, propname_b_len = 0;
+ char *propname_a = NULL;
+ char *propname_b = NULL;
+ char buff_a[4096];
+ char buff_b[4096];
+ if (nameprop_a != NULL) {
+ if (r_propname_a == NULL && propname_a_buff == NULL) {
+ propname_a_buff = buff_a;
+ propname_a_buff_size = sizeof(buff_a);
+ }
+
+ propname_a = RNA_property_string_get_alloc(
+ propptr_a, nameprop_a, propname_a_buff, propname_a_buff_size, &propname_a_len);
+// printf("propname_a = %s\n", propname_a ? propname_a : "<NONE>");
+
+ if (r_propname_a != NULL) {
+ *r_propname_a = propname_a;
+ }
+ }
+// else printf("item of type %s a has no name property!\n", propptr_a->type->name);
+ if (nameprop_b != NULL) {
+ if (r_propname_b == NULL && propname_b_buff == NULL) {
+ propname_b_buff = buff_b;
+ propname_b_buff_size = sizeof(buff_b);
+ }
+
+ propname_b = RNA_property_string_get_alloc(
+ propptr_b, nameprop_b, propname_b_buff, propname_b_buff_size, &propname_b_len);
+
+ if (r_propname_b != NULL) {
+ *r_propname_b = propname_b;
+ }
+ }
+ if (propname_a != NULL && propname_b != NULL) {
+ if (propname_a_len != propname_b_len ||
+ propname_a[0] != propname_b[0] ||
+ !STREQ(propname_a, propname_b))
+ {
+ is_valid_for_diffing = false;
+// printf("%s: different names\n", rna_path ? rna_path : "<UNKNOWN>");
+ }
+ }
+ }
+
+ if (*r_is_id) {
BLI_assert(propptr_a->data == propptr_a->id.data && propptr_b->data == propptr_b->id.data);
+ }
+
+ return is_valid_for_diffing;
+}
+
+/* Used for both Pointer and Collection properties. */
+static int rna_property_override_diff_propptr(
+ PointerRNA *propptr_a, PointerRNA *propptr_b, eRNACompareMode mode, const bool no_ownership,
+ IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
+{
+ const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
+
+ bool is_id = false;
+ bool is_null = false;
+ bool is_type_diff = false;
+ /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
+ bool is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
+ propptr_a, propptr_b, &is_id, &is_null, &is_type_diff,
+ NULL, NULL, 0, NULL, NULL, 0);
+
+ if (is_id) {
BLI_assert(no_ownership); /* For now, once we deal with nodetrees we'll want to get rid of that one. */
}
if (override) {
- if (no_ownership /* || is_id */ || is_type_null) {
+ if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
/* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
* This is a quite safe path to infinite loop, among other nasty issues.
* Instead, just compare pointers themselves. */
@@ -1156,6 +1247,8 @@ static int rna_property_override_diff_propptr(
}
}
else {
+ /* We could also use is_diff_pointer, but then we potentially lose the gt/lt info -
+ * and don't think performances are critical here for now anyway... */
return !RNA_struct_equals(propptr_a, propptr_b, mode);
}
}
@@ -1374,10 +1467,13 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
case PROP_STRING:
{
- char fixed_a[128], fixed_b[128];
+ char fixed_a[4096], fixed_b[4096];
int len_str_a, len_str_b;
char *value_a = RNA_property_string_get_alloc(ptr_a, prop_a, fixed_a, sizeof(fixed_a), &len_str_a);
char *value_b = RNA_property_string_get_alloc(ptr_b, prop_b, fixed_b, sizeof(fixed_b), &len_str_b);
+ /* TODO we could do a check on length too, but then we wou
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list