[Bf-blender-cvs] [da9e50646ce] temp-gpu-image-engine: Cleanup: Simplify node group input and output socket verification

Hans Goudey noreply at git.blender.org
Wed Dec 15 14:37:51 CET 2021


Commit: da9e50646ceb0f6c3fc9ff8fbfc9107746e2759a
Author: Hans Goudey
Date:   Tue Dec 14 10:56:12 2021 -0600
Branches: temp-gpu-image-engine
https://developer.blender.org/rBda9e50646ceb0f6c3fc9ff8fbfc9107746e2759a

Cleanup: Simplify node group input and output socket verification

This commit refactors the way the socket lists for group nodes,
and group input/output nodes are verified to match the group's
interface.

Previously the `bNodeSocket.new_sock` pointer was used to
temporarily mark the new sockets. This made the code confusing
and more complicated than necessary.

Now the old socket list is saved, and sockets are moved directly from
the old list to a new list if they match, or a new socket is created
directly in the new list.

This change is split from D13518, which aims to remove the `new_node`
and `new_sock` pointers. In the future this code might be removed
entirely in favor of using node socket declarations.

Differential Revision: https://developer.blender.org/D13543

===================================================================

M	source/blender/nodes/intern/node_common.cc

===================================================================

diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index 6881145a2ae..c302b1081af 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -32,6 +32,7 @@
 #include "BLI_set.hh"
 #include "BLI_stack.hh"
 #include "BLI_string.h"
+#include "BLI_string_ref.hh"
 #include "BLI_utildefines.h"
 
 #include "BLT_translation.h"
@@ -50,29 +51,30 @@ using blender::Map;
 using blender::MultiValueMap;
 using blender::Set;
 using blender::Stack;
+using blender::StringRef;
 
 /* -------------------------------------------------------------------- */
 /** \name Node Group
  * \{ */
 
-bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
+static bNodeSocket *find_matching_socket(ListBase &sockets, StringRef identifier)
 {
-  LISTBASE_FOREACH (bNodeSocket *, sock, &groupnode->inputs) {
-    if (STREQ(sock->identifier, identifier)) {
-      return sock;
+  LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
+    if (socket->identifier == identifier) {
+      return socket;
     }
   }
   return nullptr;
 }
 
+bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
+{
+  return find_matching_socket(groupnode->inputs, identifier);
+}
+
 bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identifier)
 {
-  LISTBASE_FOREACH (bNodeSocket *, sock, &groupnode->outputs) {
-    if (STREQ(sock->identifier, identifier)) {
-      return sock;
-    }
-  }
-  return nullptr;
+  return find_matching_socket(groupnode->outputs, identifier);
 }
 
 void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
@@ -120,86 +122,81 @@ bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_dis
   return valid;
 }
 
