Cleanup: Various cleanup of node link handling functions
Use LISTBASE_FOREACH macro, rename variables, comment formatting, simplification of logic, etc.
This commit is contained in:
parent
e0a1a2f49d
commit
fd0a0096dd
|
@ -745,14 +745,11 @@ static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
|
|||
ED_workspace_status_text(C, header);
|
||||
}
|
||||
|
||||
static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
|
||||
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
|
||||
{
|
||||
int count = 0;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
if (link->fromsock == sock) {
|
||||
count++;
|
||||
}
|
||||
if (link->tosock == sock) {
|
||||
if (ELEM(socket, link->fromsock, link->tosock)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,24 +239,21 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m
|
|||
/** \name Link Insertion
|
||||
* \{ */
|
||||
|
||||
/* test if two sockets are interchangeable */
|
||||
static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
|
||||
static bool node_link_socket_match(const bNodeSocket *a, const bNodeSocket *b)
|
||||
{
|
||||
/* check if sockets are of the same type */
|
||||
/* Check if sockets are of the same type. */
|
||||
if (a->typeinfo != b->typeinfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* tests if alphabetic prefix matches
|
||||
* this allows for imperfect matches, such as numeric suffixes,
|
||||
* like Color1/Color2
|
||||
*/
|
||||
/* Test if alphabetic prefix matches, allowing for imperfect matches, such as numeric suffixes
|
||||
* like Color1/Color2. */
|
||||
int prefix_len = 0;
|
||||
char *ca = a->name, *cb = b->name;
|
||||
const char *ca = a->name, *cb = b->name;
|
||||
for (; *ca != '\0' && *cb != '\0'; ca++, cb++) {
|
||||
/* end of common prefix? */
|
||||
/* End of common prefix? */
|
||||
if (*ca != *cb) {
|
||||
/* prefix delimited by non-alphabetic char */
|
||||
/* Prefix delimited by non-alphabetic char. */
|
||||
if (isalpha(*ca) || isalpha(*cb)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -267,75 +264,66 @@ static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
|
|||
return prefix_len > 0;
|
||||
}
|
||||
|
||||
static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
|
||||
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
|
||||
{
|
||||
bNodeLink *link;
|
||||
int count = 0;
|
||||
for (link = ntree->links.first; link; link = link->next) {
|
||||
if (link->fromsock == sock) {
|
||||
count++;
|
||||
}
|
||||
if (link->tosock == sock) {
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
if (ELEM(socket, link->fromsock, link->tosock)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Find an eligible socket for linking. */
|
||||
static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur)
|
||||
static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree,
|
||||
bNode *node,
|
||||
bNodeSocket *to_socket)
|
||||
{
|
||||
bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
|
||||
bNodeSocket *sock;
|
||||
bNodeSocket *first = to_socket->in_out == SOCK_IN ? node->inputs.first : node->outputs.first;
|
||||
|
||||
/* Iterate over all sockets of the target node, to find one that matches the same socket type.
|
||||
* The idea behind this is: When a user connects an input to a socket that is
|
||||
* already linked (and if its not an Multi Input Socket), we try to find a replacement socket for
|
||||
* the link that we try to overwrite and connect that previous link to the new socket. */
|
||||
sock = cur->next ? cur->next : first; /* Wrap around the list end. */
|
||||
while (sock != cur) {
|
||||
if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
|
||||
break;
|
||||
/* Wrap around the list end. */
|
||||
bNodeSocket *socket_iter = to_socket->next ? to_socket->next : first;
|
||||
while (socket_iter != to_socket) {
|
||||
if (!nodeSocketIsHidden(socket_iter) && node_link_socket_match(socket_iter, to_socket)) {
|
||||
const int link_count = node_count_links(ntree, socket_iter);
|
||||
/* Add one to account for the new link being added. */
|
||||
if (link_count + 1 <= nodeSocketLinkLimit(socket_iter)) {
|
||||
return socket_iter; /* Found a valid free socket we can swap to. */
|
||||
}
|
||||
}
|
||||
sock = sock->next ? sock->next : first; /* Wrap around the list end. */
|
||||
socket_iter = socket_iter->next ? socket_iter->next : first; /* Wrap around the list end. */
|
||||
}
|
||||
|
||||
if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
|
||||
int link_count = node_count_links(ntree, sock);
|
||||
/* Take +1 into account since we would add a new link. */
|
||||
if (link_count + 1 <= nodeSocketLinkLimit(sock)) {
|
||||
return sock; /* Found a valid free socket we can swap to. */
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The idea behind this is: When a user connects an input to a socket that is
|
||||
* already linked (and if its not an Multi Input Socket), we try to find a replacement socket for
|
||||
* the link that we try to overwrite and connect that previous link to the new socket.
|
||||
*/
|
||||
void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link)
|
||||
{
|
||||
bNodeSocket *sock = link->tosock;
|
||||
bNodeLink *tlink, *tlink_next;
|
||||
bNodeSocket *socket = link->tosock;
|
||||
|
||||
if (node != link->tonode) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
|
||||
bNodeSocket *new_sock;
|
||||
tlink_next = tlink->next;
|
||||
LISTBASE_FOREACH_MUTABLE (bNodeLink *, to_link, &ntree->links) {
|
||||
if (socket == to_link->tosock) {
|
||||
bNodeSocket *new_socket = node_find_linkable_socket(ntree, node, socket);
|
||||
if (new_socket && new_socket != socket) {
|
||||
/* Attempt to redirect the existing link to the new socket. */
|
||||
to_link->tosock = new_socket;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sock != tlink->tosock) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_sock = node_find_linkable_socket(ntree, node, sock);
|
||||
if (new_sock && new_sock != sock) {
|
||||
/* redirect existing link */
|
||||
tlink->tosock = new_sock;
|
||||
}
|
||||
else if (!new_sock) {
|
||||
/* no possible replacement, remove tlink */
|
||||
nodeRemLink(ntree, tlink);
|
||||
tlink = NULL;
|
||||
if (new_socket == NULL) {
|
||||
/* No possible replacement, remove the existing link. */
|
||||
nodeRemLink(ntree, to_link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue