/* SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once /** \file * \ingroup fn * * This file provides means to create a #LazyFunction from #Graph (which could then e.g. be used in * another #Graph again). */ #include "BLI_vector.hh" #include "BLI_vector_set.hh" #include "FN_lazy_function_graph.hh" namespace blender::fn::lazy_function { /** * Can be implemented to log values produced during graph evaluation. */ class GraphExecutorLogger { public: virtual ~GraphExecutorLogger() = default; virtual void log_socket_value(const Socket &socket, GPointer value, const Context &context) const; virtual void log_before_node_execute(const FunctionNode &node, const Params ¶ms, const Context &context) const; virtual void log_after_node_execute(const FunctionNode &node, const Params ¶ms, const Context &context) const; virtual void dump_when_outputs_are_missing(const FunctionNode &node, Span missing_sockets, const Context &context) const; virtual void dump_when_input_is_set_twice(const InputSocket &target_socket, const OutputSocket &from_socket, const Context &context) const; }; /** * Has to be implemented when some of the nodes in the graph may have side effects. The * #GraphExecutor has to know about that to make sure that these nodes will be executed even though * their outputs are not needed. */ class GraphExecutorSideEffectProvider { public: virtual ~GraphExecutorSideEffectProvider() = default; virtual Vector get_nodes_with_side_effects(const Context &context) const; }; class GraphExecutor : public LazyFunction { public: using Logger = GraphExecutorLogger; using SideEffectProvider = GraphExecutorSideEffectProvider; private: /** * The graph that is evaluated. */ const Graph &graph_; /** * Input and output sockets of the entire graph. */ VectorSet graph_inputs_; VectorSet graph_outputs_; /** * Optional logger for events that happen during execution. */ const Logger *logger_; /** * Optional side effect provider. It knows which nodes have side effects based on the context * during evaluation. */ const SideEffectProvider *side_effect_provider_; friend class Executor; public: GraphExecutor(const Graph &graph, Span graph_inputs, Span graph_outputs, const Logger *logger, const SideEffectProvider *side_effect_provider); void *init_storage(LinearAllocator<> &allocator) const override; void destruct_storage(void *storage) const override; private: void execute_impl(Params ¶ms, const Context &context) const override; }; } // namespace blender::fn::lazy_function