Nodes: unify static and dynamic declarations #113742

Merged
Jacques Lucke merged 2 commits from JacquesLucke/blender:unify-declarations into main 2023-10-15 20:28:32 +02:00
35 changed files with 178 additions and 134 deletions

View File

@ -362,17 +362,22 @@ typedef struct bNodeType {
/* Execute a geometry node. */
NodeGeometryExecFunction geometry_node_execute;
/* Declares which sockets the node has. */
NodeDeclareFunction declare;
/**
* Declare which sockets the node has for declarations that aren't static per node type.
* In other words, defining this callback means that different nodes of this type can have
* different declarations and different sockets.
* Declares which sockets and panels the node has. It has to be able to generate a declaration
* with and without a specific node context. If the declaration depends on the node, but the node
* is not provided, then the declaration should be generated as much as possible and everything
* that depends on the node context should be skipped.
*/
NodeDeclareDynamicFunction declare_dynamic;
NodeDeclareFunction declare;
/* Declaration to be used when it is not dynamic. */
NodeDeclarationHandle *fixed_declaration;
/**
* Declaration of the node outside of any context. If the node declaration is never dependent on
* the node context, this declaration is also shared with the corresponding node instances.
* Otherwise, it mainly allows checking what sockets a node will have, without having to create
* the node. In this case, the static declaration is mostly just a hint, and does not have to
* match with the final node.
*/
NodeDeclarationHandle *static_declaration;
/**
* Add to the list of search names and operations gathered by node link drag searching.

View File

@ -1153,7 +1153,7 @@ namespace blender::bke {
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
{
if (ntype->declare || ntype->declare_dynamic) {
if (ntype->declare) {
node_verify_sockets(ntree, node, true);
return;
}
@ -1455,8 +1455,8 @@ static void node_free_type(void *nodetype_v)
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
blender::bke::update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
delete nodetype->fixed_declaration;
nodetype->fixed_declaration = nullptr;
delete nodetype->static_declaration;
nodetype->static_declaration = nullptr;
/* Can be null when the type is not dynamically allocated. */
if (nodetype->free_self) {
@ -1470,11 +1470,9 @@ void nodeRegisterType(bNodeType *nt)
BLI_assert(nt->idname[0] != '\0');
BLI_assert(nt->poll != nullptr);
if (nt->declare && !nt->declare_dynamic) {
if (nt->fixed_declaration == nullptr) {
nt->fixed_declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration);
}
if (nt->declare) {
nt->static_declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration(*nt, *nt->static_declaration, nullptr, nullptr);
}
BLI_ghash_insert(blender::bke::nodetypes_hash, nt->idname, nt);
@ -3268,8 +3266,12 @@ void node_free_node(bNodeTree *ntree, bNode *node)
MEM_freeN(node->prop);
}
if (node->typeinfo->declare_dynamic) {
delete node->runtime->declaration;
if (node->runtime->declaration) {
/* Only free if this declaration is not shared with the node type, which can happen if it does
* not depend on any context. */
if (node->runtime->declaration != node->typeinfo->static_declaration) {
delete node->runtime->declaration;
}
}
MEM_delete(node->runtime);
@ -3734,18 +3736,20 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
if (node->runtime->declaration != nullptr) {
return false;
}
if (node->typeinfo->declare_dynamic) {
if (node->typeinfo->declare) {
if (node->typeinfo->static_declaration) {
if (!node->typeinfo->static_declaration->is_context_dependent) {
node->runtime->declaration = node->typeinfo->static_declaration;
return true;
}
}
}
if (node->typeinfo->declare) {
BLI_assert(ntree != nullptr);
BLI_assert(node != nullptr);
blender::nodes::update_node_declaration_and_sockets(*ntree, *node);
return true;
}
if (node->typeinfo->declare) {
/* Declaration should have been created in #nodeRegisterType. */
BLI_assert(node->typeinfo->fixed_declaration != nullptr);
node->runtime->declaration = node->typeinfo->fixed_declaration;
return true;
}
return false;
}

View File

@ -563,8 +563,12 @@ class NodeTreeMainUpdater {
if (ntype.updatefunc) {
ntype.updatefunc(&ntree, node);
}
if (ntype.declare_dynamic) {
nodes::update_node_declaration_and_sockets(ntree, *node);
if (ntype.declare) {
/* Should have been created when the node was registered. */
BLI_assert(ntype.static_declaration != nullptr);
if (ntype.static_declaration->is_context_dependent) {
nodes::update_node_declaration_and_sockets(ntree, *node);
}
}
}
}

View File

@ -364,7 +364,7 @@ static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
using namespace blender::nodes;
r_node_decl.emplace(NodeDeclaration());
blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl);
blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl, nullptr, nullptr);
Span<SocketDeclaration *> socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs :
r_node_decl->outputs;
int index = 0;

