diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2016-09-18 22:36:34 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2016-09-18 22:44:42 +0300 |
commit | 572bc1364ca9d978edf5aee991849dd4f8e56a52 (patch) | |
tree | 61e965068f2d6bc835ecb8bd0ffe29709c9f5c1d /source/blender/blenlib | |
parent | 6c28d3bac26b22049768824bef6ae9d0e82bb71f (diff) |
BLI_listbase: Add/use utility to move link (BLI_listbase_link_move)
We were calling BLI_remlink and then BLI_insertlinkbefore/after quite often. BLI_listbase_link_move simplifies code a bit and makes it easier to follow. It also returns if link position has changed which can be used to avoid unnecessary updates.
Added it to a number of list reorder operators for now and made use of return value. Behavior shouldn't be changed.
Also some minor cleanup.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_listbase.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/listbase.c | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 9dfa80006de..96349a7b066 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -69,6 +69,7 @@ void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnew void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1); 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(); void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); int BLI_listbase_count_ex(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index ebee2c7941c..e72eff57ad9 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -342,6 +342,44 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) } } +/** + * Reinsert \a link 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). + * + * \param step: Absolute value defines step size, sign defines direction. E.g pass -1 + * to move \a link before previous, or 1 to move behind next. + * \return If position of \a link has changed. + */ +bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) +{ + Link *link = vlink; + Link *hook = link; + const bool is_up = step < 0; + + if (step == 0 || vlink == NULL) { + return false; + } + BLI_assert(BLI_findindex(listbase, link) != -1); + + /* find link to insert before/after */ + for (int i = 0; i < ABS(step); i++) { + hook = is_up ? hook->prev : hook->next; + if (!hook) { + return false; + } + } + + /* reinsert link */ + BLI_remlink(listbase, vlink); + if (is_up) { + BLI_insertlinkbefore(listbase, hook, vlink); + } + else { + BLI_insertlinkafter(listbase, hook, vlink); + } + return true; +} + /** * Removes and disposes of the entire contents of listbase using direct free(3). |