Blender V4.3
socket_search_link.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <fmt/format.h>
6
7#include "BLI_set.hh"
8
9#include "BKE_context.hh"
10#include "BKE_node.hh"
11
12#include "UI_interface.hh"
13
14#include "BLT_translation.hh"
15
17#include "NOD_socket.hh"
19
20namespace blender::nodes {
21
22void GatherLinkSearchOpParams::add_item(std::string socket_name,
24 const int weight)
25{
26
27 std::string name = fmt::format("{}{} " UI_MENU_ARROW_SEP " {}",
28 IFACE_(node_type_.ui_name),
29 node_type_.deprecation_notice ? IFACE_(" (Deprecated)") : "",
30 socket_name);
31
32 items_.append({std::move(name), std::move(fn), weight});
33}
34
36{
37 return other_socket_;
38}
39
41{
42 return snode_;
43}
44
46{
47 return node_tree_;
48}
49
51{
52 return node_type_;
53}
54
56{
57 return other_socket_.in_out == SOCK_IN ? SOCK_OUT : SOCK_IN;
58}
59
61{
63 bNodeSocket *new_node_socket = bke::node_find_enabled_socket(new_node, in_out, socket_name);
64 if (new_node_socket == nullptr) {
65 /* If the socket isn't found, some node's search gather functions probably aren't configured
66 * properly. It's likely enough that it's worth avoiding a crash in a release build though. */
68 return;
69 }
70 bke::node_add_link(&node_tree, &new_node, new_node_socket, &node, &socket);
71 if (in_out == SOCK_OUT) {
72 /* If the old socket already contained a value, then transfer it to a new one, from
73 * which this value will get there. */
75 }
76}
77
79{
80 std::string idname_str = idname;
81 bNode *node = bke::node_add_node(&C, &node_tree, idname_str.c_str());
82 BLI_assert(node != nullptr);
83 added_nodes_.append(node);
84 return *node;
85}
86
88{
89 return this->add_node(node_type.idname);
90}
91
93 StringRef socket_name)
94{
96 if (new_node.typeinfo->updatefunc) {
97 new_node.typeinfo->updatefunc(&node_tree, &new_node);
98 }
99 this->connect_available_socket(new_node, socket_name);
100}
101
103 Span<SocketDeclaration *> declarations)
104{
105 const bke::bNodeType &node_type = params.node_type();
106
107 const SocketDeclaration *main_socket = nullptr;
108 Vector<const SocketDeclaration *> connectable_sockets;
109
110 Set<StringRef> socket_names;
111 for (const int i : declarations.index_range()) {
112 const SocketDeclaration &socket = *declarations[i];
113 if (!socket_names.add(socket.name)) {
114 /* Don't add sockets with the same name to the search. Needed to support being called from
115 * #search_link_ops_for_basic_node, which should have "okay" behavior for nodes with
116 * duplicate socket names. */
117 continue;
118 }
119 if (!socket.can_connect(params.other_socket())) {
120 continue;
121 }
122 if (socket.is_default_link_socket || main_socket == nullptr) {
123 /* Either the first connectable or explicitly tagged socket is the main socket. */
124 main_socket = &socket;
125 }
126 connectable_sockets.append(&socket);
127 }
128 for (const int i : connectable_sockets.index_range()) {
129 const SocketDeclaration &socket = *connectable_sockets[i];
130 /* Give non-main sockets a lower weight so that they don't show up at the top of the search
131 * when they are not explicitly searched for. The -1 is used to make sure that the first socket
132 * has a smaller weight than zero so that it does not have the same weight as the main socket.
133 * Negative weights are used to avoid making the highest weight dependent on the number of
134 * sockets. */
135 const int weight = (&socket == main_socket) ? 0 : -1 - i;
136 params.add_item(
137 IFACE_(socket.name.c_str()),
138 [&node_type, &socket](LinkSearchOpParams &params) {
139 bNode &node = params.add_node(node_type);
140 socket.make_available(node);
141 params.update_and_connect_available_socket(node, socket.name);
142 },
143 weight);
144 }
145}
146
148{
149 const bke::bNodeType &node_type = params.node_type();
150 if (!node_type.static_declaration) {
151 return;
152 }
153 const NodeDeclaration &declaration = *node_type.static_declaration;
155}
156
157} // namespace blender::nodes
Main * CTX_data_main(const bContext *C)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define IFACE_(msgid)
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr IndexRange index_range() const
Definition BLI_span.hh:402
void append(const T &value)
IndexRange index_range() const
const bke::bNodeType & node_type() const
void add_item(std::string socket_name, SocketLinkOperation::LinkSocketFn fn, int weight=0)
void connect_available_socket(bNode &new_node, StringRef socket_name)
void update_and_connect_available_socket(bNode &new_node, StringRef socket_name)
Span< SocketDeclaration * > sockets(eNodeSocketInOut in_out) const
virtual bool can_connect(const bNodeSocket &socket) const =0
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
Definition node.cc:2912
bNode * node_add_node(const bContext *C, bNodeTree *ntree, const char *idname)
Definition node.cc:2617
bNodeSocket * node_find_enabled_socket(bNode &node, eNodeSocketInOut in_out, StringRef name)
Definition node.cc:1850
void node_socket_move_default_value(Main &bmain, bNodeTree &tree, bNodeSocket &src, bNodeSocket &dst)
Definition node.cc:2846
void search_link_ops_for_basic_node(GatherLinkSearchOpParams &params)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclaration * > declarations)
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
#define UI_MENU_ARROW_SEP
bNodeTypeHandle * typeinfo
Defines a node type.
Definition BKE_node.hh:218
blender::nodes::NodeDeclaration * static_declaration
Definition BKE_node.hh:356
const char * deprecation_notice
Definition BKE_node.hh:397
std::function< void(LinkSearchOpParams &link_params)> LinkSocketFn