View File

@ -30,9 +30,7 @@ struct bNodeSocket *node_group_output_find_socket(struct bNode *node, const char
namespace blender::nodes {
void node_group_declare_dynamic(const bNodeTree &node_tree,
const bNode &node,
NodeDeclarationBuilder &b);
void node_group_declare(NodeDeclarationBuilder &b);
} // namespace blender::nodes

View File

@ -469,6 +469,11 @@ class NodeDeclaration {
* outputs | buttons | inputs order. Panels are only supported when using custom socket order. */
bool use_custom_socket_order = false;
/**
* True if any context was used to build this declaration.
*/
bool is_context_dependent = false;
friend NodeDeclarationBuilder;
/** Returns true if the declaration is considered valid. */
@ -488,6 +493,8 @@ class NodeDeclaration {
class NodeDeclarationBuilder {
private:
NodeDeclaration &declaration_;
const bNodeTree *ntree_ = nullptr;
const bNode *node_ = nullptr;
Vector<std::unique_ptr<BaseSocketDeclarationBuilder>> socket_builders_;
Vector<std::unique_ptr<PanelDeclarationBuilder>> panel_builders_;
bool is_function_node_ = false;
@ -496,7 +503,21 @@ class NodeDeclarationBuilder {
friend PanelDeclarationBuilder;
public:
NodeDeclarationBuilder(NodeDeclaration &declaration);
NodeDeclarationBuilder(NodeDeclaration &declaration,
const bNodeTree *ntree = nullptr,
const bNode *node = nullptr);
const bNode *node_or_null() const
{
declaration_.is_context_dependent = true;
return node_;
}
const bNodeTree *tree_or_null() const
{
declaration_.is_context_dependent = true;
return ntree_;
}
/**
* All inputs support fields, and all outputs are fields if any of the inputs is a field.
@ -558,10 +579,10 @@ void index(const bNode &node, void *r_value);
void id_or_index(const bNode &node, void *r_value);
} // namespace implicit_field_inputs
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration);
void build_node_declaration_dynamic(const bNodeTree &node_tree,
const bNode &node,
NodeDeclaration &r_declaration);
void build_node_declaration(const bNodeType &typeinfo,
NodeDeclaration &r_declaration,
const bNodeTree *ntree,
const bNode *node);
std::unique_ptr<SocketDeclaration> make_declaration_for_socket_type(
eNodeSocketDatatype socket_type);

View File

@ -33,7 +33,7 @@ void register_node_type_cmp_group()
blender::bke::node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype.declare = blender::nodes::node_group_declare;
nodeRegisterType(&ntype);
}
@ -47,5 +47,5 @@ void register_node_type_cmp_custom_group(bNodeType *ntype)
if (ntype->insert_link == nullptr) {
ntype->insert_link = node_insert_link_default;
}
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype->declare = blender::nodes::node_group_declare;
}

View File

@ -20,13 +20,17 @@
namespace blender::nodes::node_composite_switchview_cc {
static void node_declare_dynamic(const bNodeTree & /*ntree*/,
const bNode &node,
NodeDeclarationBuilder &b)
static void node_declare(NodeDeclarationBuilder &b)
{
Scene *scene = reinterpret_cast<Scene *>(node.id);
b.add_output<decl::Color>(N_("Image"));
const bNode *node = b.node_or_null();
if (node == nullptr) {
return;
}
Scene *scene = reinterpret_cast<Scene *>(node->id);
if (scene != nullptr) {
/* add the new views */
LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) {
@ -98,7 +102,7 @@ void register_node_type_cmp_switch_view()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SWITCH_VIEW, "Switch View", NODE_CLASS_CONVERTER);
ntype.declare_dynamic = file_ns::node_declare_dynamic;
ntype.declare = file_ns::node_declare;
ntype.draw_buttons_ex = file_ns::node_composit_buts_switch_view_ex;
ntype.initfunc_api = file_ns::init_switch_view;
ntype.get_compositor_operation = file_ns::get_compositor_operation;

View File

@ -107,7 +107,7 @@ static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSoc
static void node_gather_link_search_ops(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;

View File

@ -93,7 +93,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));

View File

@ -125,7 +125,7 @@ static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSoc
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());

View File

@ -86,7 +86,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
const NodeDeclaration &declaration = *node_type.fixed_declaration;
const NodeDeclaration &declaration = *node_type.static_declaration;
/* Weight and Iterations inputs don't change based on the data type. */
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));

View File

@ -52,7 +52,7 @@ static void node_group_declare(const bNodeTree &node_tree,
if (!group) {
return;
}
node_group_declare_dynamic(node_tree, node, b);
node_group_declare(node_tree, node, b);
if (!node.id) {
return;
}
@ -89,7 +89,7 @@ static void register_node_type_geo_group()
blender::bke::node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
ntype.declare_dynamic = node_group_declare;
ntype.declare = node_group_declare;
nodeRegisterType(&ntype);
}
@ -106,5 +106,5 @@ void register_node_type_geo_custom_group(bNodeType *ntype)
if (ntype->insert_link == nullptr) {
ntype->insert_link = node_insert_link_default;
}
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype->declare = blender::nodes::node_group_declare;
}

View File

@ -138,7 +138,7 @@ class SocketSearchOp {
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
if (params.in_out() == SOCK_OUT) {
search_link_ops_for_declarations(params, declaration.outputs);
}

View File

@ -122,7 +122,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(4));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(3));

View File

@ -96,7 +96,7 @@ class SocketSearchOp {
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.outputs);
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));

View File

@ -65,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs);
const bNodeType &node_type = params.node_type();

View File

@ -90,7 +90,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
if (params.in_out() == SOCK_OUT) {
search_link_ops_for_declarations(params, declaration.outputs);
return;

View File

@ -108,7 +108,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(4));

View File

@ -20,14 +20,18 @@ namespace blender::nodes::node_geo_repeat_input_cc {
NODE_STORAGE_FUNCS(NodeGeometryRepeatInput);
static void node_declare_dynamic(const bNodeTree &tree,
const bNode &node,
NodeDeclarationBuilder &b)
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>("Iterations").min(0).default_value(1);
const NodeGeometryRepeatInput &storage = node_storage(node);
const bNode *output_node = tree.node_by_id(storage.output_node_id);
const bNode *node = b.node_or_null();
const bNodeTree *tree = b.tree_or_null();
if (ELEM(nullptr, node, tree)) {
return;
}
const NodeGeometryRepeatInput &storage = node_storage(*node);
const bNode *output_node = tree->node_by_id(storage.output_node_id);
if (output_node == nullptr) {
return;
}
@ -72,7 +76,7 @@ static void node_register()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_REPEAT_INPUT, "Repeat Input", NODE_CLASS_INTERFACE);
ntype.initfunc = node_init;
ntype.declare_dynamic = node_declare_dynamic;
ntype.declare = node_declare;
ntype.gather_link_search_ops = nullptr;
ntype.insert_link = node_insert_link;
node_type_storage(

View File

@ -24,11 +24,13 @@ namespace blender::nodes::node_geo_repeat_output_cc {
NODE_STORAGE_FUNCS(NodeGeometryRepeatOutput);
static void node_declare_dynamic(const bNodeTree & /*node_tree*/,
const bNode &node,
NodeDeclarationBuilder &b)
static void node_declare(NodeDeclarationBuilder &b)
{
const NodeGeometryRepeatOutput &storage = node_storage(node);
const bNode *node = b.node_or_null();
if (node == nullptr) {
return;
}
const NodeGeometryRepeatOutput &storage = node_storage(*node);
for (const int i : IndexRange(storage.items_num)) {
const NodeRepeatItem &item = storage.items[i];
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
@ -86,7 +88,7 @@ static void node_register()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_REPEAT_OUTPUT, "Repeat Output", NODE_CLASS_INTERFACE);
ntype.initfunc = node_init;
ntype.declare_dynamic = node_declare_dynamic;
ntype.declare = node_declare;
ntype.insert_link = node_insert_link;
node_type_storage(&ntype, "NodeGeometryRepeatOutput", node_free_storage, node_copy_storage);
nodeRegisterType(&ntype);

View File

@ -129,7 +129,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));

View File

@ -91,7 +91,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));

