Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/FN_lazy_function_graph_executor.hh')
-rw-r--r--source/blender/functions/FN_lazy_function_graph_executor.hh98
1 files changed, 98 insertions, 0 deletions
diff --git a/source/blender/functions/FN_lazy_function_graph_executor.hh b/source/blender/functions/FN_lazy_function_graph_executor.hh
new file mode 100644
index 00000000000..a6ae5cac967
--- /dev/null
+++ b/source/blender/functions/FN_lazy_function_graph_executor.hh
@@ -0,0 +1,98 @@
+/* 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 &params,
+ const Context &context) const;
+
+ virtual void log_after_node_execute(const FunctionNode &node,
+ const Params &params,
+ const Context &context) const;
+
+ virtual void dump_when_outputs_are_missing(const FunctionNode &node,
+ Span<const OutputSocket *> 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<const FunctionNode *> 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<const OutputSocket *> graph_inputs_;
+ VectorSet<const InputSocket *> 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<const OutputSocket *> graph_inputs,
+ Span<const InputSocket *> 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 &params, const Context &context) const override;
+};
+
+} // namespace blender::fn::lazy_function