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>2018-01-11 00:45:44 +0300
committerJulian Eisel <eiseljulian@gmail.com>2018-01-11 00:45:44 +0300
commit748e95ad50f260dd67aa83927dd90b389a1f3c59 (patch)
tree0328e4cfc703fa5c4630539e4818e25e7f5aac58 /source/blender/editors/space_outliner/outliner_tree.c
parent181124ad1352b19d82e178f302dd4b5c178e54ce (diff)
Fix crash when deleting collections
With factory settings, steps to reproduce were: * Select "Collection 1" (in "RenderLayer") * Delete It might crash at this point, although maybe this crash is ASAN only. However, this was also doing some weird things that I've corrected now. It called outliner_build_tree in an operator callback. This should only be called in the main redraw function or so, not in regular handlers. Instead, we manually cleanup the tree to keep it valid.
Diffstat (limited to 'source/blender/editors/space_outliner/outliner_tree.c')
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 3a97964e538..4097751fd0c 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -189,16 +189,11 @@ static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short ty
/* ********************************************************* */
/* Tree Management */
-void outliner_free_tree(ListBase *lb)
+void outliner_free_tree(ListBase *tree)
{
- while (lb->first) {
- TreeElement *te = lb->first;
-
- outliner_free_tree(&te->subtree);
- BLI_remlink(lb, te);
-
- if (te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name);
- MEM_freeN(te);
+ for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
+ element_next = element->next;
+ outliner_free_tree_element(element, tree);
}
}
@@ -208,6 +203,25 @@ void outliner_cleanup_tree(SpaceOops *soops)
outliner_storage_cleanup(soops);
}
+/**
+ * Free \a element and its sub-tree and remove its link in \a parent_subtree.
+ *
+ * \note Does not remove the TreeStoreElem of \a element!
+ * \param parent_subtree Subtree of the parent element, so the list containing \a element.
+ */
+void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
+{
+ BLI_assert(BLI_findindex(parent_subtree, element) > -1);
+ BLI_remlink(parent_subtree, element);
+
+ outliner_free_tree(&element->subtree);
+
+ if (element->flag & TE_FREE_NAME) {
+ MEM_freeN((void *)element->name);
+ }
+ MEM_freeN(element);
+}
+
/* ********************************************************* */
@@ -1780,11 +1794,7 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
tselem->flag &= ~TSE_SEARCHMATCH;
if ((!TSELEM_OPEN(tselem, soops)) || outliner_filter_tree(soops, &te->subtree) == 0) {
- outliner_free_tree(&te->subtree);
- BLI_remlink(lb, te);
-
- if (te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name);
- MEM_freeN(te);
+ outliner_free_tree_element(te, lb);
}
}
else {