Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2016-09-18 22:36:34 +0300
committerJulian Eisel <eiseljulian@gmail.com>2016-09-18 22:44:42 +0300
commit572bc1364ca9d978edf5aee991849dd4f8e56a52 (patch)
tree61e965068f2d6bc835ecb8bd0ffe29709c9f5c1d /source/blender/blenlib/intern/listbase.c
parent6c28d3bac26b22049768824bef6ae9d0e82bb71f (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/intern/listbase.c')
-rw-r--r--source/blender/blenlib/intern/listbase.c38
1 files changed, 38 insertions, 0 deletions
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).