[Bf-blender-cvs] [d982122] id_override_static: Some initial, WIP DNA/RNA/readwrite code for static ID override.

Bastien Montagne noreply at git.blender.org
Mon Jan 2 12:56:33 CET 2017


Commit: d982122f796f794330fca7131a35d387f833ffc7
Author: Bastien Montagne
Date:   Wed Dec 7 21:40:07 2016 +0100
Branches: id_override_static
https://developer.blender.org/rBd982122f796f794330fca7131a35d387f833ffc7

Some initial, WIP DNA/RNA/readwrite code for static ID override.

Quite obviously totally useless (and harmless) currently, compiles but
does nothing.

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

M	source/blender/blenkernel/intern/library_query.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/RNA_types.h
M	source/blender/makesrna/intern/rna_define.c

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

diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index fa75c90..40943df 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -313,6 +313,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
 	FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag)
 
+	if (id->override) {
+		CALLBACK_INVOKE_ID(id->override->reference, IDWALK_USER);
+	}
+
 	do {
 		data.self_id = id;
 		data.cd_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_INDIRECT_USAGE : 0;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 03c5d08..146263c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2155,6 +2155,34 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
 
 /* ************ READ ID *************** */
 
+static void lib_link_id(FileData *fd, Main *main)
+{
+	ListBase *lbarray[MAX_LIBARRAY];
+	int base_count, i;
+
+	base_count = set_listbasepointers(main, lbarray);
+
+	for (i = 0; i < base_count; i++) {
+		ListBase *lb = lbarray[i];
+		ID *id;
+
+		for (id = lb->first; id; id = id->next) {
+			if (id->override) {
+				id->override->reference = newlibadr_us(fd, id->lib, id->override->reference);
+			}
+		}
+	}
+}
+
+static void direct_link_id_override_data_cb(FileData *fd, void *datav)
+{
+	IDOverrideData *data = datav;
+
+	data->rna_path = newdataadr(fd, data->rna_path);
+	data->subitem_reference_name = newdataadr(fd, data->subitem_reference_name);
+	data->subitem_local_name = newdataadr(fd, data->subitem_local_name);
+}
+
 static void direct_link_id(FileData *fd, ID *id)
 {
 	/*link direct data of ID properties*/
@@ -2163,6 +2191,12 @@ static void direct_link_id(FileData *fd, ID *id)
 		/* this case means the data was written incorrectly, it should not happen */
 		IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
 	}
+
+	/* Link direct data of overrides. */
+	if (id->override) {
+		id->override = newdataadr(fd, id->override);
+		link_list_ex(fd, &id->override->data, direct_link_id_override_data_cb);
+	}
 }
 
 /* ************ READ CurveMapping *************** */
@@ -8383,6 +8417,8 @@ static void lib_link_all(FileData *fd, Main *main)
 {
 	oldnewmap_sort(fd);
 	
+	lib_link_id(fd, main);
+
 	/* No load UI for undo memfiles */
 	if (fd->memfile == NULL) {
 		lib_link_windowmanager(fd, main);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ad1999c..4f79938 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -675,6 +675,21 @@ static void write_iddata(void *wd, const ID *id)
 	if (id->properties && !ELEM(GS(id->name), ID_WM)) {
 		IDP_WriteProperty(id->properties, wd);
 	}
+
+	if (id->override) {
+		writestruct(wd, DATA, IDOverride, 1, id->override);
+
+		writelist(wd, DATA, IDOverrideData, &id->override->data);
+		for (IDOverrideData *od = id->override->data.first; od; od = od->next) {
+			writedata(wd, DATA, strlen(od->rna_path) + 1, od->rna_path);
+			if (od->subitem_reference_name) {
+				writedata(wd, DATA, strlen(od->subitem_reference_name) + 1, od->subitem_reference_name);
+			}
+			if (od->subitem_local_name) {
+				writedata(wd, DATA, strlen(od->subitem_local_name) + 1, od->subitem_local_name);
+			}
+		}
+	}
 }
 
 static void write_previews(WriteData *wd, const PreviewImage *prv_orig)
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 59fd0c7..e261748 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -106,6 +106,54 @@ enum {
 
 /* add any future new id property types here.*/
 
+
+/* Static ID override structs. */
+
+/* A single overriding operation data, can affect only a single property. */
+typedef struct IDOverrideData {
+	struct IDOverrideData *next, *prev;
+
+	/* Path from ID to overridden property. *Does not* include indices/names for arrays/collections items. */
+	char *rna_path;
+
+	/* Sub-item references, if needed (for arrays or collections only).
+	 * We need both reference and local values to allow e.g. insertion into collections (constraints, modifiers...).
+	 * In collection case, if names are defined, they are used in priority.
+	 * Names are pointers (instead of char[64]) to save some space, NULL when unset.
+	 * Indices are -1 when unset. */
+	char *subitem_reference_name;
+	char *subitem_local_name;
+	int subitem_reference_index;
+	int subitem_local_index;
+
+	/* Type of override. */
+	short operation;
+
+	short pad_s1[3];
+} IDOverrideData;
+
+/* IDOverrideData->operation. */
+enum {
+	/* Basic operations. */
+	IDOVERRIDE_REPLACE       =   1,  /* Fully replace local value by reference one. */
+
+	/* Numeric-only operations. */
+	IDOVERRIDE_ADD           = 101,  /* Add local value to reference one. */
+	IDOVERRIDE_SUBTRACT      = 102,  /* Subtract local value from reference one (needed due to unsigned values etc.). */
+	IDOVERRIDE_MULTIPLY      = 103,  /* Multiply reference value by local one (useful for scales and the like). */
+
+	/* Collection-only operations. */
+	IDOVERRIDE_INSERT_AFTER  = 201,  /* Insert after given reference's subitem. */
+	IDOVERRIDE_INSERT_BEFORE = 202,  /* Insert before given reference's subitem. */
+};
+
+/* Main container for all overriding data info. */
+typedef struct IDOverride {
+	struct ID *reference;  /* Reference linked ID which this one overrides. */
+	ListBase data;  /* List of IDOverrideData structs. */
+} IDOverride;
+
+
 /* watch it: Sequence has identical beginning. */
 /**
  * ID is the first thing included in all serializable types. It
@@ -134,6 +182,8 @@ typedef struct ID {
 	int us;
 	int icon_id;
 	IDProperty *properties;
+	IDOverride *override;  /* Reference linked ID which this one overrides. */
+	void *pad_v1;
 } ID;
 
 /**
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 1a191a6..17cd79b 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -174,6 +174,9 @@ typedef enum PropertyFlag {
 	 * and collections */
 	PROP_ANIMATABLE              = (1 << 1),
 
+	/* Means the property can be overriden by a local 'proxy' of some linked datablock. */
+	PROP_OVERRIDABLE             = (1 << 8),
+
 	/* This flag means when the property's widget is in 'textedit' mode, it will be updated after every typed char,
 	 * instead of waiting final validation. Used e.g. for text searchbox. */
 	PROP_TEXTEDIT_UPDATE         = (1 << 31),
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index dc97d39..1f36da1 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1144,6 +1144,9 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
 	}
 
 	if (DefRNA.preprocess) {
+		/* TODO For later, once things are working, think we want overridable ON by default. */
+		/*prop->flag |= PROP_OVERRIDABLE;*/
+
 		switch (type) {
 			case PROP_BOOLEAN:
 				DefRNA.silent = 1;




More information about the Bf-blender-cvs mailing list