diff --git a/source/blender/blenkernel/intern/bake_items_socket.cc b/source/blender/blenkernel/intern/bake_items_socket.cc index aab4ffd2149..492d05f3182 100644 --- a/source/blender/blenkernel/intern/bake_items_socket.cc +++ b/source/blender/blenkernel/intern/bake_items_socket.cc @@ -92,11 +92,9 @@ static std::unique_ptr move_common_socket_value_to_bake_item( if (const auto *item_socket_value = std::get_if( &bundle_item.value.value)) { + SocketValueVariant value_variant = item_socket_value->value; if (std::unique_ptr bake_item = move_common_socket_value_to_bake_item( - *item_socket_value->type, - *static_cast(item_socket_value->value), - std::nullopt, - r_geometry_bake_items)) + *item_socket_value->type, value_variant, std::nullopt, r_geometry_bake_items)) { bundle_bake_item->items.append( BundleBakeItem::Item{bundle_item.key, @@ -297,7 +295,7 @@ Array> move_socket_values_to_bake_items( copy_bake_item_to_socket_value( *socket_value->value, stype->type, {}, data_block_map, r_attribute_map)) { - bundle.add(item.key, nodes::BundleItemSocketValue{stype, &*child_value_variant}); + bundle.add(item.key, nodes::BundleItemSocketValue{stype, *child_value_variant}); } else { return std::nullopt; diff --git a/source/blender/nodes/NOD_geometry_nodes_bundle.hh b/source/blender/nodes/NOD_geometry_nodes_bundle.hh index 06e9f79abb9..80e92b264b9 100644 --- a/source/blender/nodes/NOD_geometry_nodes_bundle.hh +++ b/source/blender/nodes/NOD_geometry_nodes_bundle.hh @@ -18,7 +18,7 @@ struct BundleItemSocketValue { /** The type of data referenced. It uses #bNodeSocketType::geometry_nodes_cpp_type. */ const bke::bNodeSocketType *type; /** Non-owning pointer to the value. The memory is owned by the Bundle directly. */ - void *value; + bke::SocketValueVariant value; }; /** @@ -60,16 +60,8 @@ class Bundle : public ImplicitSharingMixin { private: Vector items_; - Vector buffers_; public: - Bundle(); - Bundle(const Bundle &other); - Bundle(Bundle &&other) noexcept; - Bundle &operator=(const Bundle &other); - Bundle &operator=(Bundle &&other) noexcept; - ~Bundle(); - static BundlePtr create(); bool add(StringRef key, const BundleItemValue &value); @@ -115,21 +107,15 @@ inline std::optional BundleItemValue::as_socket_value( if (!socket_value) { return std::nullopt; } - if (!socket_value->value || !socket_value->type) { - return std::nullopt; + if (socket_value->type->type == dst_socket_type.type) { + return socket_value->value.get(); } - const void *converted_value = socket_value->value; - BUFFER_FOR_CPP_TYPE_VALUE(*dst_socket_type.geometry_nodes_cpp_type, buffer); - if (socket_value->type != &dst_socket_type) { - if (!implicitly_convert_socket_value( - *socket_value->type, socket_value->value, dst_socket_type, buffer)) - { - return std::nullopt; - } - converted_value = buffer; + if (std::optional converted_value = implicitly_convert_socket_value( + *socket_value->type, socket_value->value, dst_socket_type)) + { + return converted_value->get(); } - const auto &value_variant = *static_cast(converted_value); - return value_variant.get(); + return std::nullopt; } template inline const bke::bNodeSocketType *socket_type_info_by_static_type() @@ -183,15 +169,8 @@ template inline std::optional BundleItemValue::as() const if (!socket_value) { return std::nullopt; } - if (!socket_value->value || !socket_value->type) { - return std::nullopt; - } - if (!socket_value->type->geometry_nodes_cpp_type->is()) { - return std::nullopt; - } - const auto *value = static_cast(socket_value->value); - if (value->is_list()) { - return value->get(); + if (socket_value->value.is_list()) { + return socket_value->value.get(); } return std::nullopt; } @@ -242,7 +221,7 @@ template inline void to_stored_type(T &&value, Fn &&fn) } else if (const bke::bNodeSocketType *socket_type = socket_type_info_by_static_type()) { auto value_variant = bke::SocketValueVariant::From(std::forward(value)); - fn(BundleItemValue{BundleItemSocketValue{socket_type, &value_variant}}); + fn(BundleItemValue{BundleItemSocketValue{socket_type, value_variant}}); } else { /* All allowed types should be handled above already. */ diff --git a/source/blender/nodes/NOD_geometry_nodes_closure_eval.hh b/source/blender/nodes/NOD_geometry_nodes_closure_eval.hh index 1e5f1a06939..597ba4af6cf 100644 --- a/source/blender/nodes/NOD_geometry_nodes_closure_eval.hh +++ b/source/blender/nodes/NOD_geometry_nodes_closure_eval.hh @@ -8,17 +8,16 @@ #include "NOD_geometry_nodes_lazy_function.hh" +#include "BKE_node_socket_value.hh" + namespace blender::nodes { struct ClosureEagerEvalParams { struct InputItem { std::string key; const bke::bNodeSocketType *type = nullptr; - /** - * The actual socket value of type bNodeSocketType::geometry_nodes_cpp_type. - * This is not const, because it may be moved from. - */ - void *value = nullptr; + /** This may be moved from. */ + bke::SocketValueVariant value; }; struct OutputItem { @@ -28,7 +27,7 @@ struct ClosureEagerEvalParams { * Where the output value should be stored. This is expected to point to uninitialized memory * when it's passed into #evaluate_closure_eagerly which will then construct the value inplace. */ - void *value = nullptr; + bke::SocketValueVariant *value = nullptr; }; Vector inputs; diff --git a/source/blender/nodes/NOD_geometry_nodes_values.hh b/source/blender/nodes/NOD_geometry_nodes_values.hh index 85f7de1fbab..02ac9178120 100644 --- a/source/blender/nodes/NOD_geometry_nodes_values.hh +++ b/source/blender/nodes/NOD_geometry_nodes_values.hh @@ -56,10 +56,10 @@ template constexpr bool is_GeoNodesMultiInput_v implicitly_convert_socket_value( + const bke::bNodeSocketType &from_type, + const bke::SocketValueVariant &from_value, + const bke::bNodeSocketType &to_type); /** * Builds a lazy-function that can convert between socket types. Returns null if the conversion is diff --git a/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc b/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc index 905c32ea522..6384e7a0427 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc @@ -122,9 +122,9 @@ static void node_geo_exec(GeoNodeExecParams params) if (name.is_empty()) { continue; } - void *input_ptr = params.low_level_lazy_function_params().try_get_input_data_ptr(i); - BLI_assert(input_ptr); - bundle.add(name, BundleItemSocketValue{stype, input_ptr}); + bke::SocketValueVariant value = params.extract_input( + node.input_socket(i).identifier); + bundle.add(name, BundleItemSocketValue{stype, std::move(value)}); } params.set_output("Bundle", std::move(bundle_ptr)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc index 52c76d9b3ea..0b0ad9d929d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc @@ -144,14 +144,13 @@ static void node_geo_exec(GeoNodeExecParams params) fmt::format("{}: \"{}\"", TIP_("Cannot get internal value from bundle"), name)); continue; } - void *output_ptr = lf_params.get_output_data_ptr(i); - if (socket_value->type->type == stype->type) { - socket_value->type->geometry_nodes_cpp_type->copy_construct(socket_value->value, output_ptr); - } - else { - if (implicitly_convert_socket_value( - *socket_value->type, socket_value->value, *stype, output_ptr)) + + SocketValueVariant output_value = std::move(socket_value->value); + if (socket_value->type->type != stype->type) { + if (std::optional converted_value = implicitly_convert_socket_value( + *socket_value->type, output_value, *stype)) { + output_value = std::move(*converted_value); params.error_message_add( NodeWarningType::Info, fmt::format("{}: \"{}\" ({} " BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE " {})", @@ -168,10 +167,10 @@ static void node_geo_exec(GeoNodeExecParams params) name, TIP_(socket_value->type->label), TIP_(stype->label))); - construct_socket_default_value(*stype, output_ptr); + output_value = *socket_value->type->geometry_nodes_default_value; } } - lf_params.output_set(i); + lf_params.set_output(i, std::move(output_value)); } params.set_default_remaining_outputs(); diff --git a/source/blender/nodes/intern/geometry_nodes_bundle.cc b/source/blender/nodes/intern/geometry_nodes_bundle.cc index 7541c75a184..09a4d3e699c 100644 --- a/source/blender/nodes/intern/geometry_nodes_bundle.cc +++ b/source/blender/nodes/intern/geometry_nodes_bundle.cc @@ -43,59 +43,11 @@ bool BundleSignature::all_matching_exactly(const Span signature return true; } -Bundle::Bundle() = default; - -Bundle::~Bundle() -{ - for (StoredItem &item : items_) { - if (BundleItemSocketValue *socket_value = std::get_if( - &item.value.value)) - { - socket_value->type->geometry_nodes_cpp_type->destruct(socket_value->value); - } - } - for (void *buffer : buffers_) { - MEM_freeN(buffer); - } -} - -Bundle::Bundle(const Bundle &other) -{ - for (const StoredItem &item : other.items_) { - this->add_new(item.key, item.value); - } -} - -Bundle::Bundle(Bundle &&other) noexcept - : items_(std::move(other.items_)), buffers_(std::move(other.buffers_)) -{ -} - BundlePtr Bundle::create() { return BundlePtr(MEM_new(__func__)); } -Bundle &Bundle::operator=(const Bundle &other) -{ - if (this == &other) { - return *this; - } - this->~Bundle(); - new (this) Bundle(other); - return *this; -} - -Bundle &Bundle::operator=(Bundle &&other) noexcept -{ - if (this == &other) { - return *this; - } - this->~Bundle(); - new (this) Bundle(std::move(other)); - return *this; -} - [[maybe_unused]] static bool is_valid_key(const StringRef key) { return key.find('/') == StringRef::not_found; @@ -104,22 +56,7 @@ Bundle &Bundle::operator=(Bundle &&other) noexcept void Bundle::add_new(const StringRef key, const BundleItemValue &value) { BLI_assert(is_valid_key(key)); - if (const BundleItemSocketValue *socket_value = std::get_if(&value.value)) - { - const bke::bNodeSocketType &type = *socket_value->type; - BLI_assert(type.geometry_nodes_cpp_type); - const CPPType &cpp_type = *type.geometry_nodes_cpp_type; - void *buffer = MEM_mallocN_aligned(cpp_type.size, cpp_type.alignment, __func__); - cpp_type.copy_construct(socket_value->value, buffer); - items_.append(StoredItem{std::move(key), {BundleItemSocketValue{&type, buffer}}}); - buffers_.append(buffer); - } - else if (std::holds_alternative(value.value)) { - items_.append(StoredItem{std::move(key), value}); - } - else { - BLI_assert_unreachable(); - } + items_.append(StoredItem{std::move(key), value}); } void Bundle::add_override(const StringRef key, const BundleItemValue &value) @@ -164,7 +101,7 @@ void Bundle::add_path_override(const StringRef path, const BundleItemValue &valu std::move(child_bundle)); this->add( first_part, - BundleItemSocketValue{bke::node_socket_type_find_static(SOCK_BUNDLE), &child_bundle_value}); + BundleItemSocketValue{bke::node_socket_type_find_static(SOCK_BUNDLE), child_bundle_value}); } bool Bundle::add_path(StringRef path, const BundleItemValue &value) @@ -245,17 +182,7 @@ BundlePtr Bundle::copy() const bool Bundle::remove(const StringRef key) { BLI_assert(is_valid_key(key)); - const int removed_num = items_.remove_if([&key](StoredItem &item) { - if (item.key == key) { - if (BundleItemSocketValue *socket_value = std::get_if( - &item.value.value)) - { - socket_value->type->geometry_nodes_cpp_type->destruct(socket_value->value); - } - return true; - } - return false; - }); + const int removed_num = items_.remove_if([&key](StoredItem &item) { return item.key == key; }); return removed_num >= 1; } diff --git a/source/blender/nodes/intern/geometry_nodes_closure_zone.cc b/source/blender/nodes/intern/geometry_nodes_closure_zone.cc index c7334854d41..0b5fc980605 100644 --- a/source/blender/nodes/intern/geometry_nodes_closure_zone.cc +++ b/source/blender/nodes/intern/geometry_nodes_closure_zone.cc @@ -788,18 +788,18 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa if (const std::optional mapped_i = inputs_map[input_item_i]) { const bke::bNodeSocketType &from_type = *item.type; const bke::bNodeSocketType &to_type = *signature.inputs[*mapped_i].type; - const CPPType &to_cpp_type = *to_type.geometry_nodes_cpp_type; - void *value = allocator.allocate(to_cpp_type); - if (&from_type == &to_type) { - to_cpp_type.copy_construct(item.value, value); + bke::SocketValueVariant input_value; + if (std::optional value = implicitly_convert_socket_value( + from_type, item.value, to_type)) + { + input_value = *value; } else { - if (!implicitly_convert_socket_value(from_type, item.value, to_type, value)) { - const void *default_value = closure.default_input_value(*mapped_i); - to_cpp_type.copy_construct(default_value, value); - } + input_value = *to_type.geometry_nodes_default_value; } - lf_input_values[indices.inputs.main[*mapped_i]] = {to_cpp_type, value}; + lf_input_values[indices.inputs.main[*mapped_i]] = { + CPPType::get(), + allocator.construct(std::move(input_value)).release()}; } else { /* Provided input value is ignored. */ @@ -859,15 +859,15 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa if (const std::optional mapped_i = outputs_map[output_item_i]) { const bke::bNodeSocketType &from_type = *signature.outputs[*mapped_i].type; const bke::bNodeSocketType &to_type = *item.type; - const CPPType &to_cpp_type = *to_type.geometry_nodes_cpp_type; - void *computed_value = lf_output_values[indices.outputs.main[*mapped_i]].get(); - if (&from_type == &to_type) { - to_cpp_type.move_construct(computed_value, item.value); + if (std::optional value = implicitly_convert_socket_value( + from_type, + *lf_output_values[indices.outputs.main[*mapped_i]].get(), + to_type)) + { + new (item.value) bke::SocketValueVariant(std::move(*value)); } else { - if (!implicitly_convert_socket_value(from_type, computed_value, to_type, item.value)) { - construct_socket_default_value(to_type, item.value); - } + new (item.value) bke::SocketValueVariant(*to_type.geometry_nodes_default_value); } } else { diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 3db0b3f1ef0..a7554efdf80 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -548,37 +548,34 @@ static void execute_multi_function_on_value_variant__field( return true; } -bool implicitly_convert_socket_value(const bke::bNodeSocketType &from_type, - const void *from_value, - const bke::bNodeSocketType &to_type, - void *r_to_value) +std::optional implicitly_convert_socket_value( + const bke::bNodeSocketType &from_type, + const SocketValueVariant &from_value, + const bke::bNodeSocketType &to_type) { - BLI_assert(from_value != r_to_value); if (from_type.type == to_type.type) { - from_type.geometry_nodes_cpp_type->copy_construct(from_value, r_to_value); - return true; + return from_value; } const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); const CPPType *from_cpp_type = from_type.base_cpp_type; const CPPType *to_cpp_type = to_type.base_cpp_type; if (!from_cpp_type || !to_cpp_type) { - return false; + return std::nullopt; } if (conversions.is_convertible(*from_cpp_type, *to_cpp_type)) { const MultiFunction &multi_fn = *conversions.get_conversion_multi_function( mf::DataType::ForSingle(*from_cpp_type), mf::DataType::ForSingle(*to_cpp_type)); - SocketValueVariant input_variant = *static_cast(from_value); - SocketValueVariant *output_variant = new (r_to_value) SocketValueVariant(); + SocketValueVariant input_variant = from_value; + SocketValueVariant output_variant; std::string error_message; if (!execute_multi_function_on_value_variant( - multi_fn, {}, {&input_variant}, {output_variant}, nullptr, error_message)) + multi_fn, {}, {&input_variant}, {&output_variant}, nullptr, error_message)) { - std::destroy_at(output_variant); - return false; + return std::nullopt; } - return true; + return output_variant; } - return false; + return std::nullopt; } class LazyFunctionForImplicitConversion : public LazyFunction { @@ -691,16 +688,16 @@ class LazyFunctionForMutedNode : public LazyFunction { continue; } const int lf_input_index = lf_index_by_bsocket_[input_bsocket->index_in_tree()]; - const void *input_value = params.try_get_input_data_ptr_or_request(lf_input_index); - if (input_value == nullptr) { + const SocketValueVariant *input_value = + params.try_get_input_data_ptr_or_request(lf_input_index); + if (!input_value) { /* Wait for value to be available. */ continue; } - void *output_value = params.get_output_data_ptr(lf_output_index); - if (implicitly_convert_socket_value( - *input_bsocket->typeinfo, input_value, *output_bsocket->typeinfo, output_value)) + if (std::optional converted_value = implicitly_convert_socket_value( + *input_bsocket->typeinfo, *input_value, *output_bsocket->typeinfo)) { - params.output_set(lf_output_index); + params.set_output(lf_output_index, std::move(*converted_value)); continue; } set_default_value_for_output_socket(params, lf_output_index, *output_bsocket);