Fix T60267: Assert manipulating a collection
authorCampbell Barton <ideasman42@gmail.com>
Mon, 14 Jan 2019 02:58:38 +0000 (13:58 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 14 Jan 2019 02:59:56 +0000 (13:59 +1100)
source/blender/windowmanager/message_bus/intern/wm_message_bus.c
source/blender/windowmanager/message_bus/intern/wm_message_bus_rna.c

index 63a897b..439f63d 100644 (file)
@@ -245,6 +245,10 @@ void WM_msg_id_remove(struct wmMsgBus *mbus, const struct ID *id)
  * \note While we could have a separate type for ID's, use RNA since there is enough overlap.
  * \{ */
 
+
+/**
+ * \note #wmMsgBus.messages_tag_count isn't updated, caller must handle.
+ */
 void wm_msg_subscribe_value_free(
         wmMsgSubscribeKey *msg_key, wmMsgSubscribeValueLink *msg_lnk)
 {
index 619777f..6934f15 100644 (file)
@@ -120,10 +120,15 @@ static void wm_msg_rna_update_by_id(
 
                        /* Remove any non-persistent values, so a single persistent
                         * value doesn't modify behavior for the rest. */
-                       wmMsgSubscribeValueLink *msg_lnk_next;
-                       for (wmMsgSubscribeValueLink *msg_lnk = key->head.values.first; msg_lnk; msg_lnk = msg_lnk_next) {
+                       for (wmMsgSubscribeValueLink *msg_lnk = key->head.values.first, *msg_lnk_next;
+                            msg_lnk;
+                            msg_lnk = msg_lnk_next)
+                       {
                                msg_lnk_next = msg_lnk->next;
                                if (msg_lnk->params.is_persistent == false) {
+                                       if (msg_lnk->params.tag) {
+                                               mbus->messages_tag_count -= 1;
+                                       }
                                        wm_msg_subscribe_value_free(&key->head, msg_lnk);
                                }
                        }
@@ -153,6 +158,18 @@ static void wm_msg_rna_update_by_id(
                        }
 
                        if (remove) {
+                               for (wmMsgSubscribeValueLink *msg_lnk = key->head.values.first, *msg_lnk_next;
+                                    msg_lnk;
+                                    msg_lnk = msg_lnk_next)
+                               {
+                                       msg_lnk_next = msg_lnk->next;
+                                       if (msg_lnk->params.is_persistent == false) {
+                                               if (msg_lnk->params.tag) {
+                                                       mbus->messages_tag_count -= 1;
+                                               }
+                                               wm_msg_subscribe_value_free(&key->head, msg_lnk);
+                                       }
+                               }
                                /* Failed to persist, remove the key. */
                                BLI_remlink(&mbus->messages, key);
                                wm_msg_rna_gset_key_free(key);
@@ -176,6 +193,18 @@ static void wm_msg_rna_remove_by_id(struct wmMsgBus *mbus, const ID *id)
                wmMsgSubscribeKey_RNA *key = BLI_gsetIterator_getKey(&gs_iter);
                BLI_gsetIterator_step(&gs_iter);
                if (key->msg.params.ptr.id.data == id) {
+                       /* Clear here so we can decrement 'messages_tag_count'. */
+                       for (wmMsgSubscribeValueLink *msg_lnk = key->head.values.first, *msg_lnk_next;
+                            msg_lnk;
+                            msg_lnk = msg_lnk_next)
+                       {
+                               msg_lnk_next = msg_lnk->next;
+                               if (msg_lnk->params.tag) {
+                                       mbus->messages_tag_count -= 1;
+                               }
+                               wm_msg_subscribe_value_free(&key->head, msg_lnk);
+                       }
+
                        BLI_remlink(&mbus->messages, key);
                        BLI_gset_remove(gs, key, NULL);
                        wm_msg_rna_gset_key_free(key);