[Bf-blender-cvs] [734a889056d] id_override_static: Some cleanup, introduce idea of 'override template'.

Bastien Montagne noreply at git.blender.org
Wed May 31 18:01:57 CEST 2017


Commit: 734a889056d15f20ba570b618e73aa5d600297c1
Author: Bastien Montagne
Date:   Wed May 31 12:55:53 2017 +0200
Branches: id_override_static
https://developer.blender.org/rB734a889056d15f20ba570b618e73aa5d600297c1

Some cleanup, introduce idea of 'override template'.

Nothing functionnal for now, just made it possible for override to have
NULL reference ID.

Those overrides would be used as templates (created in original file of
the ID, they define some kind of default overriding settings). They
should also allow to forcefully lock some properties (forbid users of
that library ID to override some properties).

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

M	source/blender/blenkernel/intern/library_override.c
M	source/blender/editors/interface/interface_ops.c
M	source/blender/makesrna/intern/rna_access.c

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

diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index 1f43eee5c7f..f3ae2c9f314 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -58,7 +58,9 @@ static void bke_override_property_operation_clear(IDOverridePropertyOperation *o
 /** Initialize empty overriding of \a reference_id by \a local_id. */
 IDOverride *BKE_override_init(struct ID *local_id, struct ID *reference_id)
 {
-	BLI_assert(reference_id->lib != NULL);
+	/* If reference_id is NULL, we are creating an override template for purely local data.
+	 * Else, reference *must* be linked data. */
+	BLI_assert(reference_id == NULL || reference_id->lib != NULL);
 
 	local_id->override = MEM_callocN(sizeof(*local_id->override), __func__);
 	local_id->override->reference = reference_id;
@@ -273,7 +275,12 @@ bool BKE_override_status_check_local(ID *local)
 
 	ID *reference = local->override->reference;
 
-	BLI_assert(reference != NULL && GS(local->name) == GS(reference->name));
+	if (reference == NULL) {
+		/* This is an override template, local status is always OK! */
+		return true;
+	}
+
+	BLI_assert(GS(local->name) == GS(reference->name));
 
 	/* Note that reference is assumed always valid, caller has to ensure that itself. */
 
@@ -304,7 +311,12 @@ bool BKE_override_status_check_reference(ID *local)
 
 	ID *reference = local->override->reference;
 
-	BLI_assert(reference != NULL && GS(local->name) == GS(reference->name));
+	if (reference == NULL) {
+		/* This is an override template, reference is virtual, so its status is always OK! */
+		return true;
+	}
+
+	BLI_assert(GS(local->name) == GS(reference->name));
 
 	if (reference->override && (reference->tag & LIB_TAG_OVERRIDE_OK) == 0) {
 		if (!BKE_override_status_check_reference(reference)) {
@@ -343,9 +355,10 @@ bool BKE_override_status_check_reference(ID *local)
 bool BKE_override_operations_create(ID *local, const bool no_skip)
 {
 	BLI_assert(local->override != NULL);
+	const bool is_template = (local->override->reference == NULL);
 	bool ret = false;
 
-	if (local->flag & LIB_AUTOOVERRIDE) {
+	if (!is_template && local->flag & LIB_AUTOOVERRIDE) {
 		/* This prevents running that (heavy) callback too often when editing data. */
 		const double currtime = PIL_check_seconds_timer();
 		if (!no_skip && (currtime - local->override->last_auto_run) < OVERRIDE_AUTO_CHECK_DELAY) {
@@ -371,7 +384,7 @@ bool BKE_override_operations_create(ID *local, const bool no_skip)
 /** Update given override from its reference (re-applying overriden properties). */
 void BKE_override_update(Main *bmain, ID *local)
 {
-	if (local->override == NULL) {
+	if (local->override == NULL || local->override->reference == NULL) {
 		return;
 	}
 
@@ -476,12 +489,17 @@ OverrideStorage *BKE_override_operations_store_initialize(void)
 /**
  * Generate suitable 'write' data (this only affects differential override operations).
  *
- * \note ID is in 'invalid' state for all usages but being written to file, after this function has been called and
- * until \a BKE_override_operations_store_end is called to restore it. */
+ * Note that \a local ID is no more modified by this call, all extra data are stored in its temp \a storage_id copy. */
 ID *BKE_override_operations_store_start(OverrideStorage *override_storage, ID *local)
 {
 	BLI_assert(local->override != NULL);
 	BLI_assert(override_storage != NULL);
+	const bool is_template = (local->override->reference == NULL);
+
+	if (is_template) {
+		/* This is actually purely local data with an override template, nothing to do here! */
+		return NULL;
+	}
 
 	/* Forcefully ensure we now about all needed override operations. */
 	BKE_override_operations_create(local, true);
@@ -489,15 +507,9 @@ ID *BKE_override_operations_store_start(OverrideStorage *override_storage, ID *l
 	ID *storage_id;
 	TIMEIT_START_AVERAGED(BKE_override_operations_store_start);
 
-	/* Here we work on original local data-block, after having made a temp copy of it.
-	 * Once we are done, _store_end() will swap temp and local contents.
-	 * This allows us to keep most of original data to write (which is needed to (hopefully) avoid memory/pointers
-	 * collisions in .blend file), and also neats things like original ID name. ;) */
-	/* Note: ideally I'd rather work on copy here as well, and not touch to original at all, but then we'd have
-	 * issues with ID data itself (which is currently not swapped by BKE_id_swap()) AND pointers overlapping. */
-
-	/* XXX TODO We *need* an id_copy_nolib(), that stays out of Main and does not inc/dec ID pointers... */
-	id_copy(override_storage, local, &storage_id, false);  /* XXX ...and worse of all, this won't work with scene! */
+	/* XXX TODO We may also want a specialized handling of things here too, to avoid copying heavy never-overridable
+	 *          data (like Mesh geometry etc.)? And also maybe avoid lib refcounting completely (shallow copy...). */
+	id_copy((Main *)override_storage, local, &storage_id, false);  /* XXX ...and worse of all, this won't work with scene! */
 
 	if (storage_id != NULL) {
 		PointerRNA rnaptr_reference, rnaptr_final, rnaptr_storage;
@@ -517,7 +529,7 @@ ID *BKE_override_operations_store_start(OverrideStorage *override_storage, ID *l
 	return storage_id;
 }
 
-/** Restore given ID modified by \a BKE_override_operations_store_start, to its valid original state. */
+/** Restore given ID modified by \a BKE_override_operations_store_start, to its original state. */
 void BKE_override_operations_store_end(OverrideStorage *UNUSED(override_storage), ID *local)
 {
 	BLI_assert(local->override != NULL);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index eea52076756..ca130d95383 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -466,10 +466,15 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
 	BLI_assert(oprop != NULL);
 	BLI_assert(id != NULL && id->override != NULL);
 
-	/* We need source (i.e. linked data) to restore values of deleted overrides... */
-	RNA_id_pointer_create(id->override->reference, &id_refptr);
-	if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) {
-		BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer");
+	const bool is_template = (id->override->reference == NULL);
+
+	/* We need source (i.e. linked data) to restore values of deleted overrides...
+	 * If this is an override template, we obviously do not need to restore anything. */
+	if (!is_template) {
+		RNA_id_pointer_create(id->override->reference, &id_refptr);
+		if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) {
+			BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer");
+		}
 	}
 
 	if (!all && index != -1) {
@@ -488,7 +493,9 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
 			}
 		}
 		BKE_override_property_operation_delete(oprop, opop);
-		RNA_property_copy(&ptr, &src, prop, index);
+		if (!is_template) {
+			RNA_property_copy(&ptr, &src, prop, index);
+		}
 		if (BLI_listbase_is_empty(&oprop->operations)) {
 			BKE_override_property_delete(id->override, oprop);
 		}
@@ -496,7 +503,9 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
 	else {
 		/* Just remove whole generic override operation of this property. */
 		BKE_override_property_delete(id->override, oprop);
-		RNA_property_copy(&ptr, &src, prop, -1);
+		if (!is_template) {
+			RNA_property_copy(&ptr, &src, prop, -1);
+		}
 	}
 
 	return operator_button_property_finish(C, &ptr, prop);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 24eea22c898..30202a2f572 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -7593,7 +7593,7 @@ static bool rna_property_override_operation_store(
 	if (prop->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! */
+		/* XXX TODO this is ugly, we already get correct prop in upcalling code, should just pass them to this func! */
 		prop = (PropertyRNA *)rna_idproperty_find(ptr, ((IDProperty *)prop)->name);
 		fromprop = (PropertyRNA *)rna_idproperty_find(fromptr, ((IDProperty *)fromprop)->name);
 		if (storage) {
@@ -7965,7 +7965,7 @@ bool RNA_struct_override_matches(
 	return equals;
 }
 
-/** Store needed second operands into local data-block for differential override operations. */
+/** Store needed second operands into \a storage data-block for differential override operations. */
 bool RNA_struct_override_store(PointerRNA *local, PointerRNA *reference, PointerRNA *storage, IDOverride *override)
 {
 	bool changed = false;




More information about the Bf-blender-cvs mailing list