From 172a5d4d8c820832cf2865e21f48880b4a37cde9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 22 Sep 2023 08:16:19 -0400 Subject: [PATCH] Cleanup: Use StringRef for node interface, avoid 0 size allocations --- .../blenkernel/BKE_node_tree_interface.hh | 36 +++----- .../blenkernel/intern/node_tree_interface.cc | 83 +++++++++++++------ .../makesdna/DNA_node_tree_interface_types.h | 20 ++--- .../intern/rna_node_tree_interface.cc | 7 +- 4 files changed, 80 insertions(+), 66 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_tree_interface.hh b/source/blender/blenkernel/BKE_node_tree_interface.hh index d1db4be6ce7..48e48f9e7b0 100644 --- a/source/blender/blenkernel/BKE_node_tree_interface.hh +++ b/source/blender/blenkernel/BKE_node_tree_interface.hh @@ -208,10 +208,10 @@ template bool socket_data_to_static_type(const eNodeSocketDatatype return false; } -template bool socket_data_to_static_type(const char *socket_type, const Fn &fn) +template bool socket_data_to_static_type(const StringRef socket_type, const Fn &fn) { for (const bNodeSocketStaticTypeInfo &info : node_socket_subtypes) { - if (STREQ(socket_type, info.socket_identifier)) { + if (socket_type == info.socket_identifier) { return socket_data_to_static_type(info.type, fn); } } @@ -233,7 +233,8 @@ template struct TypeTagExecutor { } // namespace detail -template void socket_data_to_static_type_tag(const char *socket_type, const Fn &fn) +template +void socket_data_to_static_type_tag(const StringRef socket_type, const Fn &fn) { detail::TypeTagExecutor executor{fn}; socket_data_to_static_type(socket_type, executor); @@ -263,33 +264,16 @@ template const T &get_socket_data_as(const bNodeTreeInterfaceSocket return *static_cast(item.socket_data); } -inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree, - const bNode &from_node, - const bNodeSocket &from_sock, - const StringRefNull socket_type, - const StringRefNull name) -{ - NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0); - SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT); - SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT); - - bNodeTreeInterfaceSocket *iosock = ntree.tree_interface.add_socket( - name.data(), from_sock.description, socket_type, flag, nullptr); - if (iosock == nullptr) { - return nullptr; - } - const bNodeSocketType *typeinfo = iosock->socket_typeinfo(); - if (typeinfo->interface_from_socket) { - typeinfo->interface_from_socket(&ntree.id, iosock, &from_node, &from_sock); - UNUSED_VARS(from_sock); - } - return iosock; -} +bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree, + const bNode &from_node, + const bNodeSocket &from_sock, + const StringRef socket_type, + const StringRef name); inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree, const bNode &from_node, const bNodeSocket &from_sock, - const StringRefNull socket_type) + const StringRef socket_type) { return add_interface_socket_from_node(ntree, from_node, from_sock, socket_type, from_sock.name); } diff --git a/source/blender/blenkernel/intern/node_tree_interface.cc b/source/blender/blenkernel/intern/node_tree_interface.cc index 81f3760ce11..e77c92a69da 100644 --- a/source/blender/blenkernel/intern/node_tree_interface.cc +++ b/source/blender/blenkernel/intern/node_tree_interface.cc @@ -38,9 +38,11 @@ namespace socket_types { * `NodeSocketFloatUnsigned`, `NodeSocketFloatFactor`. Only the "base type" (`NodeSocketFloat`) * is considered valid for interface sockets. */ -static const char *try_get_supported_socket_type(StringRefNull socket_type) +static const char *try_get_supported_socket_type(const StringRef socket_type) { - const bNodeSocketType *typeinfo = nodeSocketTypeFind(socket_type.c_str()); + /* Make a copy of the string for `.c_str()` until the socket type map uses C++ types. */ + const std::string idname(socket_type); + const bNodeSocketType *typeinfo = nodeSocketTypeFind(idname.c_str()); if (typeinfo == nullptr) { return nullptr; } @@ -170,7 +172,7 @@ template<> void socket_data_init_impl(bNodeSocketValueMaterial &data) data.value = nullptr; } -static void *make_socket_data(const char *socket_type) +static void *make_socket_data(const StringRef socket_type) { void *socket_data = nullptr; socket_data_to_static_type_tag(socket_type, [&socket_data](auto type_tag) { @@ -981,16 +983,18 @@ void bNodeTreeInterfacePanel::foreach_item( } } +namespace blender::bke::node_interface { + static bNodeTreeInterfaceSocket *make_socket(const int uid, - blender::StringRefNull name, - blender::StringRefNull description, - blender::StringRefNull socket_type, + const StringRef name, + const StringRef description, + const StringRef socket_type, const NodeTreeInterfaceSocketFlag flag) { BLI_assert(name.c_str() != nullptr); BLI_assert(socket_type.c_str() != nullptr); - const char *idname = socket_types::try_get_supported_socket_type(socket_type.c_str()); + const char *idname = socket_types::try_get_supported_socket_type(socket_type); if (idname == nullptr) { return nullptr; } @@ -1001,32 +1005,61 @@ static bNodeTreeInterfaceSocket *make_socket(const int uid, /* Init common socket properties. */ new_socket->identifier = BLI_sprintfN("Socket_%d", uid); new_socket->item.item_type = NODE_INTERFACE_SOCKET; - new_socket->name = BLI_strdup(name.c_str()); - new_socket->description = BLI_strdup_null(description.c_str()); - new_socket->socket_type = BLI_strdup(socket_type.c_str()); + new_socket->name = BLI_strdupn(name.data(), name.size()); + new_socket->description = description.is_empty() ? + nullptr : + BLI_strdupn(description.data(), description.size()); + new_socket->socket_type = BLI_strdupn(socket_type.data(), socket_type.size()); new_socket->flag = flag; - new_socket->socket_data = socket_types::make_socket_data(socket_type.c_str()); + new_socket->socket_data = socket_types::make_socket_data(socket_type); return new_socket; } +bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree, + const bNode &from_node, + const bNodeSocket &from_sock, + const StringRef socket_type, + const StringRef name) +{ + NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0); + SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT); + SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT); + + bNodeTreeInterfaceSocket *iosock = ntree.tree_interface.add_socket( + name, from_sock.description, socket_type, flag, nullptr); + if (iosock == nullptr) { + return nullptr; + } + const bNodeSocketType *typeinfo = iosock->socket_typeinfo(); + if (typeinfo->interface_from_socket) { + typeinfo->interface_from_socket(&ntree.id, iosock, &from_node, &from_sock); + UNUSED_VARS(from_sock); + } + return iosock; +} + static bNodeTreeInterfacePanel *make_panel(const int uid, - blender::StringRefNull name, - blender::StringRefNull description, + const blender::StringRef name, + const blender::StringRef description, const NodeTreeInterfacePanelFlag flag) { BLI_assert(name.c_str() != nullptr); bNodeTreeInterfacePanel *new_panel = MEM_cnew(__func__); new_panel->item.item_type = NODE_INTERFACE_PANEL; - new_panel->name = BLI_strdup(name.c_str()); - new_panel->description = BLI_strdup_null(description.c_str()); + new_panel->name = BLI_strdupn(name.data(), name.size()); + new_panel->description = description.is_empty() ? + nullptr : + BLI_strdupn(description.data(), description.size()); new_panel->identifier = uid; new_panel->flag = flag; return new_panel; } +} // namespace blender::bke::node_interface + void bNodeTreeInterface::init_data() { this->runtime = MEM_new(__func__); @@ -1112,9 +1145,9 @@ void bNodeTreeInterface::active_item_set(bNodeTreeInterfaceItem *item) }); } -bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(blender::StringRefNull name, - blender::StringRefNull description, - blender::StringRefNull socket_type, +bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(const blender::StringRef name, + const blender::StringRef description, + const blender::StringRef socket_type, const NodeTreeInterfaceSocketFlag flag, bNodeTreeInterfacePanel *parent) { @@ -1133,9 +1166,9 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::add_socket(blender::StringRefNull return new_socket; } -bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(blender::StringRefNull name, - blender::StringRefNull description, - blender::StringRefNull socket_type, +bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(const blender::StringRef name, + const blender::StringRef description, + const blender::StringRef socket_type, const NodeTreeInterfaceSocketFlag flag, bNodeTreeInterfacePanel *parent, const int position) @@ -1155,8 +1188,8 @@ bNodeTreeInterfaceSocket *bNodeTreeInterface::insert_socket(blender::StringRefNu return new_socket; } -bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull name, - blender::StringRefNull description, +bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(const blender::StringRef name, + const blender::StringRef description, const NodeTreeInterfacePanelFlag flag, bNodeTreeInterfacePanel *parent) { @@ -1179,8 +1212,8 @@ bNodeTreeInterfacePanel *bNodeTreeInterface::add_panel(blender::StringRefNull na return new_panel; } -bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(blender::StringRefNull name, - blender::StringRefNull description, +bNodeTreeInterfacePanel *bNodeTreeInterface::insert_panel(const blender::StringRef name, + const blender::StringRef description, const NodeTreeInterfacePanelFlag flag, bNodeTreeInterfacePanel *parent, const int position) diff --git a/source/blender/makesdna/DNA_node_tree_interface_types.h b/source/blender/makesdna/DNA_node_tree_interface_types.h index 7d8f1e961b2..4c26101438b 100644 --- a/source/blender/makesdna/DNA_node_tree_interface_types.h +++ b/source/blender/makesdna/DNA_node_tree_interface_types.h @@ -303,9 +303,9 @@ typedef struct bNodeTreeInterface { * \param parent: Panel in which to add the socket. If parent is null the socket is added in the * root panel. */ - bNodeTreeInterfaceSocket *add_socket(blender::StringRefNull name, - blender::StringRefNull description, - blender::StringRefNull socket_type, + bNodeTreeInterfaceSocket *add_socket(blender::StringRef name, + blender::StringRef description, + blender::StringRef socket_type, NodeTreeInterfaceSocketFlag flag, bNodeTreeInterfacePanel *parent); /** @@ -314,9 +314,9 @@ typedef struct bNodeTreeInterface { * root panel. * \param position: Position of the socket within the parent panel. */ - bNodeTreeInterfaceSocket *insert_socket(blender::StringRefNull name, - blender::StringRefNull description, - blender::StringRefNull socket_type, + bNodeTreeInterfaceSocket *insert_socket(blender::StringRef name, + blender::StringRef description, + blender::StringRef socket_type, NodeTreeInterfaceSocketFlag flag, bNodeTreeInterfacePanel *parent, int position); @@ -326,8 +326,8 @@ typedef struct bNodeTreeInterface { * \param parent: Panel in which the new panel is added as a child. If parent is null the new * panel is made a child of the root panel. */ - bNodeTreeInterfacePanel *add_panel(blender::StringRefNull name, - blender::StringRefNull description, + bNodeTreeInterfacePanel *add_panel(blender::StringRef name, + blender::StringRef description, NodeTreeInterfacePanelFlag flag, bNodeTreeInterfacePanel *parent); /** @@ -336,8 +336,8 @@ typedef struct bNodeTreeInterface { * panel is made a child of the root panel. * \param position: Position of the child panel within the parent panel. */ - bNodeTreeInterfacePanel *insert_panel(blender::StringRefNull name, - blender::StringRefNull description, + bNodeTreeInterfacePanel *insert_panel(blender::StringRef name, + blender::StringRef description, NodeTreeInterfacePanelFlag flag, bNodeTreeInterfacePanel *parent, int position); diff --git a/source/blender/makesrna/intern/rna_node_tree_interface.cc b/source/blender/makesrna/intern/rna_node_tree_interface.cc index 331946ffe50..4ea2a0b103a 100644 --- a/source/blender/makesrna/intern/rna_node_tree_interface.cc +++ b/source/blender/makesrna/intern/rna_node_tree_interface.cc @@ -439,11 +439,8 @@ static bNodeTreeInterfaceSocket *rna_NodeTreeInterfaceItems_new_socket( } const char *socket_type = typeinfo->idname; NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(in_out); - bNodeTreeInterfaceSocket *socket = interface->add_socket(name ? name : "", - description ? description : "", - socket_type ? socket_type : "", - flag, - parent); + bNodeTreeInterfaceSocket *socket = interface->add_socket( + name, description, socket_type, flag, parent); if (socket == nullptr) { BKE_report(reports, RPT_ERROR, "Unable to create socket"); -- 2.30.2