From 162e184ffd0f2e5f1584b95339df6cb3c429f017 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 9 Apr 2017 16:07:09 +1000 Subject: ListBase: Add insert-replace function Handy to replace an existing link (without having to store before/after links) Use for id-props --- source/blender/blenlib/BLI_listbase.h | 1 + source/blender/blenlib/intern/listbase.c | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'source/blender/blenlib') 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). -- cgit v1.2.3