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:
authorSv. Lockal <lockalsash@gmail.com>2013-08-17 15:49:18 +0400
committerSv. Lockal <lockalsash@gmail.com>2013-08-17 15:49:18 +0400
commit95dc1d922b83e9fbece5c83be1c9607dade7ca4f (patch)
tree410d85909d586dbcbd7cc4cea618340cbe2671b9 /source/blender/editors/space_outliner/outliner_tree.c
parent0f07ca6809f0ab56f3119c1ad2b841a9dbfa4ab4 (diff)
Fix [36486] Outliner doesn't allow to expand Hierarchies of armature if it's present on 2 Scenes
This is done by fixing logic for finding the first unused element in treehash. The blend file from [36486] also exposes a memleak, but it should be addressed separately.
Diffstat (limited to 'source/blender/editors/space_outliner/outliner_tree.c')
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 514bfc43ac7..af870f3ca5d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -150,6 +150,8 @@ static void outliner_storage_cleanup(SpaceOops *soops)
}
}
+/* This function hashes only by type, nr and id, while cmp function also compares 'used' flag;
+ * This is done to skip full treehash rebuild in outliner_storage_cleanup */
static unsigned int tse_hash(const void *ptr)
{
const TreeStoreElem *tse = (const TreeStoreElem *)ptr;
@@ -164,16 +166,27 @@ static int tse_cmp(const void *a, const void *b)
{
const TreeStoreElem *tse_a = (const TreeStoreElem *)a;
const TreeStoreElem *tse_b = (const TreeStoreElem *)b;
- return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id;
+ return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr ||
+ tse_a->id != tse_b->id || tse_a->used != tse_b->used;
+}
+
+static TreeStoreElem *lookup_treehash(GHash *th, short type, short nr, short used, ID *id)
+{
+ TreeStoreElem tse_template;
+ tse_template.type = type;
+ tse_template.nr = type ? nr : 0; // we're picky! :)
+ tse_template.id = id;
+ tse_template.used = used;
+ return BLI_ghash_lookup(th, &tse_template);
}
static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr)
{
/* When treestore comes directly from readfile.c, treehash is empty;
* In this case we don't want to get TSE_CLOSED while adding elements one by one,
- * that is why this function restores treehash */
+ * that is why this function restores treehash */
bool restore_treehash = (soops->treestore && !soops->treehash);
- TreeStoreElem *tselem, elem_template;
+ TreeStoreElem *tselem;
if (soops->treestore == NULL) {
/* if treestore was not created in readfile.c, create it here */
@@ -191,12 +204,9 @@ static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short ty
}
}
- /* check if 'te' is in treestore */
- elem_template.type = type;
- elem_template.nr = type ? nr : 0; // we're picky! :)
- elem_template.id = id;
- tselem = BLI_ghash_lookup(soops->treehash, &elem_template);
- if (tselem && !tselem->used) {
+ /* check for unused tree elements is in treestore */
+ tselem = lookup_treehash(soops->treehash, type, nr, 0, id);
+ if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
return;
@@ -250,16 +260,12 @@ static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *stor
/* tse is not in the treestore, we use its contents to find a match */
TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse)
{
- GHash *th = soops->treehash;
- TreeStoreElem *tselem, tselem_template;
+ TreeStoreElem *tselem;
if (tse->id == NULL) return NULL;
/* check if 'tse' is in treestore */
- tselem_template.id = tse->id;
- tselem_template.type = tse->type;
- tselem_template.nr = tse->type ? tse->nr : 0;
- tselem = BLI_ghash_lookup(th, &tselem_template);
+ tselem = lookup_treehash(soops->treehash, tse->type, tse->nr, tse->used, tse->id);
if (tselem)
return outliner_find_tree_element(&soops->tree, tselem);