[Bf-blender-cvs] [f100fd4609d] node-add-asset-menu: Fix memory leaks
Hans Goudey
noreply at git.blender.org
Thu Oct 6 20:57:52 CEST 2022
Commit: f100fd4609d15a09ae8331c4b26382a53fd33cec
Author: Hans Goudey
Date: Thu Oct 6 13:57:10 2022 -0500
Branches: node-add-asset-menu
https://developer.blender.org/rBf100fd4609d15a09ae8331c4b26382a53fd33cec
Fix memory leaks
The storage is owned by the node editor until the asset system is more complete
===================================================================
M source/blender/editors/space_node/add_menu_assets.cc
M source/blender/editors/space_node/node_intern.hh
M source/blender/editors/space_node/space_node.cc
===================================================================
diff --git a/source/blender/editors/space_node/add_menu_assets.cc b/source/blender/editors/space_node/add_menu_assets.cc
index cf72f00bf79..d20eb635bd3 100644
--- a/source/blender/editors/space_node/add_menu_assets.cc
+++ b/source/blender/editors/space_node/add_menu_assets.cc
@@ -38,6 +38,7 @@ struct LibraryCatalog {
struct AssetItemTree {
bke::AssetCatalogTree catalogs;
MultiValueMap<bke::AssetCatalogPath, LibraryAsset> assets_per_path;
+ Map<const bke::AssetCatalogTreeItem *, bke::AssetCatalogPath> full_catalog_per_tree_item;
};
static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree &node_tree)
@@ -100,13 +101,28 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree &node
}
});
- return {std::move(catalogs_with_node_assets), std::move(assets_per_path)};
+ /* Build another map storing full asset paths for each tree item, in order to have stable
+ * pointers to asset catalog paths to use for context pointers. This is necessary because
+ * #bke::AssetCatalogTreeItem doesn't store its full path directly. */
+ Map<const bke::AssetCatalogTreeItem *, bke::AssetCatalogPath> full_catalog_per_tree_item;
+ catalogs_with_node_assets.foreach_item([&](bke::AssetCatalogTreeItem &item) {
+ full_catalog_per_tree_item.add_new(&item, item.catalog_path());
+ });
+
+ return {std::move(catalogs_with_node_assets),
+ std::move(assets_per_path),
+ std::move(full_catalog_per_tree_item)};
}
static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
{
bScreen &screen = *CTX_wm_screen(C);
const SpaceNode &snode = *CTX_wm_space_node(C);
+ if (!snode.runtime->assets_for_menu) {
+ BLI_assert_unreachable();
+ return;
+ }
+ AssetItemTree &tree = *snode.runtime->assets_for_menu;
const bNodeTree *edit_tree = snode.edittree;
if (!edit_tree) {
return;
@@ -119,7 +135,6 @@ static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
const bke::AssetCatalogPath &menu_path = *static_cast<const bke::AssetCatalogPath *>(
menu_path_ptr.data);
- AssetItemTree tree = build_catalog_tree(*C, *edit_tree);
const Span<LibraryAsset> asset_items = tree.assets_per_path.lookup(menu_path);
bke::AssetCatalogTreeItem *catalog_item = tree.catalogs.find_item(menu_path);
BLI_assert(catalog_item != nullptr);
@@ -137,18 +152,18 @@ static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
&screen.id, &RNA_FileSelectEntry, const_cast<FileDirEntry *>(item.handle.file_data)};
uiLayoutSetContextPointer(row, "active_file", &file);
- PointerRNA library_ptr{
- &screen.id, &RNA_AssetLibraryReference, new AssetLibraryReference(item.library_ref)};
+ PointerRNA library_ptr{&screen.id,
+ &RNA_AssetLibraryReference,
+ const_cast<AssetLibraryReference *>(&item.library_ref)};
uiLayoutSetContextPointer(row, "asset_library_ref", &library_ptr);
uiItemO(row, ED_asset_handle_get_name(&item.handle), ICON_NONE, "NODE_OT_add_group_asset");
}
catalog_item->foreach_child([&](bke::AssetCatalogTreeItem &child_item) {
- const bke::AssetCatalogPath path = child_item.catalog_path();
-
- /* TODO: Where should this memory live? */
- PointerRNA path_ptr{&screen.id, &RNA_AssetCatalogPath, new bke::AssetCatalogPath(path)};
+ const bke::AssetCatalogPath &path = tree.full_catalog_per_tree_item.lookup(&child_item);
+ PointerRNA path_ptr{
+ &screen.id, &RNA_AssetCatalogPath, const_cast<bke::AssetCatalogPath *>(&path)};
uiLayout *row = uiLayoutRow(layout, false);
uiLayoutSetContextPointer(row, "asset_catalog_path", &path_ptr);
uiItemM(row, "NODE_MT_node_add_catalog_assets", path.name().c_str(), ICON_NONE);
@@ -158,10 +173,13 @@ static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
static void add_root_catalogs_draw(const bContext *C, Menu *menu)
{
bScreen &screen = *CTX_wm_screen(C);
- const SpaceNode &snode = *CTX_wm_space_node(C);
+ SpaceNode &snode = *CTX_wm_space_node(C);
const bNodeTree *edit_tree = snode.edittree;
- AssetItemTree tree = build_catalog_tree(*C, *edit_tree);
+ snode.runtime->assets_for_menu.reset();
+ snode.runtime->assets_for_menu = std::make_shared<AssetItemTree>(
+ build_catalog_tree(*C, *edit_tree));
+ AssetItemTree &tree = *snode.runtime->assets_for_menu;
if (tree.catalogs.is_empty()) {
return;
}
@@ -170,10 +188,9 @@ static void add_root_catalogs_draw(const bContext *C, Menu *menu)
uiItemS(layout);
tree.catalogs.foreach_root_item([&](bke::AssetCatalogTreeItem &item) {
- const bke::AssetCatalogPath path = item.catalog_path();
-
- /* TODO: Where should this memory live? */
- PointerRNA path_ptr{&screen.id, &RNA_AssetCatalogPath, new bke::AssetCatalogPath(path)};
+ const bke::AssetCatalogPath &path = tree.full_catalog_per_tree_item.lookup(&item);
+ PointerRNA path_ptr{
+ &screen.id, &RNA_AssetCatalogPath, const_cast<bke::AssetCatalogPath *>(&path)};
uiLayout *row = uiLayoutRow(layout, false);
uiLayoutSetContextPointer(row, "asset_catalog_path", &path_ptr);
uiItemM(row, "NODE_MT_node_add_catalog_assets", path.name().c_str(), ICON_NONE);
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index f4d992f754e..fe32109ed96 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -38,6 +38,8 @@ extern const char *node_context_dir[];
namespace blender::ed::space_node {
+struct AssetItemTree;
+
/** Temporary data used in node link drag modal operator. */
struct bNodeLinkDrag {
/** Links dragged by the operator. */
@@ -96,6 +98,15 @@ struct SpaceNode_Runtime {
/* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
/** Temporary data for node insert offset (in UI called Auto-offset). */
struct NodeInsertOfsData *iofsd;
+
+ /**
+ * Temporary data for node add menu in order to provide longer-term storage for context pointers.
+ * Recreated every time the root menu is opened. In the future this will be replaced with an "all
+ * libraries" cache in the asset system itself.
+ *
+ * Stored with a shared pointer so that it can be forward declared.
+ */
+ std::shared_ptr<AssetItemTree> assets_for_menu;
};
enum NodeResizeDirection {
diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc
index 9ae5b846fd0..5754e77399f 100644
--- a/source/blender/editors/space_node/space_node.cc
+++ b/source/blender/editors/space_node/space_node.cc
@@ -300,7 +300,7 @@ static void node_free(SpaceLink *sl)
if (snode->runtime) {
snode->runtime->linkdrag.reset();
- MEM_freeN(snode->runtime);
+ MEM_delete(snode->runtime);
}
}
More information about the Bf-blender-cvs
mailing list