View File

@ -100,7 +100,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_back(1));

View File

@ -85,7 +85,7 @@ static void search_link_ops(GatherLinkSearchOpParams &params)
if (!U.experimental.use_new_volume_nodes) {
return;
}
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));

View File

@ -182,19 +182,23 @@ std::unique_ptr<LazyFunction> get_simulation_input_lazy_function(
namespace blender::nodes::node_geo_simulation_input_cc {
static void node_declare_dynamic(const bNodeTree &node_tree,
const bNode &node,
NodeDeclarationBuilder &b)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *output_node = node_tree.node_by_id(node_storage(node).output_node_id);
b.add_output<decl::Float>("Delta Time");
const bNode *node = b.node_or_null();
const bNodeTree *node_tree = b.tree_or_null();
if (ELEM(nullptr, node, node_tree)) {
return;
}
const bNode *output_node = node_tree->node_by_id(node_storage(*node).output_node_id);
if (!output_node) {
return;
}
const auto &output_storage = *static_cast<const NodeGeometrySimulationOutput *>(
output_node->storage);
b.add_output<decl::Float>("Delta Time");
for (const int i : IndexRange(output_storage.items_num)) {
const NodeSimulationItem &item = output_storage.items[i];
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
@ -234,7 +238,7 @@ static void node_register()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SIMULATION_INPUT, "Simulation Input", NODE_CLASS_INTERFACE);
ntype.initfunc = node_init;
ntype.declare_dynamic = node_declare_dynamic;
ntype.declare = node_declare;
ntype.insert_link = node_insert_link;
ntype.gather_link_search_ops = nullptr;
node_type_storage(&ntype,

View File

@ -672,16 +672,19 @@ std::unique_ptr<LazyFunction> get_simulation_output_lazy_function(
namespace blender::nodes::node_geo_simulation_output_cc {
static void node_declare_dynamic(const bNodeTree & /*node_tree*/,
const bNode &node,
NodeDeclarationBuilder &b)
static void node_declare(NodeDeclarationBuilder &b)
{
const NodeGeometrySimulationOutput &storage = node_storage(node);
b.add_input<decl::Bool>("Skip").description(
"Forward the output of the simulation input node directly to the output node and ignore "
"the nodes in the simulation zone");
const bNode *node = b.node_or_null();
if (node == nullptr) {
return;
}
const NodeGeometrySimulationOutput &storage = node_storage(*node);
for (const int i : IndexRange(storage.items_num)) {
const NodeSimulationItem &item = storage.items[i];
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
@ -877,7 +880,7 @@ static void node_register()
geo_node_type_base(
&ntype, GEO_NODE_SIMULATION_OUTPUT, "Simulation Output", NODE_CLASS_INTERFACE);
ntype.initfunc = node_init;
ntype.declare_dynamic = node_declare_dynamic;
ntype.declare = node_declare;
ntype.gather_link_search_ops = nullptr;
ntype.insert_link = node_insert_link;
ntype.draw_buttons_ex = node_layout_ex;

View File

@ -82,7 +82,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));

View File

@ -357,12 +357,14 @@ static PanelDeclarationPtr declaration_for_interface_panel(const bNodeTree & /*n
return dst;
}
void node_group_declare_dynamic(const bNodeTree & /*node_tree*/,
const bNode &node,
NodeDeclarationBuilder &b)
void node_group_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
if (node == nullptr) {
return;
}
NodeDeclaration &r_declaration = b.declaration();
const bNodeTree *group = reinterpret_cast<const bNodeTree *>(node.id);
const bNodeTree *group = reinterpret_cast<const bNodeTree *>(node->id);
if (!group) {
return;
}
@ -606,19 +608,21 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier)
namespace blender::nodes {
static void group_input_declare_dynamic(const bNodeTree &node_tree,
const bNode & /*node*/,
NodeDeclarationBuilder &b)
static void group_input_declare(NodeDeclarationBuilder &b)
{
const bNodeTree *node_tree = b.tree_or_null();
if (node_tree == nullptr) {
return;
}
NodeDeclaration &r_declaration = b.declaration();
node_tree.tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
node_tree->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
const bNodeTreeInterfaceSocket &socket =
node_interface::get_item_as<bNodeTreeInterfaceSocket>(item);
if (socket.flag & NODE_INTERFACE_SOCKET_INPUT) {
SocketDeclarationPtr socket_decl = declaration_for_interface_socket(
node_tree, socket, SOCK_OUT);
*node_tree, socket, SOCK_OUT);
r_declaration.outputs.append(socket_decl.get());
r_declaration.items.append(std::move(socket_decl));
}
@ -632,19 +636,21 @@ static void group_input_declare_dynamic(const bNodeTree &node_tree,
r_declaration.items.append(std::move(extend_decl));
}
static void group_output_declare_dynamic(const bNodeTree &node_tree,
const bNode & /*node*/,
NodeDeclarationBuilder &b)
static void group_output_declare(NodeDeclarationBuilder &b)
{
const bNodeTree *node_tree = b.tree_or_null();
if (node_tree == nullptr) {
return;
}
NodeDeclaration &r_declaration = b.declaration();
node_tree.tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
node_tree->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
const bNodeTreeInterfaceSocket &socket =
node_interface::get_item_as<bNodeTreeInterfaceSocket>(item);
if (socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) {
SocketDeclarationPtr socket_decl = declaration_for_interface_socket(
node_tree, socket, SOCK_IN);
*node_tree, socket, SOCK_IN);
r_declaration.inputs.append(socket_decl.get());
r_declaration.items.append(std::move(socket_decl));
}
@ -710,7 +716,7 @@ void register_node_type_group_input()
blender::bke::node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE);
blender::bke::node_type_size(ntype, 140, 80, 400);
ntype->declare_dynamic = blender::nodes::group_input_declare_dynamic;
ntype->declare = blender::nodes::group_input_declare;
ntype->insert_link = blender::nodes::group_input_insert_link;
nodeRegisterType(ntype);
@ -734,7 +740,7 @@ void register_node_type_group_output()
blender::bke::node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE);
blender::bke::node_type_size(ntype, 140, 80, 400);
ntype->declare_dynamic = blender::nodes::group_output_declare_dynamic;
ntype->declare = blender::nodes::group_output_declare;
ntype->insert_link = blender::nodes::group_output_insert_link;
ntype->no_muting = true;

View File

@ -21,24 +21,17 @@ static void reset_declaration(NodeDeclaration &declaration)
new (&declaration) NodeDeclaration();
}
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration)
void build_node_declaration(const bNodeType &typeinfo,
NodeDeclaration &r_declaration,
const bNodeTree *ntree,
const bNode *node)
{
reset_declaration(r_declaration);
NodeDeclarationBuilder node_decl_builder{r_declaration};
NodeDeclarationBuilder node_decl_builder{r_declaration, ntree, node};
typeinfo.declare(node_decl_builder);
node_decl_builder.finalize();
}
void build_node_declaration_dynamic(const bNodeTree &node_tree,
const bNode &node,
NodeDeclaration &r_declaration)
{
reset_declaration(r_declaration);
NodeDeclarationBuilder node_decl_builder{r_declaration};
node.typeinfo->declare_dynamic(node_tree, node, node_decl_builder);
node_decl_builder.finalize();
}
void NodeDeclarationBuilder::finalize()
{
if (is_function_node_) {
@ -117,8 +110,10 @@ void NodeDeclarationBuilder::finalize()
BLI_assert(declaration_.is_valid());
}
NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration)
: declaration_(declaration)
NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration,
const bNodeTree *ntree,
const bNode *node)
: declaration_(declaration), ntree_(ntree), node_(node)
{
}

