Cleanup: add type inheritance for Cycles nodes

This commit is contained in:
Brecht Van Lommel 2020-02-03 09:02:00 +01:00
parent b1f1a1ca60
commit ad489b7164
6 changed files with 41 additions and 7 deletions

View File

@ -326,6 +326,10 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str());
continue;
}
else if (node_type->create == NULL) {
fprintf(stderr, "Can't create abstract node type \"%s\".\n", node_type->name.c_str());
continue;
}
snode = (ShaderNode *)node_type->create(node_type);
}

View File

@ -669,4 +669,14 @@ size_t Node::get_total_size_in_bytes() const
return total_size;
}
bool Node::is_a(const NodeType *type_)
{
for (const NodeType *base = type; base; base = base->base) {
if (base == type_) {
return true;
}
}
return false;
}
CCL_NAMESPACE_END

View File

@ -94,6 +94,9 @@ struct Node {
/* Get total size of this node. */
size_t get_total_size_in_bytes() const;
/* Type testing, taking into account base classes. */
bool is_a(const NodeType *type);
ustring name;
const NodeType *type;
};

View File

@ -135,8 +135,13 @@ bool SocketType::is_float3(Type type)
/* Node Type */
NodeType::NodeType(Type type_) : type(type_)
NodeType::NodeType(Type type, const NodeType *base) : type(type), base(base)
{
if (base) {
/* Inherit sockets. */
inputs = base->inputs;
outputs = base->outputs;
}
}
NodeType::~NodeType()
@ -209,7 +214,7 @@ unordered_map<ustring, NodeType, ustringHash> &NodeType::types()
return _types;
}
NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_)
NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_, const NodeType *base_)
{
ustring name(name_);
@ -219,7 +224,7 @@ NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_)
return NULL;
}
types()[name] = NodeType(type_);
types()[name] = NodeType(type_, base_);
NodeType *type = &types()[name];
type->name = name;

View File

@ -103,7 +103,7 @@ struct SocketType {
struct NodeType {
enum Type { NONE, SHADER };
explicit NodeType(Type type = NONE);
explicit NodeType(Type type = NONE, const NodeType *base = NULL);
~NodeType();
void register_input(ustring name,
@ -124,11 +124,15 @@ struct NodeType {
ustring name;
Type type;
const NodeType *base;
vector<SocketType, std::allocator<SocketType>> inputs;
vector<SocketType, std::allocator<SocketType>> outputs;
CreateFunc create;
static NodeType *add(const char *name, CreateFunc create, Type type = NONE);
static NodeType *add(const char *name,
CreateFunc create,
Type type = NONE,
const NodeType *base = NULL);
static const NodeType *find(ustring name);
static unordered_map<ustring, NodeType, ustringHash> &types();
};
@ -148,6 +152,14 @@ struct NodeType {
} \
template<typename T> const NodeType *structname::register_type()
#define NODE_ABSTRACT_DECLARE \
template<typename T> static const NodeType *register_type(); \
static const NodeType *node_type;
#define NODE_ABSTRACT_DEFINE(structname) \
const NodeType *structname::node_type = structname::register_type<structname>(); \
template<typename T> const NodeType *structname::register_type()
/* Sock Definition Macros */
#define SOCKET_OFFSETOF(T, name) (((char *)&(((T *)1)->name)) - (char *)1)

View File

@ -200,7 +200,7 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
map<ustring, Node *>::iterator it = reader.node_map.find(value);
if (it != reader.node_map.end()) {
Node *value_node = it->second;
if (value_node->type == *(socket.node_type))
if (value_node->is_a(*(socket.node_type)))
node->set(socket, it->second);
}
break;
@ -215,7 +215,7 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
map<ustring, Node *>::iterator it = reader.node_map.find(ustring(tokens[i]));
if (it != reader.node_map.end()) {
Node *value_node = it->second;
value[i] = (value_node->type == *(socket.node_type)) ? value_node : NULL;
value[i] = (value_node->is_a(*(socket.node_type))) ? value_node : NULL;
}
else {
value[i] = NULL;