diff options
author | Jacques Lucke <jacques@blender.org> | 2021-10-18 12:40:00 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-10-18 12:46:21 +0300 |
commit | eb0d216dc1caab515eb7cf1ef6bb1632e5ca8fae (patch) | |
tree | 59e9f61142052255df5680d34d93fe8271251ec3 /source/blender/nodes/NOD_multi_function.hh | |
parent | 746ee29d3638402e2435f47787087b6458f026c7 (diff) |
Geometry Nodes: decouple multi-function lifetimes from modifier
Previously, some multi-functions were allocated in a resource scope.
This was fine as long as the multi-functions were only needed during
the current evaluation of the node tree. However, now cases arise
that require the multi-functions to be alive after the modifier is finished.
For example, we want to evaluate fields created with geometry nodes
outside of geometry nodes.
To make this work, `std::shared_ptr` has to be used in a few more places.
Realistically, this shouldn't have a noticable impact on performance.
If this does become a bottleneck in the future, we can think about ways
to make this work without using `shared_ptr` for multi-functions that
are only used once.
Diffstat (limited to 'source/blender/nodes/NOD_multi_function.hh')
-rw-r--r-- | source/blender/nodes/NOD_multi_function.hh | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/source/blender/nodes/NOD_multi_function.hh b/source/blender/nodes/NOD_multi_function.hh index c1952cf8014..367ceaab9f7 100644 --- a/source/blender/nodes/NOD_multi_function.hh +++ b/source/blender/nodes/NOD_multi_function.hh @@ -33,15 +33,15 @@ class NodeMultiFunctions; */ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { private: - ResourceScope &resource_scope_; bNode &node_; bNodeTree &tree_; + std::shared_ptr<MultiFunction> owned_built_fn_; const MultiFunction *built_fn_ = nullptr; friend NodeMultiFunctions; public: - NodeMultiFunctionBuilder(ResourceScope &resource_scope, bNode &node, bNodeTree &tree); + NodeMultiFunctionBuilder(bNode &node, bNodeTree &tree); /** * Assign a multi-function for the current node. The input and output parameters of the function @@ -58,31 +58,33 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { bNode &node(); bNodeTree &tree(); - - ResourceScope &resource_scope(); }; /** * Gives access to multi-functions for all nodes in a node tree that support them. */ class NodeMultiFunctions { + public: + struct Item { + const MultiFunction *fn = nullptr; + std::shared_ptr<MultiFunction> owned_fn; + }; + private: - Map<const bNode *, const MultiFunction *> map_; + Map<const bNode *, Item> map_; public: - NodeMultiFunctions(const DerivedNodeTree &tree, ResourceScope &resource_scope); + NodeMultiFunctions(const DerivedNodeTree &tree); - const MultiFunction *try_get(const DNode &node) const; + const Item &try_get(const DNode &node) const; }; /* -------------------------------------------------------------------- */ /** \name #NodeMultiFunctionBuilder Inline Methods * \{ */ -inline NodeMultiFunctionBuilder::NodeMultiFunctionBuilder(ResourceScope &resource_scope, - bNode &node, - bNodeTree &tree) - : resource_scope_(resource_scope), node_(node), tree_(tree) +inline NodeMultiFunctionBuilder::NodeMultiFunctionBuilder(bNode &node, bNodeTree &tree) + : node_(node), tree_(tree) { } @@ -96,11 +98,6 @@ inline bNodeTree &NodeMultiFunctionBuilder::tree() return tree_; } -inline ResourceScope &NodeMultiFunctionBuilder::resource_scope() -{ - return resource_scope_; -} - inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn) { built_fn_ = fn; @@ -108,14 +105,14 @@ inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn) inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction &fn) { - this->set_matching_fn(&fn); + built_fn_ = &fn; } template<typename T, typename... Args> inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn(Args &&...args) { - const T &fn = resource_scope_.construct<T>(std::forward<Args>(args)...); - this->set_matching_fn(&fn); + owned_built_fn_ = std::make_shared<T>(std::forward<Args>(args)...); + built_fn_ = &*owned_built_fn_; } /** \} */ @@ -124,9 +121,14 @@ inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn(Args &&...ar /** \name #NodeMultiFunctions Inline Methods * \{ */ -inline const MultiFunction *NodeMultiFunctions::try_get(const DNode &node) const +inline const NodeMultiFunctions::Item &NodeMultiFunctions::try_get(const DNode &node) const { - return map_.lookup_default(node->bnode(), nullptr); + static Item empty_item; + const Item *item = map_.lookup_ptr(node->bnode()); + if (item == nullptr) { + return empty_item; + } + return *item; } /** \} */ |