diff options
Diffstat (limited to 'source/blender/nodes/NOD_node_declaration.hh')
-rw-r--r-- | source/blender/nodes/NOD_node_declaration.hh | 100 |
1 files changed, 84 insertions, 16 deletions
diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 52f4ac291d2..d64b76ccbb9 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -27,12 +27,19 @@ namespace blender::nodes { class NodeDeclarationBuilder; +/** + * Describes a single input or output socket. This is subclassed for different socket types. + */ class SocketDeclaration { protected: std::string name_; std::string identifier_; + bool hide_label_ = false; + bool hide_value_ = false; + bool is_multi_input_ = false; friend NodeDeclarationBuilder; + template<typename SocketDecl> friend class SocketDeclarationBuilder; public: virtual ~SocketDeclaration() = default; @@ -43,6 +50,49 @@ class SocketDeclaration { StringRefNull name() const; StringRefNull identifier() const; + + protected: + void set_common_flags(bNodeSocket &socket) const; + bool matches_common_data(const bNodeSocket &socket) const; +}; + +class BaseSocketDeclarationBuilder { + public: + virtual ~BaseSocketDeclarationBuilder() = default; +}; + +/** + * Wraps a #SocketDeclaration and provides methods to set it up correctly. + * This is separate from #SocketDeclaration, because it allows separating the API used by nodes to + * declare themselves from how the declaration is stored internally. + */ +template<typename SocketDecl> +class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { + protected: + using Self = typename SocketDecl::Builder; + static_assert(std::is_base_of_v<SocketDeclaration, SocketDecl>); + SocketDecl *decl_; + + friend class NodeDeclarationBuilder; + + public: + Self &hide_label(bool value = true) + { + decl_->hide_label_ = value; + return *(Self *)this; + } + + Self &hide_value(bool value = true) + { + decl_->hide_value_ = value; + return *(Self *)this; + } + + Self &multi_input(bool value = true) + { + decl_->is_multi_input_ = value; + return *(Self *)this; + } }; using SocketDeclarationPtr = std::unique_ptr<SocketDeclaration>; @@ -60,17 +110,28 @@ class NodeDeclaration { Span<SocketDeclarationPtr> inputs() const; Span<SocketDeclarationPtr> outputs() const; + + MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration") }; class NodeDeclarationBuilder { private: NodeDeclaration &declaration_; + Vector<std::unique_ptr<BaseSocketDeclarationBuilder>> builders_; public: NodeDeclarationBuilder(NodeDeclaration &declaration); - template<typename DeclType> DeclType &add_input(StringRef name, StringRef identifier = ""); - template<typename DeclType> DeclType &add_output(StringRef name, StringRef identifier = ""); + template<typename DeclType> + typename DeclType::Builder &add_input(StringRef name, StringRef identifier = ""); + template<typename DeclType> + typename DeclType::Builder &add_output(StringRef name, StringRef identifier = ""); + + private: + template<typename DeclType> + typename DeclType::Builder &add_socket(StringRef name, + StringRef identifier, + Vector<SocketDeclarationPtr> &r_decls); }; /* -------------------------------------------------------------------- @@ -97,27 +158,34 @@ inline NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declarati } template<typename DeclType> -inline DeclType &NodeDeclarationBuilder::add_input(StringRef name, StringRef identifier) +inline typename DeclType::Builder &NodeDeclarationBuilder::add_input(StringRef name, + StringRef identifier) { - static_assert(std::is_base_of_v<SocketDeclaration, DeclType>); - std::unique_ptr<DeclType> socket_decl = std::make_unique<DeclType>(); - DeclType &ref = *socket_decl; - ref.name_ = name; - ref.identifier_ = identifier.is_empty() ? name : identifier; - declaration_.inputs_.append(std::move(socket_decl)); - return ref; + return this->add_socket<DeclType>(name, identifier, declaration_.inputs_); +} + +template<typename DeclType> +inline typename DeclType::Builder &NodeDeclarationBuilder::add_output(StringRef name, + StringRef identifier) +{ + return this->add_socket<DeclType>(name, identifier, declaration_.outputs_); } template<typename DeclType> -inline DeclType &NodeDeclarationBuilder::add_output(StringRef name, StringRef identifier) +inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket( + StringRef name, StringRef identifier, Vector<SocketDeclarationPtr> &r_decls) { static_assert(std::is_base_of_v<SocketDeclaration, DeclType>); + using Builder = typename DeclType::Builder; std::unique_ptr<DeclType> socket_decl = std::make_unique<DeclType>(); - DeclType &ref = *socket_decl; - ref.name_ = name; - ref.identifier_ = identifier.is_empty() ? name : identifier; - declaration_.outputs_.append(std::move(socket_decl)); - return ref; + std::unique_ptr<Builder> socket_decl_builder = std::make_unique<Builder>(); + socket_decl_builder->decl_ = &*socket_decl; + socket_decl->name_ = name; + socket_decl->identifier_ = identifier.is_empty() ? name : identifier; + r_decls.append(std::move(socket_decl)); + Builder &socket_decl_builder_ref = *socket_decl_builder; + builders_.append(std::move(socket_decl_builder)); + return socket_decl_builder_ref; } /* -------------------------------------------------------------------- |