Cleanup: Simplify node editor link dragging storage

Now that `node_intern.hh` is a C++ header, we can use C++ types
there. This patch replaces the linked list of dragged links with a
vector. Also, the list of drag operator custom data, `nldrag`, doesn't
seem to need to be a list at all, so I just made it a unique pointer.

Differential Revision: https://developer.blender.org/D13252
This commit is contained in:
Hans Goudey 2021-11-19 15:36:32 -05:00
parent c3fed4d463
commit 51a7961e09
4 changed files with 44 additions and 71 deletions

View File

@ -2116,15 +2116,15 @@ static void count_multi_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
}
}
/* Count temporary links going into this socket. */
LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
if (snode->runtime->linkdrag) {
for (const bNodeLink *link : snode->runtime->linkdrag->links) {
if (link->tosock && (link->tosock->flag & SOCK_MULTI_INPUT)) {
int &count = counts.lookup_or_add(link->tosock, 0);
count++;
}
}
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
if (socket->flag & SOCK_MULTI_INPUT) {
@ -2383,9 +2383,9 @@ void node_draw_space(const bContext *C, ARegion *region)
/* Temporary links. */
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
node_draw_link(C, v2d, snode, (bNodeLink *)linkdata->data);
if (snode->runtime->linkdrag) {
for (const bNodeLink *link : snode->runtime->linkdrag->links) {
node_draw_link(C, v2d, snode, link);
}
}
GPU_line_smooth(false);

View File

@ -49,13 +49,8 @@ struct wmWindow;
/* temp data to pass on to modal */
struct bNodeLinkDrag {
struct bNodeLinkDrag *next, *prev;
/* List of links dragged by the operator.
* NOTE: This is a list of LinkData structs on top of the actual bNodeLinks.
* This way the links can be added to the node tree while being stored in this list.
*/
ListBase links;
/** Links dragged by the operator. */
blender::Vector<bNodeLink *> links;
bool from_multi_input_socket;
int in_out;
@ -80,7 +75,7 @@ struct SpaceNode_Runtime {
bool recalc;
/** Temporary data for modal linking operator. */
struct ListBase linkdrag;
std::unique_ptr<bNodeLinkDrag> linkdrag;
/* XXX hack for translate_attach op-macros to pass data from transform op to insert_offset op */
/** Temporary data for node insert offset (in UI called Auto-offset). */

View File

@ -207,11 +207,9 @@ static void clear_picking_highlight(ListBase *links)
}
}
static LinkData *create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bNodeSocket *sock)
static bNodeLink *create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bNodeSocket *sock)
{
LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
if (sock->in_out == SOCK_OUT) {
oplink->fromnode = node;
oplink->fromsock = sock;
@ -226,7 +224,7 @@ static LinkData *create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bN
oplink->flag |= NODE_LINK_TEST;
}
oplink->flag |= NODE_LINK_DRAGGED;
return linkdata;
return oplink;
}
static void pick_link(const bContext *C,
@ -240,10 +238,9 @@ static void pick_link(const bContext *C,
RNA_boolean_set(op->ptr, "has_link_picked", true);
Main *bmain = CTX_data_main(C);
LinkData *linkdata = create_drag_link(
bmain, snode, link_to_pick->fromnode, link_to_pick->fromsock);
bNodeLink *link = create_drag_link(bmain, snode, link_to_pick->fromnode, link_to_pick->fromsock);
BLI_addtail(&nldrag->links, linkdata);
nldrag->links.append(link);
nodeRemLink(snode->edittree, link_to_pick);
BLI_assert(nldrag->last_node_hovered_while_dragging_a_link != nullptr);
@ -1013,9 +1010,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
/* avoid updates while applying links */
ntree->is_updating = true;
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
for (bNodeLink *link : nldrag->links) {
/* See note below, but basically TEST flag means that the link
* was connected to output (or to a node which affects the
* output).
@ -1068,10 +1063,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
UI_view2d_edge_pan_cancel(C, &nldrag->pan_data);
}
BLI_remlink(&snode->runtime->linkdrag, nldrag);
/* links->data pointers are either held by the tree or freed already */
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
snode->runtime->linkdrag.reset();
}
static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
@ -1083,9 +1075,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
bNode *tnode;
bNodeSocket *tsock = nullptr;
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
for (bNodeLink *link : nldrag->links) {
/* skip if socket is on the same node as the fromsock */
if (tnode && link->fromnode == tnode) {
continue;
@ -1115,8 +1105,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
}
else {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
for (bNodeLink *link : nldrag->links) {
if (nldrag->last_node_hovered_while_dragging_a_link) {
sort_multi_input_socket_links(
snode, nldrag->last_node_hovered_while_dragging_a_link, nullptr, cursor);
@ -1130,9 +1119,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
bNode *tnode;
bNodeSocket *tsock = nullptr;
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
for (bNodeLink *link : nldrag->links) {
/* skip if this is already the target socket */
if (link->fromsock == tsock) {
continue;
@ -1148,9 +1135,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
}
}
else {
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
bNodeLink *link = (bNodeLink *)linkdata->data;
for (bNodeLink *link : nldrag->links) {
link->fromnode = nullptr;
link->fromsock = nullptr;
}
@ -1202,16 +1187,16 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
/* return 1 when socket clicked */
static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor[2], bool detach)
static std::unique_ptr<bNodeLinkDrag> node_link_init(Main *bmain,
SpaceNode *snode,
float cursor[2],
bool detach)
{
bNodeLinkDrag *nldrag = nullptr;
/* output indicated? */
bNode *node;
bNodeSocket *sock;
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
nldrag = (bNodeLinkDrag *)MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
std::unique_ptr<bNodeLinkDrag> nldrag = std::make_unique<bNodeLinkDrag>();
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
int link_limit = nodeSocketLinkLimit(sock);
@ -1221,9 +1206,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* detach current links and store them in the operator data */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode->edittree->links) {
if (link->fromsock == sock) {
LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
*oplink = *link;
oplink->next = oplink->prev = nullptr;
oplink->flag |= NODE_LINK_VALID;
@ -1240,7 +1223,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
oplink->flag |= NODE_LINK_TEST;
}
BLI_addtail(&nldrag->links, linkdata);
nldrag->links.append(oplink);
nodeRemLink(snode->edittree, link);
}
}
@ -1249,14 +1232,14 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on output side */
nldrag->in_out = SOCK_OUT;
/* create a new link */
LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
nldrag->links.append(create_drag_link(bmain, snode, node, sock));
}
return nldrag;
}
/* or an input? */
else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
nldrag = (bNodeLinkDrag *)MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) {
std::unique_ptr<bNodeLinkDrag> nldrag = std::make_unique<bNodeLinkDrag>();
nldrag->last_node_hovered_while_dragging_a_link = node;
const int num_links = nodeCountSocketLinks(snode->edittree, sock);
@ -1275,9 +1258,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
}
if (link_to_pick != nullptr && !nldrag->from_multi_input_socket) {
LinkData *linkdata = (LinkData *)MEM_callocN(sizeof(LinkData), "drag link op link data");
bNodeLink *oplink = (bNodeLink *)MEM_callocN(sizeof(bNodeLink), "drag link op link");
linkdata->data = oplink;
*oplink = *link_to_pick;
oplink->next = oplink->prev = nullptr;
oplink->flag |= NODE_LINK_VALID;
@ -1287,7 +1268,7 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
oplink->flag |= NODE_LINK_TEST;
}
BLI_addtail(&nldrag->links, linkdata);
nldrag->links.append(oplink);
nodeRemLink(snode->edittree, link_to_pick);
/* send changed event to original link->tonode */
@ -1300,13 +1281,12 @@ static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor
/* dragged links are fixed on input side */
nldrag->in_out = SOCK_IN;
/* create a new link */
LinkData *linkdata = create_drag_link(bmain, snode, node, sock);
BLI_addtail(&nldrag->links, linkdata);
nldrag->links.append(create_drag_link(bmain, snode, node, sock));
}
return nldrag;
}
return nldrag;
return {};
}
static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@ -1324,13 +1304,13 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
bNodeLinkDrag *nldrag = node_link_init(bmain, snode, cursor, detach);
std::unique_ptr<bNodeLinkDrag> nldrag = node_link_init(bmain, snode, cursor, detach);
if (nldrag) {
UI_view2d_edge_pan_operator_init(C, &nldrag->pan_data, op);
op->customdata = nldrag;
BLI_addtail(&snode->runtime->linkdrag, nldrag);
snode->runtime->linkdrag = std::move(nldrag);
op->customdata = snode->runtime->linkdrag.get();
/* add modal handler */
WM_event_add_modal_handler(C, op);
@ -1345,12 +1325,10 @@ static void node_link_cancel(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata;
BLI_remlink(&snode->runtime->linkdrag, nldrag);
UI_view2d_edge_pan_cancel(C, &nldrag->pan_data);
BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
snode->runtime->linkdrag.reset();
clear_picking_highlight(&snode->edittree->links);
}

View File

@ -303,7 +303,10 @@ static void node_free(SpaceLink *sl)
MEM_freeN(path);
}
MEM_SAFE_FREE(snode->runtime);
if (snode->runtime) {
snode->runtime->linkdrag.reset();
MEM_freeN(snode->runtime);
}
}
/* spacetype; init callback */
@ -534,10 +537,7 @@ static SpaceLink *node_duplicate(SpaceLink *sl)
BLI_duplicatelist(&snoden->treepath, &snode->treepath);
if (snode->runtime != nullptr) {
snoden->runtime = (SpaceNode_Runtime *)MEM_dupallocN(snode->runtime);
BLI_listbase_clear(&snoden->runtime->linkdrag);
}
snoden->runtime = nullptr;
/* NOTE: no need to set node tree user counts,
* the editor only keeps at least 1 (id_us_ensure_real),