diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index 8c6dbe788bc..f5588c37710 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -613,7 +613,8 @@ class Map { * the map, it will be newly added. * * The create_value callback is only called when the key did not exist yet. It is expected to - * take no parameters and return the value to be inserted. + * take no parameters and return the value to be inserted. The callback is called before the key + * is copied/moved into the map. */ template Value &lookup_or_add_cb(const Key &key, const CreateValueF &create_value) diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc index 85381c81eee..e38347af598 100644 --- a/source/blender/blenlib/tests/BLI_map_test.cc +++ b/source/blender/blenlib/tests/BLI_map_test.cc @@ -763,6 +763,20 @@ TEST(map, Equality) EXPECT_NE(a, b); } +TEST(map, AddCbMove) +{ + Map map; + std::string value = "a"; + bool value_checked = false; + map.lookup_or_add_cb(std::move(value), [&]() { + EXPECT_EQ(value, "a"); + value_checked = true; + return 10; + }); + EXPECT_TRUE(value_checked); + EXPECT_EQ(value, ""); +} + /** * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot. */ diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 9392c44883b..482aa2c8733 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -3786,7 +3786,7 @@ struct GeometryNodesLazyFunctionBuilder { * Combine multiple socket usages with a logical or. Inserts a new node for that purpose if * necessary. */ - lf::OutputSocket *or_socket_usages(MutableSpan usages, + lf::OutputSocket *or_socket_usages(const Span usages, BuildGraphParams &graph_params) { if (usages.is_empty()) { @@ -3796,16 +3796,19 @@ struct GeometryNodesLazyFunctionBuilder { return usages[0]; } - std::sort(usages.begin(), usages.end()); - return graph_params.socket_usages_combination_cache.lookup_or_add_cb_as(usages, [&]() { - auto &logical_or_fn = scope_.construct(usages.size()); - lf::Node &logical_or_node = graph_params.lf_graph.add_function(logical_or_fn); + /* Sort usages to produce a deterministic key for the same set of sockets. */ + Vector usages_sorted(usages); + std::sort(usages_sorted.begin(), usages_sorted.end()); + return graph_params.socket_usages_combination_cache.lookup_or_add_cb( + std::move(usages_sorted), [&]() { + auto &logical_or_fn = scope_.construct(usages.size()); + lf::Node &logical_or_node = graph_params.lf_graph.add_function(logical_or_fn); - for (const int i : usages.index_range()) { - graph_params.lf_graph.add_link(*usages[i], logical_or_node.input(i)); - } - return &logical_or_node.output(0); - }); + for (const int i : usages_sorted.index_range()) { + graph_params.lf_graph.add_link(*usages_sorted[i], logical_or_node.input(i)); + } + return &logical_or_node.output(0); + }); } void build_output_socket_usages(const bNode &bnode, BuildGraphParams &graph_params)