[Bf-blender-cvs] [162e184ffd0] master: ListBase: Add insert-replace function

Campbell Barton noreply at git.blender.org
Sun Apr 9 08:07:38 CEST 2017


Commit: 162e184ffd0f2e5f1584b95339df6cb3c429f017
Author: Campbell Barton
Date:   Sun Apr 9 16:07:09 2017 +1000
Branches: master
https://developer.blender.org/rB162e184ffd0f2e5f1584b95339df6cb3c429f017

ListBase: Add insert-replace function

Handy to replace an existing link
(without having to store before/after links)

Use for id-props

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

M	source/blender/blenkernel/intern/idprop.c
M	source/blender/blenlib/BLI_listbase.h
M	source/blender/blenlib/intern/listbase.c

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

diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index a596869e5e8..6ebdd371acb 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -503,14 +503,9 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src)
 					break;
 				default:
 				{
-					IDProperty *tmp = other;
-					IDProperty *copy = IDP_CopyProperty(prop);
-
-					BLI_insertlinkafter(&dest->data.group, other, copy);
-					BLI_remlink(&dest->data.group, tmp);
-
-					IDP_FreeProperty(tmp);
-					MEM_freeN(tmp);
+					BLI_insertlinkreplace(&dest->data.group, other, IDP_CopyProperty(prop));
+					IDP_FreeProperty(other);
+					MEM_freeN(other);
 					break;
 				}
 			}
@@ -530,11 +525,9 @@ void IDP_SyncGroupTypes(IDProperty *dst, const IDProperty *src, const bool do_ar
 			if ((prop_dst->type != prop_src->type || prop_dst->subtype != prop_src->subtype) ||
 			    (do_arraylen && ELEM(prop_dst->type, IDP_ARRAY, IDP_IDPARRAY) && (prop_src->len != prop_dst->len)))
 			{
-				IDP_FreeFromGroup(dst, prop_dst);
-				prop_dst = IDP_CopyProperty(prop_src);
-
-				dst->len++;
-				BLI_insertlinkbefore(&dst->data.group, prop_dst_next, prop_dst);
+				BLI_insertlinkreplace(&dst->data.group, prop_dst, IDP_CopyProperty(prop_src));
+				IDP_FreeProperty(prop_dst);
+				MEM_freeN(prop_dst);
 			}
 			else if (prop_dst->type == IDP_GROUP) {
 				IDP_SyncGroupTypes(prop_dst, prop_src, do_arraylen);
@@ -559,11 +552,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src)
 	for (prop = src->data.group.first; prop; prop = prop->next) {
 		for (loop = dest->data.group.first; loop; loop = loop->next) {
 			if (STREQ(loop->name, prop->name)) {
-				IDProperty *copy = IDP_CopyProperty(prop);
-
-				BLI_insertlinkafter(&dest->data.group, loop, copy);
-
-				BLI_remlink(&dest->data.group, loop);
+				BLI_insertlinkreplace(&dest->data.group, loop, IDP_CopyProperty(prop));
 				IDP_FreeProperty(loop);
 				MEM_freeN(loop);
 				break;
@@ -590,9 +579,7 @@ void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop
 	BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name));
 
 	if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) {
-		BLI_insertlinkafter(&group->data.group, prop_exist, prop);
-		
-		BLI_remlink(&group->data.group, prop_exist);
+		BLI_insertlinkreplace(&group->data.group, prop_exist, prop);
 		IDP_FreeProperty(prop_exist);
 		MEM_freeN(prop_exist);
 	}
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 96349a7b066..00e761b81bc 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -67,6 +67,7 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1);
 void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
 void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1);
 void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1);
+void BLI_insertlinkreplace(ListBase *listbase, void *v_l_src, void *v_l_dst) ATTR_NONNULL(1, 2, 3);
 void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2);
 void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1, 2);
 bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL();
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index c9bf4976ae8..6cb7b7d8e3e 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -342,6 +342,40 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
 	}
 }
 
+
+/**
+ * Insert a link in place of another, without changing it's position in the list.
+ *
+ * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`.
+ * - `vreplacelink` *must* be in the list.
+ * - `vnewlink` *must not* be in the list.
+ */
+void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
+{
+	Link *l_old = vreplacelink;
+	Link *l_new = vnewlink;
+
+	/* update adjacent links */
+	if (l_old->next != NULL) {
+		l_old->next->prev = l_new;
+	}
+	if (l_old->prev != NULL) {
+		l_old->prev->next = l_new;
+	}
+
+	/* set direct links */
+	l_new->next = l_old->next;
+	l_new->prev = l_old->prev;
+
+	 /* update list */
+	if (listbase->first == l_old) {
+		listbase->first = l_new;
+	}
+	if (listbase->last == l_old) {
+		listbase->last = l_new;
+	}
+}
+
 /**
  * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move
  * item if new position would exceed list (could optionally move to head/tail).




More information about the Bf-blender-cvs mailing list