This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/nodes/NOD_multi_function.hh
Jacques Lucke 25e307d725 Nodes: move NodeTreeRef functionality into node runtime data
The purpose of `NodeTreeRef` was to speed up various queries on a read-only
`bNodeTree`. Not that we have runtime data in nodes and sockets, we can also
store the result of some queries there. This has some benefits:
* No need for a read-only separate node tree data structure which increased
  complexity.
* Makes it easier to reuse cached queries in more parts of Blender that can
  benefit from it.

A downside is that we loose some type safety that we got by having different
types for input and output sockets, as well as internal and non-internal links.

This patch also refactors `DerivedNodeTree` so that it does not use
`NodeTreeRef` anymore, but uses `bNodeTree` directly instead.

To provide a convenient API (that is also close to what `NodeTreeRef` has), a
new approach is implemented: `bNodeTree`, `bNode`, `bNodeSocket` and `bNodeLink`
now have C++ methods declared in `DNA_node_types.h` which are implemented in
`BKE_node_runtime.hh`. To make this work, `makesdna` now skips c++ sections when
parsing dna header files.

No user visible changes are expected.

Differential Revision: https://developer.blender.org/D15491
2022-08-31 12:16:13 +02:00

123 lines
2.8 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "FN_multi_function.hh"
#include "DNA_node_types.h"
#include "NOD_derived_node_tree.hh"
namespace blender::nodes {
using namespace fn::multi_function_types;
class NodeMultiFunctions;
/**
* Utility class to help nodes build a multi-function for themselves.
*/
class NodeMultiFunctionBuilder : NonCopyable, NonMovable {
private:
const bNode &node_;
const bNodeTree &tree_;
std::shared_ptr<MultiFunction> owned_built_fn_;
const MultiFunction *built_fn_ = nullptr;
friend NodeMultiFunctions;
public:
NodeMultiFunctionBuilder(const bNode &node, const bNodeTree &tree);
/**
* Assign a multi-function for the current node. The input and output parameters of the function
* have to match the available sockets in the node.
*/
void set_matching_fn(const MultiFunction *fn);
void set_matching_fn(const MultiFunction &fn);
/**
* Utility method for creating and assigning a multi-function when it can't have a static
* lifetime.
*/
template<typename T, typename... Args> void construct_and_set_matching_fn(Args &&...args);
const bNode &node();
const bNodeTree &tree();
};
/**
* 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 *, Item> map_;
public:
NodeMultiFunctions(const DerivedNodeTree &tree);
const Item &try_get(const DNode &node) const;
};
/* -------------------------------------------------------------------- */
/** \name #NodeMultiFunctionBuilder Inline Methods
* \{ */
inline NodeMultiFunctionBuilder::NodeMultiFunctionBuilder(const bNode &node, const bNodeTree &tree)
: node_(node), tree_(tree)
{
}
inline const bNode &NodeMultiFunctionBuilder::node()
{
return node_;
}
inline const bNodeTree &NodeMultiFunctionBuilder::tree()
{
return tree_;
}
inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn)
{
built_fn_ = fn;
}
inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction &fn)
{
built_fn_ = &fn;
}
template<typename T, typename... Args>
inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn(Args &&...args)
{
owned_built_fn_ = std::make_shared<T>(std::forward<Args>(args)...);
built_fn_ = &*owned_built_fn_;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #NodeMultiFunctions Inline Methods
* \{ */
inline const NodeMultiFunctions::Item &NodeMultiFunctions::try_get(const DNode &node) const
{
static Item empty_item;
const Item *item = map_.lookup_ptr(node.bnode());
if (item == nullptr) {
return empty_item;
}
return *item;
}
/** \} */
} // namespace blender::nodes