[Bf-blender-cvs] [556691b19ad] functions: Improve error handling with ValueOrError class
Jacques Lucke
noreply at git.blender.org
Wed Jul 24 19:11:21 CEST 2019
Commit: 556691b19ad0b6c3103a721a497b8d84ec452de2
Author: Jacques Lucke
Date: Wed Jul 24 10:58:11 2019 +0200
Branches: functions
https://developer.blender.org/rB556691b19ad0b6c3103a721a497b8d84ec452de2
Improve error handling with ValueOrError class
We might want to use exceptions instead of this.
I'm not sure yet.
===================================================================
M source/blender/blenlib/BLI_optional.hpp
A source/blender/blenlib/BLI_value_or_error.hpp
M source/blender/functions/frontends/data_flow_nodes/data_flow_nodes-c.cpp
M source/blender/functions/frontends/data_flow_nodes/function_generation.cpp
M source/blender/functions/frontends/data_flow_nodes/function_generation.hpp
M source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
M source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
M source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
M source/blender/simulations/bparticles/inserters.cpp
M source/blender/simulations/bparticles/node_frontend.cpp
M tests/gtests/blenlib/BLI_optional_test.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_optional.hpp b/source/blender/blenlib/BLI_optional.hpp
index 904fa153e1e..0365c1772b4 100644
--- a/source/blender/blenlib/BLI_optional.hpp
+++ b/source/blender/blenlib/BLI_optional.hpp
@@ -134,6 +134,14 @@ template<typename T> class Optional {
}
}
+ T extract()
+ {
+ BLI_assert(m_set);
+ T value = std::move(this->value());
+ this->reset();
+ return value;
+ }
+
private:
T *value_ptr() const
{
diff --git a/source/blender/blenlib/BLI_value_or_error.hpp b/source/blender/blenlib/BLI_value_or_error.hpp
new file mode 100644
index 00000000000..ce2ef066f42
--- /dev/null
+++ b/source/blender/blenlib/BLI_value_or_error.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include "BLI_optional.hpp"
+
+namespace BLI {
+
+struct ErrorInfo {
+ const char *file;
+ uint line;
+ const char *function;
+ std::string message;
+};
+
+/**
+ * This class can be used as return value of functions that might have an error.
+ * The main reason it exists, is that I'm not sure whether we should use exceptions or not. That
+ * needs to be discussed at some point.
+ */
+template<typename T> class ValueOrError {
+ private:
+ Optional<T> m_value;
+ ErrorInfo m_error;
+
+ public:
+ ValueOrError(T value) : m_value(std::move(value))
+ {
+ }
+
+ ValueOrError(ErrorInfo error) : m_error(std::move(error))
+ {
+ }
+
+ static ValueOrError FromError(const char *file,
+ uint line,
+ const char *function,
+ std::string message)
+ {
+ return ValueOrError(ErrorInfo{file, line, function, message});
+ }
+
+ bool is_error() const
+ {
+ return !m_value.has_value();
+ }
+
+ T extract_value()
+ {
+ BLI_assert(m_value.has_value());
+ return m_value.extract();
+ }
+
+ ErrorInfo &error()
+ {
+ return m_error;
+ }
+};
+
+} // namespace BLI
+
+#define BLI_ERROR_CREATE(MESSAGE) \
+ { \
+ ErrorInfo \
+ { \
+ __FILE__, __LINE__, __func__, MESSAGE \
+ } \
+ }
diff --git a/source/blender/functions/frontends/data_flow_nodes/data_flow_nodes-c.cpp b/source/blender/functions/frontends/data_flow_nodes/data_flow_nodes-c.cpp
index c40276a0822..a1b38da6c4d 100644
--- a/source/blender/functions/frontends/data_flow_nodes/data_flow_nodes-c.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/data_flow_nodes-c.cpp
@@ -7,12 +7,13 @@ FnFunction FN_tree_to_function(bNodeTree *btree)
{
SCOPED_TIMER("Tree to function");
BLI_assert(btree);
- auto fn_opt = DataFlowNodes::generate_function(btree);
- if (!fn_opt.has_value()) {
+ ValueOrError<SharedFunction> fn_or_error = DataFlowNodes::generate_function(btree);
+ if (fn_or_error.is_error()) {
return nullptr;
}
- Function *fn_ptr = fn_opt.value().ptr();
+ SharedFunction fn = fn_or_error.extract_value();
+ Function *fn_ptr = fn.ptr();
fn_ptr->incref();
return wrap(fn_ptr);
}
diff --git a/source/blender/functions/frontends/data_flow_nodes/function_generation.cpp b/source/blender/functions/frontends/data_flow_nodes/function_generation.cpp
index c46cca39730..91003b0c4a5 100644
--- a/source/blender/functions/frontends/data_flow_nodes/function_generation.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/function_generation.cpp
@@ -32,14 +32,14 @@ static void find_interface_sockets(VirtualNodeTree &vtree,
}
}
-static Optional<FunctionGraph> generate_function_graph(VirtualNodeTree &vtree)
+static ValueOrError<FunctionGraph> generate_function_graph(VirtualNodeTree &vtree)
{
- Optional<VTreeDataGraph> data_graph_ = generate_graph(vtree);
- if (!data_graph_.has_value()) {
- return {};
+ ValueOrError<VTreeDataGraph> data_graph_or_error = generate_graph(vtree);
+ if (data_graph_or_error.is_error()) {
+ return data_graph_or_error.error();
}
- VTreeDataGraph &data_graph = data_graph_.value();
+ VTreeDataGraph data_graph = data_graph_or_error.extract_value();
DFGraphSocketSetVector input_sockets;
DFGraphSocketSetVector output_sockets;
@@ -48,18 +48,18 @@ static Optional<FunctionGraph> generate_function_graph(VirtualNodeTree &vtree)
return FunctionGraph(data_graph.graph(), input_sockets, output_sockets);
}
-Optional<SharedFunction> generate_function(bNodeTree *btree)
+ValueOrError<SharedFunction> generate_function(bNodeTree *btree)
{
VirtualNodeTree vtree;
vtree.add_all_of_tree(btree);
vtree.freeze_and_index();
- Optional<FunctionGraph> fgraph_ = generate_function_graph(vtree);
- if (!fgraph_.has_value()) {
- return {};
+ ValueOrError<FunctionGraph> fgraph_or_error = generate_function_graph(vtree);
+ if (fgraph_or_error.is_error()) {
+ return fgraph_or_error.error();
}
- FunctionGraph fgraph = fgraph_.value();
+ FunctionGraph fgraph = fgraph_or_error.extract_value();
// fgraph.graph()->to_dot__clipboard();
auto fn = fgraph.new_function(btree->id.name);
diff --git a/source/blender/functions/frontends/data_flow_nodes/function_generation.hpp b/source/blender/functions/frontends/data_flow_nodes/function_generation.hpp
index b0b402f2094..f483aff0e70 100644
--- a/source/blender/functions/frontends/data_flow_nodes/function_generation.hpp
+++ b/source/blender/functions/frontends/data_flow_nodes/function_generation.hpp
@@ -1,14 +1,16 @@
#pragma once
#include "FN_core.hpp"
-#include "BLI_optional.hpp"
+#include "BLI_value_or_error.hpp"
struct bNodeTree;
namespace FN {
namespace DataFlowNodes {
-Optional<SharedFunction> generate_function(struct bNodeTree *btree);
+using BLI::ValueOrError;
+
+ValueOrError<SharedFunction> generate_function(struct bNodeTree *btree);
} // namespace DataFlowNodes
} // namespace FN
diff --git a/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp b/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
index 37d848ff5c3..6e98e2987bc 100644
--- a/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/graph_generation.cpp
@@ -120,7 +120,7 @@ class BasicUnlinkedInputsHandler : public UnlinkedInputsHandler {
}
};
-Optional<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree)
+ValueOrError<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree)
{
DataFlowGraphBuilder graph_builder;
Map<VirtualSocket *, DFGB_Socket> socket_map;
@@ -129,11 +129,11 @@ Optional<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree)
GraphInserters &inserters = get_standard_inserters();
if (!insert_functions_for_bnodes(builder, inserters)) {
- return {};
+ return BLI_ERROR_CREATE("error inserting functions for nodes");
}
if (!insert_links(builder, inserters)) {
- return {};
+ return BLI_ERROR_CREATE("error inserting links");
}
BasicUnlinkedInputsHandler unlinked_inputs_handler(inserters);
diff --git a/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp b/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
index ec0d36a1709..5411614081b 100644
--- a/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
+++ b/source/blender/functions/frontends/data_flow_nodes/graph_generation.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "FN_core.hpp"
-#include "BLI_optional.hpp"
+#include "BLI_value_or_error.hpp"
#include "BKE_node_tree.hpp"
#include "builder.hpp"
@@ -12,6 +12,7 @@ namespace DataFlowNodes {
using BKE::VirtualNode;
using BKE::VirtualNodeTree;
using BKE::VirtualSocket;
+using BLI::ValueOrError;
class UnlinkedInputsHandler {
public:
@@ -69,7 +70,7 @@ class VNodePlaceholderBody : public FunctionBody {
}
};
-Optional<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree);
+ValueOrError<VTreeDataGraph> generate_graph(VirtualNodeTree &vtree);
} // namespace DataFlowNodes
} // namespace FN
diff --git a/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp b/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
index fda93632fc2..cbdf0364373 100644
--- a/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
+++ b/source/blender/functions/frontends/data_flow_nodes/inserters/nodes.cpp
@@ -225,9 +225,10 @@ static void INSERT_call(BTreeGraphBuilder &builder, VirtualNode *vnode)
return;
}
- Optional<SharedFunction> fn = generate_function(btree);
- BLI_assert(fn.has_value());
- builder.insert_matching_function(fn.value(), vnode);
+ ValueOrError<SharedFunction> fn_or_error = generate_function(btree);
+ BLI_assert(!fn_or_error.is_error());
+ SharedFunction fn = fn_or_error.extract_value();
+ builder.insert_matching_function(fn, vnode);
}
static void INSERT_switch(BTreeGraphBuilder &builder, VirtualNode *vnode)
diff --git a/source/blender/simulations/bparticles/inserters.cpp b/source/blender/simulations/bparticles/inserters.cpp
index 8bd96771f9f..7aeb64bc687 100644
--- a/source/blender/simulations/bparticles/inserters.cpp
+++ b/source/blender/simulations/bparticles/inserters.cpp
@@ -18,6 +18,7 @@
namespace BParticles {
+using BLI::ValueOrError;
using FN::DFGraphSocket;
using FN::SharedFunction;
using FN::SharedType;
@@ -335,11 +336,11 @@ static std::unique_ptr<Emitter> BUILD_EMITTER_custom_function(BuildContext &ctx,
return {};
}
- Optional<SharedFunction> fn_emitter_ = FN::DataFlowNodes::generate_function(btree);
- if (!fn_emitter_.has_value()) {
+ ValueOrError<SharedFunction> fn_emitter_or_error = FN::DataFlowNodes::generate_function(btree);
+ if (fn_emitter_or_error.is_error()) {
return {};
}
- SharedFunction fn_emitter = fn_emitter_.value();
+ SharedFunction fn_emitter = fn_emitter_or_error.extract_value();
SharedFunction fn_inputs = create_function_for_data_inputs(vnode, ctx.data_graph);
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 9f3ade60882..5ff33b561a6 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -8,6 +8,7 @@
namespace BParticles {
using BLI::MultiMap;
+using BLI::ValueOrError;
static bool is_particle_type_node(VirtualNode *vnode)
{
@@ -54,7
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list