| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup fn | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file contains a graph data structure that allows composing multiple lazy-functions into a | 
					
						
							|  |  |  |  * combined lazy-function. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * There are two types of nodes in the graph: | 
					
						
							|  |  |  |  * - #FunctionNode: Corresponds to a #LazyFunction. The inputs and outputs of the function become | 
					
						
							|  |  |  |  *   input and output sockets of the node. | 
					
						
							|  |  |  |  * - #DummyNode: Is used to indicate inputs and outputs of the entire graph. It can have an | 
					
						
							|  |  |  |  *   arbitrary number of sockets. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_linear_allocator.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "FN_lazy_function.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 15:09:52 +01:00
										 |  |  | namespace blender::dot { | 
					
						
							|  |  |  | class DirectedEdge; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | namespace blender::fn::lazy_function { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Socket; | 
					
						
							|  |  |  | class InputSocket; | 
					
						
							|  |  |  | class OutputSocket; | 
					
						
							|  |  |  | class Node; | 
					
						
							|  |  |  | class Graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A #Socket is the interface of a #Node. Every #Socket is either an #InputSocket or #OutputSocket. | 
					
						
							|  |  |  |  * Links can be created from output sockets to input sockets. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class Socket : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * The node the socket belongs to. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Node *node_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Data type of the socket. Only sockets with the same type can be linked. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const CPPType *type_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Indicates whether this is an #InputSocket or #OutputSocket. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   bool is_input_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Index of the socket. E.g. 0 for the first input and the first output socket. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   int index_in_node_; | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Index of the socket in the entire graph. Every socket has a different index. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   int index_in_graph_; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend Graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   bool is_input() const; | 
					
						
							|  |  |  |   bool is_output() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int index() const; | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   int index_in_graph() const; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   InputSocket &as_input(); | 
					
						
							|  |  |  |   OutputSocket &as_output(); | 
					
						
							|  |  |  |   const InputSocket &as_input() const; | 
					
						
							|  |  |  |   const OutputSocket &as_output() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const Node &node() const; | 
					
						
							|  |  |  |   Node &node(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const CPPType &type() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::string name() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InputSocket : public Socket { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * An input can have at most one link connected to it. The linked socket is the "origin" because | 
					
						
							|  |  |  |    * it's where the data is coming from. The type of the origin must be the same as the type of | 
					
						
							|  |  |  |    * this socket. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   OutputSocket *origin_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Can be null or a non-owning pointer to a value of the type of the socket. This value will be | 
					
						
							|  |  |  |    * used when the input is used but not linked. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * This is technically not needed, because one could just create a separate node that just | 
					
						
							|  |  |  |    * outputs the value, but that would have more overhead. Especially because it's commonly the | 
					
						
							|  |  |  |    * case that most inputs are unlinked. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const void *default_value_ = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend Graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   OutputSocket *origin(); | 
					
						
							|  |  |  |   const OutputSocket *origin() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const void *default_value() const; | 
					
						
							|  |  |  |   void set_default_value(const void *value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class OutputSocket : public Socket { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * An output can be linked to an arbitrary number of inputs of the same type. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Vector<InputSocket *> targets_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend Graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   Span<InputSocket *> targets(); | 
					
						
							|  |  |  |   Span<const InputSocket *> targets() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A #Node has input and output sockets. Every node is either a #FunctionNode or a #DummyNode. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class Node : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * The function this node corresponds to. If this is null, the node is a #DummyNode. | 
					
						
							|  |  |  |    * The function is not owned by this #Node nor by the #Graph. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const LazyFunction *fn_ = nullptr; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Input sockets of the node. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Span<InputSocket *> inputs_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Output sockets of the node. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Span<OutputSocket *> outputs_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * An index that is set when calling #Graph::update_node_indices. This can be used to create | 
					
						
							|  |  |  |    * efficient mappings from nodes to other data using just an array instead of a hash map. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * This is technically not necessary but has better performance than always using hash maps. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   int index_in_graph_ = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend Graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   bool is_dummy() const; | 
					
						
							|  |  |  |   bool is_function() const; | 
					
						
							|  |  |  |   int index_in_graph() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Span<const InputSocket *> inputs() const; | 
					
						
							|  |  |  |   Span<const OutputSocket *> outputs() const; | 
					
						
							|  |  |  |   Span<InputSocket *> inputs(); | 
					
						
							|  |  |  |   Span<OutputSocket *> outputs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const InputSocket &input(int index) const; | 
					
						
							|  |  |  |   const OutputSocket &output(int index) const; | 
					
						
							|  |  |  |   InputSocket &input(int index); | 
					
						
							|  |  |  |   OutputSocket &output(int index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::string name() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A #Node that corresponds to a specific #LazyFunction. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class FunctionNode : public Node { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   const LazyFunction &function() const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 12:18:49 +01:00
										 |  |  | class DummyDebugInfo { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   virtual ~DummyDebugInfo() = default; | 
					
						
							|  |  |  |   virtual std::string node_name() const; | 
					
						
							|  |  |  |   virtual std::string input_name(const int i) const; | 
					
						
							|  |  |  |   virtual std::string output_name(const int i) const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Just stores a string per socket in a dummy node. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class SimpleDummyDebugInfo : public DummyDebugInfo { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   std::string name; | 
					
						
							|  |  |  |   Vector<std::string> input_names; | 
					
						
							|  |  |  |   Vector<std::string> output_names; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::string node_name() const override; | 
					
						
							|  |  |  |   std::string input_name(const int i) const override; | 
					
						
							|  |  |  |   std::string output_name(const int i) const override; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * A #Node that does *not* correspond to a #LazyFunction. Instead it can be used to indicate inputs | 
					
						
							|  |  |  |  * and outputs of the entire graph. It can have an arbitrary number of inputs and outputs. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class DummyNode : public Node { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2022-12-16 12:18:49 +01:00
										 |  |  |   const DummyDebugInfo *debug_info_ = nullptr; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend Node; | 
					
						
							| 
									
										
										
										
											2022-12-16 12:18:49 +01:00
										 |  |  |   friend Socket; | 
					
						
							|  |  |  |   friend Graph; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * A container for an arbitrary number of nodes and links between their sockets. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class Graph : NonCopyable, NonMovable { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Used to allocate nodes and sockets in the graph. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   LinearAllocator<> allocator_; | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Contains all nodes in the graph so that it is efficient to iterate over them. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Vector<Node *> nodes_; | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Number of sockets in the graph. Can be used as array size when indexing using | 
					
						
							|  |  |  |    * `Socket::index_in_graph`. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   int socket_num_ = 0; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   ~Graph(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Get all nodes in the graph. The index in the span corresponds to #Node::index_in_graph. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   Span<const Node *> nodes() const; | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   Span<Node *> nodes(); | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Add a new function node with sockets that match the passed in #LazyFunction. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   FunctionNode &add_function(const LazyFunction &fn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Add a new dummy node with the given socket types. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-12-16 12:18:49 +01:00
										 |  |  |   DummyNode &add_dummy(Span<const CPPType *> input_types, | 
					
						
							|  |  |  |                        Span<const CPPType *> output_types, | 
					
						
							|  |  |  |                        const DummyDebugInfo *debug_info = nullptr); | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Add a link between the two given sockets. | 
					
						
							|  |  |  |    * This has undefined behavior when the input is linked to something else already. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void add_link(OutputSocket &from, InputSocket &to); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * If the socket is linked, remove the link. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void clear_origin(InputSocket &socket); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Make sure that #Node::index_in_graph is up to date. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void update_node_indices(); | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Make sure that #Socket::index_in_graph is up to date. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void update_socket_indices(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Number of sockets in the graph. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   int socket_num() const; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Can be used to assert that #update_node_indices has been called. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   bool node_indices_are_valid() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 15:09:52 +01:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Optional configuration options for the dot graph generation. This allows creating | 
					
						
							|  |  |  |    * visualizations for specific purposes. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   class ToDotOptions { | 
					
						
							|  |  |  |    public: | 
					
						
							|  |  |  |     virtual std::string socket_name(const Socket &socket) const; | 
					
						
							|  |  |  |     virtual std::optional<std::string> socket_font_color(const Socket &socket) const; | 
					
						
							|  |  |  |     virtual void add_edge_attributes(const OutputSocket &from, | 
					
						
							|  |  |  |                                      const InputSocket &to, | 
					
						
							|  |  |  |                                      dot::DirectedEdge &dot_edge) const; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Utility to generate a dot graph string for the graph. This can be used for debugging. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-12-29 15:09:52 +01:00
										 |  |  |   std::string to_dot(const ToDotOptions &options = {}) const; | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #Socket Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool Socket::is_input() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return is_input_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool Socket::is_output() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return !is_input_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline int Socket::index() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return index_in_node_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  | inline int Socket::index_in_graph() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return index_in_graph_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | inline InputSocket &Socket::as_input() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_input()); | 
					
						
							|  |  |  |   return *static_cast<InputSocket *>(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline OutputSocket &Socket::as_output() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_output()); | 
					
						
							|  |  |  |   return *static_cast<OutputSocket *>(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const InputSocket &Socket::as_input() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_input()); | 
					
						
							|  |  |  |   return *static_cast<const InputSocket *>(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const OutputSocket &Socket::as_output() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(this->is_output()); | 
					
						
							|  |  |  |   return *static_cast<const OutputSocket *>(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const Node &Socket::node() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *node_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Node &Socket::node() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *node_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const CPPType &Socket::type() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *type_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #InputSocket Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const OutputSocket *InputSocket::origin() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return origin_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline OutputSocket *InputSocket::origin() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return origin_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const void *InputSocket::default_value() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return default_value_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline void InputSocket::set_default_value(const void *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   default_value_ = value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #OutputSocket Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const InputSocket *> OutputSocket::targets() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return targets_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<InputSocket *> OutputSocket::targets() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return targets_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #Node Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool Node::is_dummy() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return fn_ == nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline bool Node::is_function() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return fn_ != nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline int Node::index_in_graph() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return index_in_graph_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const InputSocket *> Node::inputs() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return inputs_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const OutputSocket *> Node::outputs() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return outputs_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<InputSocket *> Node::inputs() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return inputs_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<OutputSocket *> Node::outputs() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return outputs_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const InputSocket &Node::input(const int index) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *inputs_[index]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const OutputSocket &Node::output(const int index) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *outputs_[index]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline InputSocket &Node::input(const int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *inputs_[index]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline OutputSocket &Node::output(const int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return *outputs_[index]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #FunctionNode Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const LazyFunction &FunctionNode::function() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   BLI_assert(fn_ != nullptr); | 
					
						
							|  |  |  |   return *fn_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name #Graph Inline Methods
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline Span<const Node *> Graph::nodes() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return nodes_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:05:30 +01:00
										 |  |  | inline Span<Node *> Graph::nodes() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return nodes_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline int Graph::socket_num() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return socket_num_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-13 08:44:26 +02:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace blender::fn::lazy_function
 |