Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/intern/node.cc28
-rw-r--r--source/blender/makesdna/DNA_node_types.h30
-rw-r--r--source/blender/nodes/NOD_node_declaration.hh2
-rw-r--r--source/blender/nodes/intern/node_socket.cc8
5 files changed, 61 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 9df3d7c544d..d4bc0245a61 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -731,6 +731,8 @@ void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available);
int nodeSocketLinkLimit(const struct bNodeSocket *sock);
+void nodeDeclarationEnsure(struct bNodeTree *ntree, struct bNode *node);
+
/* Node Clipboard */
void BKE_node_clipboard_init(const struct bNodeTree *ntree);
void BKE_node_clipboard_clear(void);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index e6af587cbd7..61b90b44b03 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -653,6 +653,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
BLO_read_list(reader, &ntree->nodes);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->typeinfo = nullptr;
+ node->declaration = nullptr;
BLO_read_list(reader, &node->inputs);
BLO_read_list(reader, &node->outputs);
@@ -1014,10 +1015,8 @@ IDTypeInfo IDType_ID_NT = {
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
{
if (ntype->declare != nullptr) {
- blender::nodes::NodeDeclaration node_decl;
- blender::nodes::NodeDeclarationBuilder builder{node_decl};
- ntype->declare(builder);
- node_decl.build(*ntree, *node);
+ nodeDeclarationEnsure(ntree, node);
+ node->declaration->build(*ntree, *node);
return;
}
bNodeSocketTemplate *sockdef;
@@ -2216,6 +2215,10 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
bNodeLink *link_dst, *link_src;
*node_dst = *node_src;
+
+ /* Reset the declaration of the new node. */
+ node_dst->declaration = nullptr;
+
/* can be called for nodes outside a node tree (e.g. clipboard) */
if (ntree) {
if (unique_name) {
@@ -3103,6 +3106,8 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
MEM_freeN(node->prop);
}
+ delete node->declaration;
+
MEM_freeN(node);
if (ntree) {
@@ -3933,6 +3938,21 @@ int nodeSocketLinkLimit(const bNodeSocket *sock)
return sock->limit;
}
+/**
+ * If the node implements a `declare` function, this function makes sure that `node->declaration`
+ * is up to date.
+ */
+void nodeDeclarationEnsure(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ if (node->typeinfo->declare == nullptr) {
+ return;
+ }
+
+ node->declaration = new blender::nodes::NodeDeclaration();
+ blender::nodes::NodeDeclarationBuilder builder{*node->declaration};
+ node->typeinfo->declare(builder);
+}
+
/* ************** Node Clipboard *********** */
#define USE_NODE_CB_VALIDATE
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 82eabf6995c..c4cbc71762c 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -216,6 +216,16 @@ typedef enum eNodeSocketFlag {
SOCK_HIDE_LABEL = (1 << 12),
} eNodeSocketFlag;
+/** Workaround to forward-declare C++ type in C header. */
+#ifdef __cplusplus
+namespace blender::nodes {
+class NodeDeclaration;
+}
+using NodeDeclarationHandle = blender::nodes::NodeDeclaration;
+#else
+typedef struct NodeDeclarationHandle NodeDeclarationHandle;
+#endif
+
/* TODO: Limit data in bNode to what we want to see saved. */
typedef struct bNode {
struct bNode *next, *prev, *new_node;
@@ -315,6 +325,26 @@ typedef struct bNode {
* needs to be a float to feed GPU_uniform.
*/
float sss_id;
+
+ /**
+ * Describes the desired interface of the node. This is run-time data only.
+ * The actual interface of the node may deviate from the declaration temporarily.
+ * It's possible to sync the actual state of the node to the desired state. Currently, this is
+ * only done when a node is created or loaded.
+ *
+ * In the future, we may want to keep more data only in the declaration, so that it does not have
+ * to be synced to other places that are stored in files. That especially applies to data that
+ * can't be edited by users directly (e.g. min/max values of sockets, tooltips, ...).
+ *
+ * The declaration of a node can be recreated at any time when it is used. Caching it here is
+ * just a bit more efficient when it is used a lot. To make sure that the cache is up-to-date,
+ * call #nodeDeclarationEnsure before using it.
+ *
+ * Currently, the declaration is the same for every node of the same type. Going forward, that is
+ * intended to change though. Especially when nodes become more dynamic with respect to how many
+ * sockets they have.
+ */
+ NodeDeclarationHandle *declaration;
} bNode;
/* node->flag */
diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh
index 52f4ac291d2..7ba4ac52b86 100644
--- a/source/blender/nodes/NOD_node_declaration.hh
+++ b/source/blender/nodes/NOD_node_declaration.hh
@@ -60,6 +60,8 @@ class NodeDeclaration {
Span<SocketDeclarationPtr> inputs() const;
Span<SocketDeclarationPtr> outputs() const;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration")
};
class NodeDeclarationBuilder {
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 8efd6c55459..31260f95242 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -269,11 +269,9 @@ void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
return;
}
if (ntype->declare != nullptr) {
- blender::nodes::NodeDeclaration node_decl;
- blender::nodes::NodeDeclarationBuilder builder{node_decl};
- ntype->declare(builder);
- if (!node_decl.matches(*node)) {
- refresh_node(*ntree, *node, node_decl, do_id_user);
+ nodeDeclarationEnsure(ntree, node);
+ if (!node->declaration->matches(*node)) {
+ refresh_node(*ntree, *node, *node->declaration, do_id_user);
}
return;
}