52template<
typename Accessor>
55 ntree.ensure_topology_cache();
56 for (
bNode *node : ntree.nodes_by_type(Accessor::node_idname)) {
70 using ItemT =
typename Accessor::ItemT;
73 ItemT &item = (*ref.
items)[
i];
74 Accessor::destruct_item(&item);
82template<
typename Accessor>
inline void clear(
bNode &node)
95 using ItemT =
typename Accessor::ItemT;
101 Accessor::copy_item((*src_ref.
items)[
i], (*dst_ref.
items)[
i]);
110 if constexpr (Accessor::has_name_validation) {
111 return Accessor::validate_name(name);
122template<
typename Accessor>
124 typename Accessor::ItemT &item,
127 using ItemT =
typename Accessor::ItemT;
130 if constexpr (Accessor::has_type) {
142 if (&item_iter != &item) {
143 if (*Accessor::get_name(item_iter) == name) {
150 default_name.
c_str(),
151 Accessor::unique_name_separator,
158 char **item_name = Accessor::get_name(item);
167 using ItemT =
typename Accessor::ItemT;
170 ItemT *old_items = *
array.items;
171 const int old_items_num = *
array.items_num;
172 const int new_items_num = old_items_num + 1;
175 std::copy_n(old_items, old_items_num, new_items);
176 ItemT &new_item = new_items[old_items_num];
179 *
array.items = new_items;
180 *
array.items_num = new_items_num;
181 if (
array.active_index) {
182 *
array.active_index = old_items_num;
193template<
typename Accessor>
197 using ItemT =
typename Accessor::ItemT;
198 BLI_assert(Accessor::supports_socket_type(socket_type));
200 Accessor::init_with_socket_type_and_name(node, new_item, socket_type, name);
207template<
typename Accessor>
210 using ItemT =
typename Accessor::ItemT;
212 Accessor::init_with_name(node, new_item, name);
219template<
typename Accessor>
inline typename Accessor::ItemT *
add_item(
bNode &node)
221 using ItemT =
typename Accessor::ItemT;
223 Accessor::init(node, new_item);
227template<
typename Accessor>
231 if constexpr (Accessor::has_single_identifier_str) {
232 return Accessor::socket_identifier_for_item(item);
236 return Accessor::input_socket_identifier_for_item(item);
238 return Accessor::output_socket_identifier_for_item(item);
247template<
typename Accessor>
254 using ItemT =
typename Accessor::ItemT;
256 if (link.
tosock == &extend_socket) {
259 else if (link.
fromsock == &extend_socket) {
266 const ItemT *item =
nullptr;
267 if constexpr (Accessor::has_name && Accessor::has_type) {
269 if (!Accessor::supports_socket_type(socket_type)) {
272 std::string name = src_socket->
name;
273 if constexpr (Accessor::has_custom_initial_name) {
274 name = Accessor::custom_initial_name(storage_node, name);
278 else if constexpr (Accessor::has_name && !Accessor::has_type) {
284 if (item ==
nullptr) {
289 if (extend_socket.is_input()) {
297 extend_node,
SOCK_OUT, item_identifier.c_str());
307template<
typename Accessor>
313 const std::optional<StringRef> socket_identifier = std::nullopt)
316 if (link.
fromnode == &extend_node) {
317 possible_extend_socket = link.
fromsock;
319 if (link.
tonode == &extend_node) {
320 possible_extend_socket = link.
tosock;
322 if (possible_extend_socket ==
nullptr) {
325 if (!
STREQ(possible_extend_socket->
idname,
"NodeSocketVirtual")) {
328 if (socket_identifier.has_value()) {
329 if (possible_extend_socket->
identifier != socket_identifier) {
334 ntree, extend_node, *possible_extend_socket, storage_node, link);
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * STRNCPY(char(&dst)[N], const char *src)
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
constexpr const char * c_str() const
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)
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 * add_item_with_socket_type_and_name(bNode &node, const eNodeSocketDatatype socket_type, const char *name)
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)
bool try_add_item_via_extend_socket(bNodeTree &ntree, bNode &extend_node, bNodeSocket &extend_socket, bNode &storage_node, bNodeLink &link)
bNode * find_node_by_item(bNodeTree &ntree, const typename Accessor::ItemT &item)
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_single_identifier_str
static constexpr bool has_name_validation
static constexpr char unique_name_separator