Cleanup: Move Outliner runtime hash into internal runtime struct, out of DNA
This way Outliner internal data stays internal, non-Outliner code will not be able to access and mess with this. Further it allows us to use the real type (rather than `void *`), change the type to a C++ container if needed and slightly reduces the size for every Outliner stored in files. Slightly changed how we set the `SO_TREESTORE_REBUILD` for this, but it should effectively behave the same way as before.
This commit is contained in:
parent
f5eaf67e34
commit
3daf28388b
Notes:
blender-bot
2023-02-14 11:00:17 +01:00
Referenced by issue #83420, Closing Preferences Panel crashes Blender
|
@ -1561,7 +1561,6 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
|
|||
/* we only saved what was used */
|
||||
space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
|
||||
}
|
||||
space_outliner->treehash = NULL;
|
||||
space_outliner->tree.first = space_outliner->tree.last = NULL;
|
||||
space_outliner->runtime = NULL;
|
||||
}
|
||||
|
@ -1825,10 +1824,8 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
|
|||
while ((tselem = BLI_mempool_iterstep(&iter))) {
|
||||
BLO_read_id_address(reader, NULL, &tselem->id);
|
||||
}
|
||||
if (space_outliner->treehash) {
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2834,10 +2834,8 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
|
|||
tselem->id = NULL;
|
||||
}
|
||||
}
|
||||
if (space_outliner->treehash) {
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
}
|
||||
else if (sl->spacetype == SPACE_NODE) {
|
||||
|
|
|
@ -47,10 +47,13 @@ struct wmKeyConfig;
|
|||
struct wmOperatorType;
|
||||
|
||||
typedef struct SpaceOutliner_Runtime {
|
||||
/**
|
||||
* Internal C++ object to create and manage the tree for a specific display type (View Layers,
|
||||
* Scenes, Blender File, etc.). */
|
||||
/** Internal C++ object to create and manage the tree for a specific display type (View Layers,
|
||||
* Scenes, Blender File, etc.). */
|
||||
struct TreeDisplay *tree_display;
|
||||
|
||||
/** Pointers to treestore elements, grouped by (id, type, nr)
|
||||
* in hashtable for faster searching */
|
||||
struct GHash *treehash;
|
||||
} SpaceOutliner_Runtime;
|
||||
|
||||
typedef enum TreeElementInsertType {
|
||||
|
|
|
@ -132,9 +132,9 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
|
|||
if (BLI_mempool_len(ts) == unused) {
|
||||
BLI_mempool_destroy(ts);
|
||||
space_outliner->treestore = NULL;
|
||||
if (space_outliner->treehash) {
|
||||
BKE_outliner_treehash_free(space_outliner->treehash);
|
||||
space_outliner->treehash = NULL;
|
||||
if (space_outliner->runtime->treehash) {
|
||||
BKE_outliner_treehash_free(space_outliner->runtime->treehash);
|
||||
space_outliner->runtime->treehash = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -150,16 +150,16 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
|
|||
}
|
||||
BLI_mempool_destroy(ts);
|
||||
space_outliner->treestore = new_ts;
|
||||
if (space_outliner->treehash) {
|
||||
if (space_outliner->runtime->treehash) {
|
||||
/* update hash table to fix broken pointers */
|
||||
BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
|
||||
BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
|
||||
space_outliner->treestore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (space_outliner->treehash) {
|
||||
BKE_outliner_treehash_clear_used(space_outliner->treehash);
|
||||
else if (space_outliner->runtime->treehash) {
|
||||
BKE_outliner_treehash_clear_used(space_outliner->runtime->treehash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,14 +174,14 @@ static void check_persistent(
|
|||
space_outliner->treestore = BLI_mempool_create(
|
||||
sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
if (space_outliner->treehash == NULL) {
|
||||
space_outliner->treehash = BKE_outliner_treehash_create_from_treestore(
|
||||
if (space_outliner->runtime->treehash == NULL) {
|
||||
space_outliner->runtime->treehash = BKE_outliner_treehash_create_from_treestore(
|
||||
space_outliner->treestore);
|
||||
}
|
||||
|
||||
/* find any unused tree element in treestore and mark it as used
|
||||
* (note that there may be multiple unused elements in case of linked objects) */
|
||||
tselem = BKE_outliner_treehash_lookup_unused(space_outliner->treehash, type, nr, id);
|
||||
tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
|
||||
if (tselem) {
|
||||
te->store_elem = tselem;
|
||||
tselem->used = 1;
|
||||
|
@ -196,7 +196,7 @@ static void check_persistent(
|
|||
tselem->used = 0;
|
||||
tselem->flag = TSE_CLOSED;
|
||||
te->store_elem = tselem;
|
||||
BKE_outliner_treehash_add_element(space_outliner->treehash, tselem);
|
||||
BKE_outliner_treehash_add_element(space_outliner->runtime->treehash, tselem);
|
||||
}
|
||||
|
||||
/* ********************************************************* */
|
||||
|
@ -2197,12 +2197,12 @@ void outliner_build_tree(Main *mainvar,
|
|||
space_outliner->search_flags &= ~SO_SEARCH_RECURSIVE;
|
||||
}
|
||||
|
||||
if (space_outliner->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
|
||||
if (space_outliner->runtime->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
|
||||
space_outliner->treestore) {
|
||||
space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
|
||||
BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
|
||||
BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
|
||||
space_outliner->treestore);
|
||||
}
|
||||
space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
|
||||
|
||||
if (region->do_draw & RGN_DRAW_NO_REBUILD) {
|
||||
return;
|
||||
|
|
|
@ -212,7 +212,8 @@ TreeElement *outliner_find_tse(SpaceOutliner *space_outliner, const TreeStoreEle
|
|||
}
|
||||
|
||||
/* check if 'tse' is in treestore */
|
||||
tselem = BKE_outliner_treehash_lookup_any(space_outliner->treehash, tse->type, tse->nr, tse->id);
|
||||
tselem = BKE_outliner_treehash_lookup_any(
|
||||
space_outliner->runtime->treehash, tse->type, tse->nr, tse->id);
|
||||
if (tselem) {
|
||||
return outliner_find_tree_element(&space_outliner->tree, tselem);
|
||||
}
|
||||
|
|
|
@ -349,12 +349,12 @@ static void outliner_free(SpaceLink *sl)
|
|||
if (space_outliner->treestore) {
|
||||
BLI_mempool_destroy(space_outliner->treestore);
|
||||
}
|
||||
if (space_outliner->treehash) {
|
||||
BKE_outliner_treehash_free(space_outliner->treehash);
|
||||
}
|
||||
|
||||
if (space_outliner->runtime) {
|
||||
outliner_tree_display_destroy(&space_outliner->runtime->tree_display);
|
||||
if (space_outliner->runtime->treehash) {
|
||||
BKE_outliner_treehash_free(space_outliner->runtime->treehash);
|
||||
}
|
||||
MEM_freeN(space_outliner->runtime);
|
||||
}
|
||||
}
|
||||
|
@ -377,13 +377,13 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
|
|||
|
||||
BLI_listbase_clear(&space_outliner_new->tree);
|
||||
space_outliner_new->treestore = NULL;
|
||||
space_outliner_new->treehash = NULL;
|
||||
|
||||
space_outliner_new->sync_select_dirty = WM_OUTLINER_SYNC_SELECT_FROM_ALL;
|
||||
|
||||
if (space_outliner->runtime) {
|
||||
space_outliner_new->runtime = MEM_dupallocN(space_outliner->runtime);
|
||||
space_outliner_new->runtime->tree_display = NULL;
|
||||
space_outliner_new->runtime->treehash = NULL;
|
||||
}
|
||||
|
||||
return (SpaceLink *)space_outliner_new;
|
||||
|
@ -414,7 +414,7 @@ static void outliner_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_i
|
|||
changed = true;
|
||||
}
|
||||
}
|
||||
if (space_outliner->treehash && changed) {
|
||||
if (space_outliner->runtime->treehash && changed) {
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
/* postpone a full rebuild because this can be called many times on-free */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
|
@ -279,11 +279,6 @@ typedef struct SpaceOutliner {
|
|||
char show_restrict_flags;
|
||||
short filter_id_type;
|
||||
|
||||
/**
|
||||
* Pointers to treestore elements, grouped by (id, type, nr)
|
||||
* in hashtable for faster searching */
|
||||
void *treehash;
|
||||
|
||||
SpaceOutliner_Runtime *runtime;
|
||||
} SpaceOutliner;
|
||||
|
||||
|
|
Loading…
Reference in New Issue