diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2020-10-26 23:00:37 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2020-10-27 01:11:14 +0300 |
commit | 527f8b32b32187f754e5b176db6377736f9cb8ff (patch) | |
tree | da291ed0d180d105521a03b73107ec6c9c39ff3b /intern/cycles/graph | |
parent | d6180dd2f7e8e9fdfa472f99f7a17bcb487c4b2d (diff) |
Cycles API: encapsulate Node socket members
This encapsulates Node socket members behind a set of specific methods;
as such it is no longer possible to directly access Node class members
from exporters and parts of Cycles.
The methods are defined via the NODE_SOCKET_API macros in `graph/
node.h`, and are for getting or setting a specific socket's value, as
well as querying or modifying the state of its update flag.
The setters will check whether the value has changed and tag the socket
as modified appropriately. This will let us know how a Node has changed
and what to update, which is the first concrete step toward a more
granular scene update system.
Since the setters will tag the Node sockets as modified when passed
different data, this patch also removes the various `modified` methods
on Nodes in favor of `Node::is_modified` which checks the sockets'
update flags status.
Reviewed By: brecht
Maniphest Tasks: T79174
Differential Revision: https://developer.blender.org/D8544
Diffstat (limited to 'intern/cycles/graph')
-rw-r--r-- | intern/cycles/graph/node.cpp | 85 | ||||
-rw-r--r-- | intern/cycles/graph/node.h | 61 |
2 files changed, 141 insertions, 5 deletions
diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index f239040ee3d..8c355b66f13 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -52,11 +52,6 @@ Node::~Node() { } -template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) -{ - return (T &)*(((char *)node) + socket.struct_offset); -} - #ifndef NDEBUG static bool is_socket_float3(const SocketType &socket) { @@ -387,6 +382,86 @@ void Node::copy_value(const SocketType &socket, const Node &other, const SocketT } } +void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket) +{ + assert(socket.type == other_socket.type); + + if (socket.is_array()) { + switch (socket.type) { + case SocketType::BOOLEAN_ARRAY: + set(socket, get_socket_value<array<bool>>(&other, socket)); + break; + case SocketType::FLOAT_ARRAY: + set(socket, get_socket_value<array<float>>(&other, socket)); + break; + case SocketType::INT_ARRAY: + set(socket, get_socket_value<array<int>>(&other, socket)); + break; + case SocketType::COLOR_ARRAY: + case SocketType::VECTOR_ARRAY: + case SocketType::POINT_ARRAY: + case SocketType::NORMAL_ARRAY: + set(socket, get_socket_value<array<float3>>(&other, socket)); + break; + case SocketType::POINT2_ARRAY: + set(socket, get_socket_value<array<float2>>(&other, socket)); + break; + case SocketType::STRING_ARRAY: + set(socket, get_socket_value<array<ustring>>(&other, socket)); + break; + case SocketType::TRANSFORM_ARRAY: + set(socket, get_socket_value<array<Transform>>(&other, socket)); + break; + case SocketType::NODE_ARRAY: + set(socket, get_socket_value<array<Node *>>(&other, socket)); + break; + default: + assert(0); + break; + } + } + else { + switch (socket.type) { + case SocketType::BOOLEAN: + set(socket, get_socket_value<bool>(&other, socket)); + break; + case SocketType::FLOAT: + set(socket, get_socket_value<float>(&other, socket)); + break; + case SocketType::INT: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::UINT: + set(socket, get_socket_value<uint>(&other, socket)); + break; + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + set(socket, get_socket_value<float3>(&other, socket)); + break; + case SocketType::POINT2: + set(socket, get_socket_value<float2>(&other, socket)); + break; + case SocketType::STRING: + set(socket, get_socket_value<ustring>(&other, socket)); + break; + case SocketType::ENUM: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::TRANSFORM: + set(socket, get_socket_value<Transform>(&other, socket)); + break; + case SocketType::NODE: + set(socket, get_socket_value<Node *>(&other, socket)); + break; + default: + assert(0); + break; + } + } +} + template<typename T> static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket) { diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index 16bd5e4358a..b28ea09282b 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -29,6 +29,61 @@ struct Node; struct NodeType; struct Transform; +/* Note: in the following macros we use "type const &" instead of "const type &" + * to avoid issues when pasting a pointer type. */ +#define NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) \ + const SocketType *get_##name##_socket() const \ + { \ + static const SocketType *socket = type->find_input(ustring(string_name)); \ + return socket; \ + } \ + bool name##_is_modified() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return socket_is_modified(*socket); \ + } \ + void tag_##name##_modified() \ + { \ + const SocketType *socket = get_##name##_socket(); \ + socket_modified |= socket->modified_flag_bit; \ + } \ + type_ const &get_##name() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return get_socket_value<type_>(this, *socket); \ + } + +#define NODE_SOCKET_API_BASE(type_, name, string_name) \ + protected: \ + type_ name; \ +\ + public: \ + NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) + +#define NODE_SOCKET_API(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } + +#define NODE_SOCKET_API_ARRAY(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ &value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } + +#define NODE_SOCKET_API_STRUCT_MEMBER(type_, name, member) \ + NODE_SOCKET_API_BASE_METHODS(type_, name##_##member, #name "." #member) \ + void set_##name##_##member(type_ value) \ + { \ + const SocketType *socket = get_##name##_##member##_socket(); \ + this->set(*socket, value); \ + } + /* Node */ struct NodeOwner { @@ -88,6 +143,7 @@ struct Node { void set_default_value(const SocketType &input); bool equals_value(const Node &other, const SocketType &input) const; void copy_value(const SocketType &input, const Node &other, const SocketType &other_input); + void set_value(const SocketType &input, const Node &other, const SocketType &other_input); /* equals */ bool equals(const Node &other) const; @@ -119,6 +175,11 @@ struct Node { protected: const NodeOwner *owner; + template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) + { + return (T &)*(((char *)node) + socket.struct_offset); + } + SocketModifiedFlags socket_modified; template<typename T> void set_if_different(const SocketType &input, T value); |