View File

@ -578,11 +578,13 @@ static void refresh_node(bNodeTree &ntree,
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
{
if (node.typeinfo->declare_dynamic) {
if (!node.runtime->declaration) {
node.runtime->declaration = new NodeDeclaration();
if (node.typeinfo->declare) {
if (node.typeinfo->static_declaration->is_context_dependent) {
if (!node.runtime->declaration) {
node.runtime->declaration = new NodeDeclaration();
}
build_node_declaration(*node.typeinfo, *node.runtime->declaration, &ntree, &node);
}
build_node_declaration_dynamic(ntree, node, *node.runtime->declaration);
}
refresh_node(ntree, node, *node.runtime->declaration, true);
}
@ -601,7 +603,7 @@ void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
if (ntype == nullptr) {
return;
}
if (ntype->declare || ntype->declare_dynamic) {
if (ntype->declare) {
blender::bke::nodeDeclarationEnsureOnOutdatedNode(ntree, node);
refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user);
return;

View File

@ -141,18 +141,10 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams &params,
void search_link_ops_for_basic_node(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
if (!node_type.declare) {
if (!node_type.static_declaration) {
return;
}
if (node_type.declare_dynamic) {
/* Dynamic declarations aren't supported here, but avoid crashing in release builds. */
BLI_assert_unreachable();
return;
}
const NodeDeclaration &declaration = *node_type.fixed_declaration;
const NodeDeclaration &declaration = *node_type.static_declaration;
search_link_ops_for_declarations(params, declaration.sockets(params.in_out()));
}

View File

@ -97,7 +97,7 @@ void register_node_type_sh_group()
blender::bke::node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype.declare = blender::nodes::node_group_declare;
ntype.gpu_fn = gpu_group_execute;
nodeRegisterType(&ntype);
@ -112,6 +112,6 @@ void register_node_type_sh_custom_group(bNodeType *ntype)
if (ntype->insert_link == nullptr) {
ntype->insert_link = node_insert_link_default;
}
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype->declare = blender::nodes::node_group_declare;
ntype->gpu_fn = gpu_group_execute;
}

View File

@ -286,7 +286,7 @@ static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
const NodeDeclaration &declaration = *params.node_type().static_declaration;
if (params.in_out() == SOCK_OUT) {
search_link_ops_for_declarations(params, declaration.outputs);
return;

View File

@ -156,7 +156,7 @@ void register_node_type_tex_group()
blender::bke::node_type_size(&ntype, 140, 60, 400);
ntype.labelfunc = node_group_label;
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
ntype.declare = blender::nodes::node_group_declare;
ntype.init_exec_fn = group_initexec;
ntype.free_exec_fn = group_freeexec;
ntype.exec_fn = group_execute;