-/* used for both group nodes and interface nodes */
-static bNodeSocket *group_verify_socket(bNodeTree *ntree,
-                                        bNode *gnode,
-                                        const bNodeSocket *interface_socket,
-                                        ListBase *verify_lb,
-                                        eNodeSocketInOut in_out)
+static void add_new_socket_from_interface(bNodeTree &node_tree,
+                                          bNode &node,
+                                          const bNodeSocket &interface_socket,
+                                          const eNodeSocketInOut in_out)
 {
-  bNodeSocket *sock;
+  bNodeSocket *socket = nodeAddSocket(&node_tree,
+                                      &node,
+                                      in_out,
+                                      interface_socket.idname,
+                                      interface_socket.identifier,
+                                      interface_socket.name);
 
-  for (sock = (bNodeSocket *)verify_lb->first; sock; sock = sock->next) {
-    if (STREQ(sock->identifier, interface_socket->identifier)) {
-      break;
-    }
+  if (interface_socket.typeinfo->interface_init_socket) {
+    interface_socket.typeinfo->interface_init_socket(
+        &node_tree, &interface_socket, &node, socket, "interface");
   }
-  if (sock) {
-    strcpy(sock->name, interface_socket->name);
+}
 
-    const int mask = SOCK_HIDE_VALUE;
-    sock->flag = (sock->flag & ~mask) | (interface_socket->flag & mask);
+static void update_socket_to_match_interface(bNodeTree &node_tree,
+                                             bNode &node,
+                                             bNodeSocket &socket_to_update,
+                                             const bNodeSocket &interface_socket)
+{
+  strcpy(socket_to_update.name, interface_socket.name);
 
-    /* Update socket type if necessary */
-    if (sock->typeinfo != interface_socket->typeinfo) {
-      nodeModifySocketType(ntree, gnode, sock, interface_socket->idname);
-      /* Flag the tree to make sure link validity is updated after type changes. */
-      ntree->update |= NTREE_UPDATE_LINKS;
-    }
+  const int mask = SOCK_HIDE_VALUE;
+  socket_to_update.flag = (socket_to_update.flag & ~mask) | (interface_socket.flag & mask);
 
-    if (interface_socket->typeinfo->interface_verify_socket) {
-      interface_socket->typeinfo->interface_verify_socket(
-          ntree, interface_socket, gnode, sock, "interface");
-    }
-  }
-  else {
-    sock = nodeAddSocket(ntree,
-                         gnode,
-                         in_out,
-                         interface_socket->idname,
-                         interface_socket->identifier,
-                         interface_socket->name);
-
-    if (interface_socket->typeinfo->interface_init_socket) {
-      interface_socket->typeinfo->interface_init_socket(
-          ntree, interface_socket, gnode, sock, "interface");
-    }
+  /* Update socket type if necessary */
+  if (socket_to_update.typeinfo != interface_socket.typeinfo) {
+    nodeModifySocketType(&node_tree, &node, &socket_to_update, interface_socket.idname);
+    /* Flag the tree to make sure link validity is updated after type changes. */
+    node_tree.update |= NTREE_UPDATE_LINKS;
   }
 
-  /* remove from list temporarily, to distinguish from orphaned sockets */
-  BLI_remlink(verify_lb, sock);
-
-  return sock;
+  if (interface_socket.typeinfo->interface_verify_socket) {
+    interface_socket.typeinfo->interface_verify_socket(
+        &node_tree, &interface_socket, &node, &socket_to_update, "interface");
+  }
 }
 
-/* used for both group nodes and interface nodes */
-static void group_verify_socket_list(bNodeTree *ntree,
-                                     bNode *gnode,
-                                     ListBase *iosock_lb,
-                                     ListBase *verify_lb,
-                                     eNodeSocketInOut in_out)
+/**
+ * Used for group nodes and group input/output nodes to update the list of input or output sockets
+ * on a node to match the provided interface. Assumes that \a verify_lb is the node's matching
+ * input or output socket list, depending on whether the node is a group input/output or a group
+ * node.
+ */
+static void group_verify_socket_list(bNodeTree &node_tree,
+                                     bNode &node,
+                                     const ListBase &interface_sockets,
+                                     ListBase &verify_lb,
+                                     const eNodeSocketInOut in_out)
 {
-  bNodeSocket *sock, *nextsock;
-
-  /* step by step compare */
-
-  bNodeSocket *iosock = (bNodeSocket *)iosock_lb->first;
-  for (; iosock; iosock = iosock->next) {
-    /* abusing new_sock pointer for verification here! only used inside this function */
-    iosock->new_sock = group_verify_socket(ntree, gnode, iosock, verify_lb, in_out);
-  }
-  /* leftovers are removed */
-  for (sock = (bNodeSocket *)verify_lb->first; sock; sock = nextsock) {
-    nextsock = sock->next;
-    nodeRemoveSocket(ntree, gnode, sock);
-  }
-  /* and we put back the verified sockets */
-  iosock = (bNodeSocket *)iosock_lb->first;
-  for (; iosock; iosock = iosock->next) {
-    if (iosock->new_sock) {
-      BLI_addtail(verify_lb, iosock->new_sock);
-      iosock->new_sock = nullptr;
+  ListBase old_sockets = verify_lb;
+  BLI_listbase_clear(&verify_lb);
+
+  LISTBASE_FOREACH (const bNodeSocket *, interface_socket, &interface_sockets) {
+    bNodeSocket *matching_socket = find_matching_socket(old_sockets, interface_socket->identifier);
+    if (matching_socket) {
+      /* If a socket with the same identifier exists in the previous socket list, update it
+       * with the correct name, type, etc. Then move it from the old list to the new one. */
+      update_socket_to_match_interface(node_tree, node, *matching_socket, *interface_socket);
+      BLI_remlink(&old_sockets, matching_socket);
+      BLI_addtail(&verify_lb, matching_socket);
     }
+    else {
+      /* If there was no socket withe the same identifier already, simply create a new socket
+       * based on the interface socket, which will already add it to the new list. */
+      add_new_socket_from_interface(node_tree, node, *interface_socket, in_out);
+    }
+  }
+
+  /* Remove leftover sockets that didn't match the node group's interface. */
+  LISTBASE_FOREACH_MUTABLE (bNodeSocket *, unused_socket, &old_sockets) {
+    nodeRemoveSocket(&node_tree, &node, unused_socket);
   }
 }
 
@@ -215,8 +212,8 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node)
   }
   else {
     bNodeTree *ngroup = (bNodeTree *)node->id;
-    group_verify_socket_list(ntree, node, &ngroup->inputs, &node->inputs, SOCK_IN);
-    group_verify_socket_list(ntree, node, &ngroup->outputs, &node->outputs, SOCK_OUT);
+    group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN);
+    group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT);
   }
 }
 
@@ -499,7 +496,7 @@ void node_group_input_update(bNodeTree *ntree, bNode *node)
   /* check inputs and outputs, and remove or insert them */
   {
     /* value_in_out inverted for interface nodes to get correct socket value_property */
-    group_verify_socket_list(ntree, node, &ntree->inputs, &node->outputs, SOCK_OUT);
+    group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT);
 
     /* add virtual extension socket */
     nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", "");
@@ -597,7 +594,7 @@ void node_group_output_update(bNodeTree *ntree, bNode *node)
   /* check inputs and outputs, and remove or insert them */
   {
     /* value_in_out inverted for interface nodes to get correct socket value_property */
-    group_verify_socket_list(ntree, node, &ntree->outputs, &node->inputs, SOCK_IN);
+    group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN);
 
     /* add virtual extension socket */
     nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", "");



More information about the Bf-blender-cvs mailing list