Undo System: id-map avoid duplicate add/lookup
authorCampbell Barton <ideasman42@gmail.com>
Tue, 3 Apr 2018 14:46:11 +0000 (16:46 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 3 Apr 2018 15:03:33 +0000 (17:03 +0200)
Add versions of add/lookup that check the previous item.

source/blender/blenkernel/BKE_undo_system.h
source/blender/blenkernel/intern/undo_system.c

index 6072ecfae4aed972fd7a54bf9602aed7fa1c4d66..d2a322a50f0454ca7bffd4592276869337ebe8f0 100644 (file)
@@ -180,7 +180,15 @@ struct UndoIDPtrMap *BKE_undosys_ID_map_create(void);
 void                 BKE_undosys_ID_map_destroy(struct UndoIDPtrMap *map);
 void                 BKE_undosys_ID_map_add(struct UndoIDPtrMap *map, ID *id);
 struct ID           *BKE_undosys_ID_map_lookup(const struct UndoIDPtrMap *map, const struct ID *id_src);
-void                 BKE_undosys_ID_map_foreach_ID_ref(
+
+void BKE_undosys_ID_map_add_with_prev(
+        struct UndoIDPtrMap *map, struct ID *id,
+        struct ID **id_prev);
+struct ID *BKE_undosys_ID_map_lookup_with_prev(
+        const struct UndoIDPtrMap *map, struct ID *id_src,
+        struct ID *id_prev_match[2]);
+
+void BKE_undosys_ID_map_foreach_ID_ref(
         struct UndoIDPtrMap *map,
         UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data);
 
index bb4c0b1130e8c40b946377d5755a728250715604..d478be7db06d9f9499db07bd6687502e263bb1ba 100644 (file)
@@ -776,6 +776,7 @@ void BKE_undosys_ID_map_add(UndoIDPtrMap *map, ID *id)
        map->pmap[len_src].index = len_src;
        map->len = len_dst;
 
+       /* TODO(campbell): use binary search result and memmove instread of full-sort. */
        qsort(map->pmap, map->len, sizeof(*map->pmap), BLI_sortutil_cmp_ptr);
 }
 
@@ -792,4 +793,26 @@ ID *BKE_undosys_ID_map_lookup(const UndoIDPtrMap *map, const ID *id_src)
        return id_dst;
 }
 
+void BKE_undosys_ID_map_add_with_prev(UndoIDPtrMap *map, ID *id, ID **id_prev)
+{
+       if (id == *id_prev) {
+               return;
+       }
+       *id_prev = id;
+       BKE_undosys_ID_map_add(map, id);
+}
+
+ID *BKE_undosys_ID_map_lookup_with_prev(const UndoIDPtrMap *map, ID *id_src, ID *id_prev_match[2])
+{
+       if (id_src == id_prev_match[0]) {
+               return id_prev_match[1];
+       }
+       else {
+               ID *id_dst = BKE_undosys_ID_map_lookup(map, id_src);
+               id_prev_match[0] = id_src;
+               id_prev_match[1] = id_dst;
+               return id_dst;
+       }
+}
+
 /** \} */