[Bf-blender-cvs] [7e909a564fc] id_override_static: Heavy refactor of new RNA override/comparison code.

Bastien Montagne noreply at git.blender.org
Tue Nov 14 22:35:45 CET 2017


Commit: 7e909a564fc4e3814e9c6ee06521d9757ea4580e
Author: Bastien Montagne
Date:   Tue Nov 14 22:31:55 2017 +0100
Branches: id_override_static
https://developer.blender.org/rB7e909a564fc4e3814e9c6ee06521d9757ea4580e

Heavy refactor of new RNA override/comparison code.

Main reason here is to make comparison/override_diff/override_store/override_apply
customizable per RNA property if needed.

This should allow us especially to get advanced behavior on case-by-case
basis, when dealing with Pointer and Collection properties mostly.

Note that IDProps remain fuzzy area for now, a big part of the code
tries to take them into account, but it's most likely still missing some
bits, and definitively not tested at all yet!

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

M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/RNA_define.h
M	source/blender/makesrna/intern/makesrna.c
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/makesrna/intern/rna_define.c
M	source/blender/makesrna/intern/rna_internal.h
M	source/blender/makesrna/intern/rna_internal_types.h
M	source/blender/makesrna/intern/rna_rna.c

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

diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 4e73843c36f..2cc2add8b65 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1234,18 +1234,20 @@ StructRNA *ID_code_to_RNA_type(short idcode);
 
 void _RNA_warning(const char *format, ...) ATTR_PRINTF_FORMAT(1, 2);
 
-/* Equals test (skips pointers and collections)
- * is_strict false assumes uninitialized properties are equal */
+/* Equals test. */
 
-typedef enum eRNAEqualsMode {
+/* Note: In practice, EQ_STRICT and EQ_COMPARE have same behavior currently, and will yield same result. */
+typedef enum eRNACompareMode {
+	/* Only care about equality, not full comparison. */
 	RNA_EQ_STRICT,           /* set/unset ignored */
 	RNA_EQ_UNSET_MATCH_ANY,  /* unset property matches anything */
 	RNA_EQ_UNSET_MATCH_NONE, /* unset property never matches set property */
-} eRNAEqualsMode;
-
-bool RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop, eRNAEqualsMode mode);
-bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, eRNAEqualsMode mode);
+	/* Full comparison. */
+	RNA_EQ_COMPARE,
+} eRNACompareMode;
 
+bool RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop, eRNACompareMode mode);
+bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, eRNACompareMode mode);
 
 /* Override. */
 
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 47648583e14..755c5747523 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -175,6 +175,8 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *update
 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable);
 
+void RNA_def_property_override_funcs(PropertyRNA *prop, const char *diff, const char *store, const char *apply);
+
 void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func);
 void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func);
 
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 720f7324bdb..90e9304998f 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -3015,12 +3015,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 	        prop->arraylength[1],
 	        prop->arraylength[2],
 	        prop->totarraylength);
-	fprintf(f, "\t%s%s, %d, %s, %s,\n",
+	fprintf(f, "\t%s%s, %d, %s, %s, %s, %s, %s,\n",
 	        (prop->flag & PROP_CONTEXT_UPDATE) ? "(UpdateFunc)" : "",
 	        rna_function_string(prop->update),
 	        prop->noteflag,
 	        rna_function_string(prop->editable),
-	        rna_function_string(prop->itemeditable));
+	        rna_function_string(prop->itemeditable),
+	        rna_function_string(prop->override_diff),
+	        rna_function_string(prop->override_store),
+	        rna_function_string(prop->override_apply));
 
 	if (prop->flag_internal & PROP_INTERN_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
 	else fprintf(f, "\t0, -1");
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index a79e6655317..808d0837b4f 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -6929,11 +6929,21 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
 }
 
 static bool rna_property_override_operation_apply(
-        PointerRNA *ptr, PointerRNA *fromptr, PointerRNA *storage, PropertyRNA *prop, int index, int override_op);
+        PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage, PropertyRNA *prop_local,
+        IDOverridePropertyOperation *opop);
 
 bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
 {
-	return rna_property_override_operation_apply(ptr, fromptr, NULL, prop, index, IDOVERRIDE_OP_REPLACE);
+	if (!RNA_property_editable(ptr, prop)) {
+		return false;
+	}
+
+	IDOverridePropertyOperation opop = {
+	    .operation = IDOVERRIDE_OP_REPLACE,
+	    .subitem_reference_index = index,
+	    .subitem_local_index = index
+	};
+	return rna_property_override_operation_apply(ptr, fromptr, NULL, prop, &opop);
 }
 
 /* use RNA_warning macro which includes __func__ suffix */
@@ -6958,18 +6968,18 @@ void _RNA_warning(const char *format, ...)
 #endif
 }
 
-static bool rna_property_override_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEqualsMode mode,
-        IDOverride *override, const char *rna_path, bool *r_override_changed,
-        const bool ignore_non_overridable, const bool ignore_overridden);
+static int rna_property_override_diff(
+        PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNACompareMode mode,
+        IDOverride *override, const char *rna_path, bool *r_override_changed, const int flags);
 
-bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEqualsMode mode)
+bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNACompareMode mode)
 {
 	BLI_assert(ELEM(mode, RNA_EQ_STRICT, RNA_EQ_UNSET_MATCH_ANY, RNA_EQ_UNSET_MATCH_NONE));
 
-	return rna_property_override_equals(a, b, prop, mode, NULL, NULL, NULL, false, false);
+	return (rna_property_override_diff(a, b, prop, mode, NULL, NULL, NULL, 0) != 0);
 }
 
-bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNAEqualsMode mode)
+bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNACompareMode mode)
 {
 	CollectionPropertyIterator iter;
 	PropertyRNA *iterprop;
@@ -7000,1071 +7010,180 @@ bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNAEqualsMode mode)
 
 /* Low-level functions, also used by non-override RNA API like copy or equality check. */
 #include "PIL_time_utildefines.h"
-/* Used for both Pointer and Collection properties. */
-static bool rna_property_override_equals_propptr(
-        PointerRNA *propptr_a, PointerRNA *propptr_b, eRNAEqualsMode mode,
-        IDOverride *override, const char *rna_path, bool *r_override_changed,
-        const bool ignore_non_overridable, const bool ignore_overridden)
-{
-	bool is_id = false;
-	bool is_type_null = 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 true;
-		}
-		is_id = RNA_struct_is_ID(propptr_b->type);
-		is_type_null = true;
-	}
-	else {
-		is_id = RNA_struct_is_ID(propptr_a->type);
-		is_type_null = (propptr_b->type == NULL);
-	}
-
-	if (is_id) {
-		BLI_assert(propptr_a->data == propptr_a->id.data && propptr_b->data == propptr_b->id.data);
-	}
-
-	if (override) {
-		if (rna_path) {
-			if (is_type_null || is_id) {
-				/* In case this is an ID (or one of the pointers is NULL), do not compare structs!
-				 * This is a quite safe path to infinite loop.
-				 * Instead, just compare pointers themselves (we assume sub-ID structs cannot loop). */
-				const bool equals = (propptr_a->data == propptr_b->data);
+static int rna_property_override_diff(
+        PointerRNA *ptr_a, PointerRNA *ptr_b, PropertyRNA *prop_a, eRNACompareMode mode,
+        IDOverride *override, const char *rna_path, bool *r_override_changed, const int flags)
+{
+	int len_a, len_b;
 
-				if (!equals && rna_path) {
-					bool created = false;
-					IDOverrideProperty *op = BKE_override_property_get(override, rna_path, &created);
+	PropertyRNA *prop_b = prop_a;
 
-					if (op != NULL && created) {  /* If not yet overridden... */
-						BKE_override_property_operation_get(op, IDOVERRIDE_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
-						if (r_override_changed) {
-							*r_override_changed = created;
-						}
-					}
-				}
+	if (prop_a->magic != RNA_MAGIC) {
+		/* In case of IDProperty, we have to find the *real* idprop of ptr,
+		 * since prop in this case is just a fake wrapper around actual IDProp data, and not a 'real' PropertyRNA. */
+		/* XXX TODO this is ugly, we already get correct prop in upcalling code, whould just pass them to this func! */
+		prop_a = (PropertyRNA *)rna_idproperty_find(ptr_a, ((IDProperty *)prop_a)->name);
+		prop_b = (PropertyRNA *)rna_idproperty_find(ptr_b, ((IDProperty *)prop_b)->name);
 
-				return equals;
-			}
-			else {
-				const bool changed = RNA_struct_auto_override(propptr_a, propptr_b, override, rna_path);
-				if (r_override_changed) {
-					*r_override_changed = *r_override_changed || changed;
-				}
-				/* XXX Simplification here, if no override was added we assume they are equal,
-				 *     this may not be good behavior, time will say. */
-				return !changed;
-			}
-		}
-		else {
-			return RNA_struct_override_matches(
-			            propptr_a, propptr_b, override, ignore_non_overridable, ignore_overridden);
+		if (ELEM(NULL, prop_a, prop_b)) {
+			return 1;
 		}
 	}
-	else {
-		return RNA_struct_equals(propptr_a, propptr_b, mode);
-	}
-}
 
-static bool rna_property_override_equals(
-        PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEqualsMode mode,
-        IDOverride *override, const char *rna_path, bool *r_override_changed,
-        const bool ignore_non_overridable, const bool ignore_overridden)
-{
-	int len, fromlen;
+	BLI_assert(prop_a->override_diff == prop_b->override_diff && prop_a->override_diff != NULL);
 
 	if (mode == RNA_EQ_UNSET_MATCH_ANY) {
 		/* uninitialized properties are assumed to match anything */
-		if (!RNA_property_is_set(a, prop) || !RNA_property_is_set(b, prop))
-			return true;
+		if (!RNA_property_is_set(ptr_a, prop_a) || !RNA_property_is_set(ptr_b, prop_b))
+			return 0;
 	}
 	else if (mode == RNA_EQ_UNSET_MATCH_NONE) {
 		/* unset properties never match set properties */
-		if (RNA_property_is_set(a, prop) != RNA_property_is_set(b, prop))
-			return false;
+		if (RNA_property_is_set(ptr_a, prop_a) != RNA_property_is_set(ptr_b, prop_b))
+			return 1;
 	}
 
 	/* get the length of the array to work with */
-	len = RNA_property_array_length(a, prop);


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list