diff --git a/source/blender/functions/FN_lazy_function_graph.hh b/source/blender/functions/FN_lazy_function_graph.hh index c268cac3fd4..52d0eba1280 100644 --- a/source/blender/functions/FN_lazy_function_graph.hh +++ b/source/blender/functions/FN_lazy_function_graph.hh @@ -239,6 +239,9 @@ class Graph : NonCopyable, NonMovable { Span function_nodes() const; Span function_nodes(); + Span graph_inputs() const; + Span graph_outputs() const; + /** * Add a new function node with sockets that match the passed in #LazyFunction. */ @@ -488,6 +491,11 @@ inline Span Graph::nodes() const return nodes_; } +inline Span Graph::nodes() +{ + return nodes_; +} + inline Span Graph::function_nodes() const { return nodes_.as_span().drop_front(2).cast(); @@ -498,9 +506,14 @@ inline Span Graph::function_nodes() return nodes_.as_span().drop_front(2).cast(); } -inline Span Graph::nodes() +inline Span Graph::graph_inputs() const { - return nodes_; + return graph_inputs_; +} + +inline Span Graph::graph_outputs() const +{ + return graph_outputs_; } inline int Graph::socket_num() const diff --git a/source/blender/functions/FN_lazy_function_graph_executor.hh b/source/blender/functions/FN_lazy_function_graph_executor.hh index 93724f8f8ec..58fde1b8eea 100644 --- a/source/blender/functions/FN_lazy_function_graph_executor.hh +++ b/source/blender/functions/FN_lazy_function_graph_executor.hh @@ -88,8 +88,10 @@ class GraphExecutor : public LazyFunction { /** * Input and output sockets of the entire graph. */ - VectorSet graph_inputs_; - VectorSet graph_outputs_; + Vector graph_inputs_; + Vector graph_outputs_; + Array graph_input_index_by_socket_index_; + Array graph_output_index_by_socket_index_; /** * Optional logger for events that happen during execution. */ @@ -120,8 +122,8 @@ class GraphExecutor : public LazyFunction { public: GraphExecutor(const Graph &graph, - Span graph_inputs, - Span graph_outputs, + Vector graph_inputs, + Vector graph_outputs, const Logger *logger, const SideEffectProvider *side_effect_provider, const NodeExecuteWrapper *node_execute_wrapper); diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index 305d3db9e8e..080c2d0fe8a 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -657,7 +657,7 @@ class Executor { /* The notified output socket might be an input of the entire graph. In this case, notify the * caller that the input is required. */ if (node.is_interface()) { - const int graph_input_index = self_.graph_inputs_.index_of(&socket); + const int graph_input_index = self_.graph_input_index_by_socket_index_[socket.index()]; std::atomic &was_loaded = loaded_inputs_[graph_input_index]; if (was_loaded.load()) { return; @@ -702,7 +702,8 @@ class Executor { if (output_state.usage == ValueUsage::Maybe) { output_state.usage = ValueUsage::Unused; if (node.is_interface()) { - const int graph_input_index = self_.graph_inputs_.index_of(&socket); + const int graph_input_index = + self_.graph_input_index_by_socket_index_[socket.index()]; params_->set_input_unused(graph_input_index); } else { @@ -1115,7 +1116,8 @@ class Executor { } if (target_node.is_interface()) { /* Forward the value to the outside of the graph. */ - const int graph_output_index = self_.graph_outputs_.index_of_try(target_socket); + const int graph_output_index = + self_.graph_output_index_by_socket_index_[target_socket->index()]; if (graph_output_index != -1 && params_->get_output_usage(graph_output_index) != ValueUsage::Unused) { @@ -1425,14 +1427,16 @@ inline void Executor::execute_node(const FunctionNode &node, } GraphExecutor::GraphExecutor(const Graph &graph, - const Span graph_inputs, - const Span graph_outputs, + Vector graph_inputs, + Vector graph_outputs, const Logger *logger, const SideEffectProvider *side_effect_provider, const NodeExecuteWrapper *node_execute_wrapper) : graph_(graph), - graph_inputs_(graph_inputs), - graph_outputs_(graph_outputs), + graph_inputs_(std::move(graph_inputs)), + graph_outputs_(std::move(graph_outputs)), + graph_input_index_by_socket_index_(graph.graph_inputs().size(), -1), + graph_output_index_by_socket_index_(graph.graph_outputs().size(), -1), logger_(logger), side_effect_provider_(side_effect_provider), node_execute_wrapper_(node_execute_wrapper) @@ -1440,13 +1444,17 @@ GraphExecutor::GraphExecutor(const Graph &graph, /* The graph executor can handle partial execution when there are still missing inputs. */ allow_missing_requested_inputs_ = true; - for (const OutputSocket *socket : graph_inputs_) { - BLI_assert(socket->node().is_interface()); - inputs_.append({"In", socket->type(), ValueUsage::Maybe}); + for (const int i : graph_inputs_.index_range()) { + const OutputSocket &socket = *graph_inputs_[i]; + BLI_assert(socket.node().is_interface()); + inputs_.append({"In", socket.type(), ValueUsage::Maybe}); + graph_input_index_by_socket_index_[socket.index()] = i; } - for (const InputSocket *socket : graph_outputs_) { - BLI_assert(socket->node().is_interface()); - outputs_.append({"Out", socket->type()}); + for (const int i : graph_outputs_.index_range()) { + const InputSocket &socket = *graph_outputs_[i]; + BLI_assert(socket.node().is_interface()); + outputs_.append({"Out", socket.type()}); + graph_output_index_by_socket_index_[socket.index()] = i; } /* Preprocess buffer offsets. */