diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 96349a7b066..4ec222c073e 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -76,6 +76,7 @@ int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); +void BLI_listbases_swaplinks(struct ListBase *listbasea, struct ListBase *listbaseb, void *vlinka, void *vlinkb) ATTR_NONNULL(2, 3); void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index c9bf4976ae8..3bf0dfa09fa 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -169,6 +169,34 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) else if (listbase->first == linkb) listbase->first = linka; } +/** + * Swaps \a vlinka and \a vlinkb from their respective lists. Assumes they are both already in their lista! + */ +void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb) +{ + Link *linka = vlinka; + Link *linkb = vlinkb; + Link linkc = {NULL}; + + if (!linka || !linkb) { + return; + } + + /* Temporary link to use as placeholder of the links positions */ + BLI_insertlinkafter(listbasea, linka, &linkc); + + /* Bring linka into linkb position */ + BLI_remlink(listbasea, linka); + BLI_insertlinkafter(listbaseb, linkb, linka); + + /* Bring linkb into linka position */ + BLI_remlink(listbaseb, linkb); + BLI_insertlinkafter(listbasea, &linkc, linkb); + + /* Remove temporary link */ + BLI_remlink(listbasea, &linkc); +} + /** * Removes the head from \a listbase and returns it. */