57template<
typename Accessor>
60 ntree.ensure_topology_cache();
61 for (
bNode *node : ntree.nodes_by_type(Accessor::node_idname)) {
71template<
typename Accessor>
77 typename Accessor::ItemT &item = (*
array.items)[
i];
78 if (Accessor::socket_identifier_for_item(item) == identifier) {
90 using ItemT =
typename Accessor::ItemT;
93 ItemT &item = (*ref.
items)[
i];
94 Accessor::destruct_item(&item);
115 using ItemT =
typename Accessor::ItemT;
118 const int items_num = *src_ref.
items_num;
121 Accessor::copy_item((*src_ref.
items)[
i], (*dst_ref.
items)[
i]);
130 if constexpr (Accessor::has_name_validation) {
131 return Accessor::validate_name(
name);
142template<
typename Accessor>
144 typename Accessor::ItemT &item,
147 using ItemT =
typename Accessor::ItemT;
150 std::string
name = value;
151 if constexpr (!Accessor::can_have_empty_name) {
153 if constexpr (Accessor::has_type) {
167 if (&item_iter != &item) {
168 if (*Accessor::get_name(item_iter) ==
name) {
175 Accessor::unique_name_separator,
181 char **item_name = Accessor::get_name(item);
190 using ItemT =
typename Accessor::ItemT;
193 ItemT *old_items = *
array.items;
194 const int old_items_num = *
array.items_num;
195 const int new_items_num = old_items_num + 1;
198 std::copy_n(old_items, old_items_num, new_items);
199 ItemT &new_item = new_items[old_items_num];
202 *
array.items = new_items;
203 *
array.items_num = new_items_num;
204 if (
array.active_index) {
205 *
array.active_index = old_items_num;
218template<
typename Accessor>
224 std::optional<int> dimensions = std::nullopt)
226 using ItemT =
typename Accessor::ItemT;
227 BLI_assert(Accessor::supports_socket_type(socket_type, ntree.
type));
232 if constexpr (Accessor::has_vector_dimensions) {
233 Accessor::init_with_socket_type_and_name(node, new_item, socket_type,
name, dimensions);
236 Accessor::init_with_socket_type_and_name(node, new_item, socket_type,
name);
244template<
typename Accessor>
247 using ItemT =
typename Accessor::ItemT;
249 Accessor::init_with_name(node, new_item,
name);
256template<
typename Accessor>
inline typename Accessor::ItemT *
add_item(
bNode &node)
258 using ItemT =
typename Accessor::ItemT;
260 Accessor::init(node, new_item);
264template<
typename Accessor>
268 if constexpr (Accessor::has_single_identifier_str) {
269 return Accessor::socket_identifier_for_item(item);
273 return Accessor::input_socket_identifier_for_item(item);
275 return Accessor::output_socket_identifier_for_item(item);
283 if (is_supported(linked_type)) {
299template<
typename Accessor>
306 typename Accessor::ItemT **r_new_item =
nullptr)
308 using ItemT =
typename Accessor::ItemT;
310 if (link.
tosock == &extend_socket) {
313 else if (link.
fromsock == &extend_socket) {
320 ItemT *item =
nullptr;
321 if constexpr (Accessor::has_name && Accessor::has_type) {
325 return Accessor::supports_socket_type(type, ntree.
type);
327 if (!added_socket_type) {
330 std::string
name = src_socket->
name;
331 if constexpr (Accessor::has_custom_initial_name) {
332 name = Accessor::custom_initial_name(storage_node,
name);
334 std::optional<int> dimensions = std::nullopt;
339 ntree, storage_node, *added_socket_type,
name.c_str(), dimensions);
341 else if constexpr (Accessor::has_name && !Accessor::has_type) {
347 if (item ==
nullptr) {
355 if (extend_socket.is_input()) {
363 extend_node,
SOCK_OUT, item_identifier.c_str());
374template<
typename Accessor>
380 const std::optional<StringRef> socket_identifier = std::nullopt,
381 typename Accessor::ItemT **r_new_item =
nullptr)
384 if (link.
fromnode == &extend_node) {
385 possible_extend_socket = link.
fromsock;
387 if (link.
tonode == &extend_node) {
388 possible_extend_socket = link.
tosock;
390 if (possible_extend_socket ==
nullptr) {
393 if (!
STREQ(possible_extend_socket->
idname,
"NodeSocketVirtual")) {
396 if (socket_identifier.has_value()) {
397 if (possible_extend_socket->
identifier != socket_identifier) {
402 ntree, extend_node, *possible_extend_socket, storage_node, link, r_new_item);
void BKE_ntree_update_tag_node_property(bNodeTree *ntree, bNode *node)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define UNUSED_VARS_NDEBUG(...)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
std::optional< StringRefNull > node_static_socket_label(int type, int subtype)
Accessor::ItemT & add_item_to_array(bNode &node)
std::optional< eNodeSocketDatatype > get_socket_item_type_to_add(const eNodeSocketDatatype linked_type, const FunctionRef< bool(eNodeSocketDatatype type)> is_supported)
void set_item_name_and_make_unique(bNode &node, typename Accessor::ItemT &item, const char *value)
Accessor::ItemT * add_item_with_name(bNode &node, const char *name)
void destruct_array(bNode &node)
Accessor::ItemT * add_item(bNode &node)
void copy_array(const bNode &src_node, bNode &dst_node)
std::string get_validated_name(const StringRef name)
Accessor::ItemT * find_item_by_identifier(bNode &node, const StringRef identifier)
bNode * find_node_by_item(bNodeTree &ntree, const typename Accessor::ItemT &item)
Accessor::ItemT * add_item_with_socket_type_and_name(bNodeTree &ntree, bNode &node, const eNodeSocketDatatype socket_type, const char *name, std::optional< int > dimensions=std::nullopt)
bool try_add_item_via_extend_socket(bNodeTree &ntree, bNode &extend_node, bNodeSocket &extend_socket, bNode &storage_node, bNodeLink &link, typename Accessor::ItemT **r_new_item=nullptr)
bool try_add_item_via_any_extend_socket(bNodeTree &ntree, bNode &extend_node, bNode &storage_node, bNodeLink &link, const std::optional< StringRef > socket_identifier=std::nullopt, typename Accessor::ItemT **r_new_item=nullptr)
std::string get_socket_identifier(const typename Accessor::ItemT &item, const eNodeSocketInOut in_out)
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
static void unique_name(bNode *node)
static constexpr bool has_custom_initial_name
static constexpr bool has_vector_dimensions
static constexpr bool can_have_empty_name
static constexpr bool has_single_identifier_str
static constexpr bool has_name_validation
static constexpr char unique_name_separator