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:
parent
c3fed4d463
commit
51a7961e09
|
@ -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);
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue