diff --git a/source/blender/blenkernel/BKE_bake_items.hh b/source/blender/blenkernel/BKE_bake_items.hh index beabe33c308..06fef039cad 100644 --- a/source/blender/blenkernel/BKE_bake_items.hh +++ b/source/blender/blenkernel/BKE_bake_items.hh @@ -150,12 +150,20 @@ class StringBakeItem : public BakeItem { */ class BundleBakeItem : public BakeItem { public: - struct Item { - std::string key; + struct SocketValue { std::string socket_idname; std::unique_ptr value; }; + struct InternalValue { + ImplicitSharingPtr<> value; + }; + + struct Item { + std::string key; + std::variant value; + }; + Vector items; }; diff --git a/source/blender/blenkernel/intern/bake_items_serialize.cc b/source/blender/blenkernel/intern/bake_items_serialize.cc index 66baf909580..57b1fe6c86c 100644 --- a/source/blender/blenkernel/intern/bake_items_serialize.cc +++ b/source/blender/blenkernel/intern/bake_items_serialize.cc @@ -1497,11 +1497,14 @@ static void serialize_bake_item(const BakeItem &item, r_io_item.append_str("type", "BUNDLE"); ArrayValue &io_items = *r_io_item.append_array("items"); for (const BundleBakeItem::Item &item : bundle_state_item->items) { - DictionaryValue &io_bundle_item = *io_items.append_dict(); - io_bundle_item.append_str("key", item.key); - io_bundle_item.append_str("socket_idname", item.socket_idname); - io::serialize::DictionaryValue &io_bundle_item_value = *io_bundle_item.append_dict("value"); - serialize_bake_item(*item.value, blob_writer, blob_sharing, io_bundle_item_value); + if (const auto *socket_value = std::get_if(&item.value)) { + DictionaryValue &io_bundle_item = *io_items.append_dict(); + io_bundle_item.append_str("key", item.key); + io_bundle_item.append_str("socket_idname", socket_value->socket_idname); + io::serialize::DictionaryValue &io_bundle_item_value = *io_bundle_item.append_dict( + "value"); + serialize_bake_item(*socket_value->value, blob_writer, blob_sharing, io_bundle_item_value); + } } } } @@ -1614,7 +1617,8 @@ static std::unique_ptr deserialize_bake_item(const DictionaryValue &io if (!value) { return {}; } - bundle->items.append(BundleBakeItem::Item{*key, *socket_idname, std::move(value)}); + bundle->items.append(BundleBakeItem::Item{ + *key, BundleBakeItem::SocketValue{*socket_idname, std::move(value)}}); } return bundle; } diff --git a/source/blender/blenkernel/intern/bake_items_socket.cc b/source/blender/blenkernel/intern/bake_items_socket.cc index b022831afd0..423777b88af 100644 --- a/source/blender/blenkernel/intern/bake_items_socket.cc +++ b/source/blender/blenkernel/intern/bake_items_socket.cc @@ -92,11 +92,27 @@ static std::unique_ptr move_common_socket_value_to_bake_item( if (bundle_ptr) { const nodes::Bundle &bundle = *bundle_ptr; for (const nodes::Bundle::StoredItem &bundle_item : bundle.items()) { - if (std::unique_ptr bake_item = move_common_socket_value_to_bake_item( - *bundle_item.type, bundle_item.value, std::nullopt, r_geometry_bake_items)) + if (const auto *socket_value = std::get_if( + &bundle_item.value.value)) { + if (std::unique_ptr bake_item = move_common_socket_value_to_bake_item( + *socket_value->type, socket_value->value, std::nullopt, r_geometry_bake_items)) + { + bundle_bake_item->items.append(BundleBakeItem::Item{ + bundle_item.key, + BundleBakeItem::SocketValue{socket_value->type->idname, std::move(bake_item)}}); + } + } + else if (const auto *internal_value = std::get_if( + &bundle_item.value.value)) + { + const ImplicitSharingInfo *sharing_info = internal_value->value.get(); + if (sharing_info) { + sharing_info->add_user(); + } bundle_bake_item->items.append(BundleBakeItem::Item{ - bundle_item.key, bundle_item.type->idname, std::move(bake_item)}); + bundle_item.key, + BundleBakeItem::InternalValue{ImplicitSharingPtr<>{sharing_info}}}); } } } @@ -271,21 +287,34 @@ Array> move_socket_values_to_bake_items(const Span(*bundle_ptr); for (const BundleBakeItem::Item &item : item->items) { - const bNodeSocketType *stype = node_socket_type_find(item.socket_idname); - if (!stype) { - return false; + if (const auto *socket_value = std::get_if(&item.value)) { + const bNodeSocketType *stype = node_socket_type_find(socket_value->socket_idname); + if (!stype) { + return false; + } + if (!stype->geometry_nodes_cpp_type) { + return false; + } + BUFFER_FOR_CPP_TYPE_VALUE(*stype->geometry_nodes_cpp_type, buffer); + if (!copy_bake_item_to_socket_value( + *socket_value->value, stype->type, {}, r_attribute_map, buffer)) + { + return false; + } + bundle.add(item.key, nodes::BundleItemSocketValue{stype, buffer}); + stype->geometry_nodes_cpp_type->destruct(buffer); } - if (!stype->geometry_nodes_cpp_type) { - return false; - } - BUFFER_FOR_CPP_TYPE_VALUE(*stype->geometry_nodes_cpp_type, buffer); - if (!copy_bake_item_to_socket_value( - *item.value, stype->type, {}, r_attribute_map, buffer)) + if (const auto *internal_value = std::get_if(&item.value)) { - return false; + const auto *internal_data = dynamic_cast( + internal_value->value.get()); + if (!internal_data) { + continue; + } + internal_data->add_user(); + bundle.add(item.key, + nodes::BundleItemInternalValue{ImplicitSharingPtr{internal_data}}); } - bundle.add(item.key, *stype, buffer); - stype->geometry_nodes_cpp_type->destruct(buffer); } bke::SocketValueVariant::ConstructIn(r_value, std::move(bundle_ptr)); return true; diff --git a/source/blender/blenlib/BLI_implicit_sharing_ptr.hh b/source/blender/blenlib/BLI_implicit_sharing_ptr.hh index 60cd0521440..0c625f43a9e 100644 --- a/source/blender/blenlib/BLI_implicit_sharing_ptr.hh +++ b/source/blender/blenlib/BLI_implicit_sharing_ptr.hh @@ -26,6 +26,8 @@ template class ImplicitS const T *data_ = nullptr; public: + using element_type = T; + ImplicitSharingPtr() = default; explicit ImplicitSharingPtr(const T *data) : data_(data) {} @@ -219,4 +221,8 @@ class ImplicitSharingPtrAndData { } }; +template static constexpr bool is_ImplicitSharingPtr_strong_v = false; +template +static constexpr bool is_ImplicitSharingPtr_strong_v> = true; + } // namespace blender diff --git a/source/blender/editors/space_node/node_socket_tooltip.cc b/source/blender/editors/space_node/node_socket_tooltip.cc index 63efeaa5f82..9059c2f5e73 100644 --- a/source/blender/editors/space_node/node_socket_tooltip.cc +++ b/source/blender/editors/space_node/node_socket_tooltip.cc @@ -701,7 +701,16 @@ class SocketTooltipBuilder { }); for (const geo_log::BundleValueLog::Item &item : sorted_items) { this->add_space(); - const std::string type_name = TIP_(item.type->label); + std::string type_name; + if (const bke::bNodeSocketType *const *socket_type = + std::get_if(&item.type)) + { + type_name = TIP_((*socket_type)->label); + } + else if (const StringRefNull *internal_type_name = std::get_if(&item.type)) + { + type_name = *internal_type_name; + } this->add_text_field_mono( fmt::format(fmt::runtime("\u2022 \"{}\" ({})\n"), item.key, type_name)); } diff --git a/source/blender/nodes/NOD_geometry_nodes_bundle.hh b/source/blender/nodes/NOD_geometry_nodes_bundle.hh index 936c1ee62ea..031c1905d80 100644 --- a/source/blender/nodes/NOD_geometry_nodes_bundle.hh +++ b/source/blender/nodes/NOD_geometry_nodes_bundle.hh @@ -14,6 +14,37 @@ namespace blender::nodes { +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; +}; + +/** + * Other classes can derive from this to be able to store custom internal data in a bundle. + */ +class BundleItemInternalValueMixin : public ImplicitSharingMixin { + public: + /** UI name for the type. */ + virtual StringRefNull type_name() const = 0; +}; + +struct BundleItemInternalValue { + ImplicitSharingPtr value; +}; + +struct BundleItemValue { + std::variant value; + + /** + * Attempts to cast the stored value to the given type. This may do implicit conversions. + */ + template + std::optional as_socket_value(const bke::bNodeSocketType &socket_type) const; + template std::optional as() const; +}; + /** * A bundle is a map containing keys and their corresponding values. Values are stored as the type * they have in Geometry Nodes (#bNodeSocketType::geometry_nodes_cpp_type). @@ -24,8 +55,7 @@ class Bundle : public ImplicitSharingMixin { public: struct StoredItem { std::string key; - const bke::bNodeSocketType *type; - void *value; + BundleItemValue value; }; private: @@ -33,17 +63,6 @@ class Bundle : public ImplicitSharingMixin { Vector buffers_; public: - struct Item { - const bke::bNodeSocketType *type; - const void *value; - - /** - * Attempts to cast the stored value to the given type. This may do implicit conversions. - */ - template std::optional as(const bke::bNodeSocketType &socket_type) const; - template std::optional as() const; - }; - Bundle(); Bundle(const Bundle &other); Bundle(Bundle &&other) noexcept; @@ -53,12 +72,12 @@ class Bundle : public ImplicitSharingMixin { static BundlePtr create(); - bool add(StringRef key, const bke::bNodeSocketType &type, const void *value); - void add_new(StringRef key, const bke::bNodeSocketType &type, const void *value); - void add_override(StringRef key, const bke::bNodeSocketType &type, const void *value); - bool add_path(StringRef path, const bke::bNodeSocketType &type, const void *value); - void add_path_new(StringRef path, const bke::bNodeSocketType &type, const void *value); - void add_path_override(StringRef path, const bke::bNodeSocketType &type, const void *value); + bool add(StringRef key, const BundleItemValue &value); + void add_new(StringRef key, const BundleItemValue &value); + void add_override(StringRef key, const BundleItemValue &value); + bool add_path(StringRef path, const BundleItemValue &value); + void add_path_new(StringRef path, const BundleItemValue &value); + void add_path_override(StringRef path, const BundleItemValue &value); template void add(StringRef key, T value); template void add_override(StringRef key, T value); @@ -69,9 +88,9 @@ class Bundle : public ImplicitSharingMixin { bool contains(StringRef key) const; bool contains_path(StringRef path) const; - std::optional lookup(StringRef key) const; - std::optional lookup_path(Span path) const; - std::optional lookup_path(StringRef path) const; + const BundleItemValue *lookup(StringRef key) const; + const BundleItemValue *lookup_path(Span path) const; + const BundleItemValue *lookup_path(StringRef path) const; template std::optional lookup(StringRef key) const; template std::optional lookup_path(StringRef path) const; @@ -83,18 +102,28 @@ class Bundle : public ImplicitSharingMixin { BundlePtr copy() const; void delete_self() override; + + /** Create the combined path by inserting '/' between each element. */ + static std::string combine_path(const Span path); }; template -inline std::optional Bundle::Item::as(const bke::bNodeSocketType &socket_type) const +inline std::optional BundleItemValue::as_socket_value( + const bke::bNodeSocketType &dst_socket_type) const { - if (!this->value || !this->type) { + const BundleItemSocketValue *socket_value = std::get_if(&this->value); + if (!socket_value) { return std::nullopt; } - const void *converted_value = this->value; - BUFFER_FOR_CPP_TYPE_VALUE(*socket_type.geometry_nodes_cpp_type, buffer); - if (this->type != &socket_type) { - if (!implicitly_convert_socket_value(*this->type, this->value, socket_type, buffer)) { + if (!socket_value->value || !socket_value->type) { + return std::nullopt; + } + 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; @@ -114,7 +143,7 @@ template constexpr bool is_valid_static_bundle_item_type() if constexpr (fn::is_field_v) { return geo_nodes_is_field_base_type_v; } - if constexpr (is_same_any_v) { + if constexpr (is_same_any_v) { return true; } return !geo_nodes_type_stored_as_SocketValueVariant_v; @@ -141,11 +170,52 @@ template inline const bke::bNodeSocketType *socket_type_info_by_stat return bke::node_socket_type_find_static(*socket_type); } -template inline std::optional Bundle::Item::as() const +template constexpr bool is_valid_internal_bundle_item_type() { - static_assert(is_valid_static_bundle_item_type()); - if (const bke::bNodeSocketType *socket_type = socket_type_info_by_static_type()) { - return this->as(*socket_type); + if constexpr (is_ImplicitSharingPtr_strong_v) { + if constexpr (std::is_base_of_v) { + return true; + } + } + return false; +} + +template inline std::optional BundleItemValue::as() const +{ + static_assert(is_valid_static_bundle_item_type() || is_valid_internal_bundle_item_type()); + if constexpr (is_valid_internal_bundle_item_type()) { + using SharingInfoT = typename T::element_type; + const auto *internal_value = std::get_if(&this->value); + if (!internal_value) { + return std::nullopt; + } + const BundleItemInternalValueMixin *sharing_info = internal_value->value.get(); + const SharingInfoT *converted_value = dynamic_cast(sharing_info); + if (!converted_value) { + return std::nullopt; + } + sharing_info->add_user(); + return ImplicitSharingPtr{converted_value}; + } + if constexpr (std::is_same_v) { + const BundleItemSocketValue *socket_value = std::get_if(&this->value); + 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(); + } + return std::nullopt; + } + if (const bke::bNodeSocketType *dst_socket_type = socket_type_info_by_static_type()) { + return this->as_socket_value(*dst_socket_type); } /* Can't lookup this type directly currently. */ BLI_assert_unreachable(); @@ -154,7 +224,7 @@ template inline std::optional Bundle::Item::as() const template inline std::optional Bundle::lookup(const StringRef key) const { - const std::optional item = this->lookup(key); + const BundleItemValue *item = this->lookup(key); if (!item) { return std::nullopt; } @@ -163,7 +233,7 @@ template inline std::optional Bundle::lookup(const StringRef key) template inline std::optional Bundle::lookup_path(const StringRef path) const { - const std::optional item = this->lookup_path(path); + const BundleItemValue *item = this->lookup_path(path); if (!item) { return std::nullopt; } @@ -173,43 +243,61 @@ template inline std::optional Bundle::lookup_path(const StringRef template inline void to_stored_type(T &&value, Fn &&fn) { using DecayT = std::decay_t; - static_assert(is_valid_static_bundle_item_type()); - const bke::bNodeSocketType *socket_type = socket_type_info_by_static_type(); - BLI_assert(socket_type); - if constexpr (geo_nodes_type_stored_as_SocketValueVariant_v) { - auto value_variant = bke::SocketValueVariant::From(std::forward(value)); - fn(*socket_type, &value_variant); + static_assert( + is_valid_static_bundle_item_type() || is_valid_internal_bundle_item_type() || + is_same_any_v); + if constexpr (std::is_same_v) { + fn(std::forward(value)); + } + else if constexpr (std::is_same_v) { + fn(BundleItemValue{std::forward(value)}); + } + else if constexpr (std::is_same_v) { + fn(BundleItemValue{std::forward(value)}); + } + else if constexpr (is_valid_internal_bundle_item_type()) { + const BundleItemInternalValueMixin *sharing_info = value.get(); + if (sharing_info) { + sharing_info->add_user(); + } + fn(BundleItemValue{BundleItemInternalValue{ImplicitSharingPtr{sharing_info}}}); + } + else if (const bke::bNodeSocketType *socket_type = socket_type_info_by_static_type()) { + if constexpr (geo_nodes_type_stored_as_SocketValueVariant_v) { + auto value_variant = bke::SocketValueVariant::From(std::forward(value)); + fn(BundleItemValue{BundleItemSocketValue{socket_type, &value_variant}}); + } + else { + fn(BundleItemValue{BundleItemSocketValue{socket_type, &value}}); + } } else { - fn(*socket_type, &value); + /* All allowed types should be handled above already. */ + BLI_assert_unreachable(); } } template inline void Bundle::add(const StringRef key, T value) { - to_stored_type(value, [&](const bke::bNodeSocketType &type, const void *value) { - this->add(key, type, value); - }); + to_stored_type(value, [&](const BundleItemValue &item_value) { this->add(key, item_value); }); } template inline void Bundle::add_path(const StringRef path, T value) { - to_stored_type(value, [&](const bke::bNodeSocketType &type, const void *value) { - this->add_path(path, type, value); - }); + to_stored_type(value, + [&](const BundleItemValue &item_value) { this->add_path(path, item_value); }); } template inline void Bundle::add_override(const StringRef key, T value) { - to_stored_type(value, [&](const bke::bNodeSocketType &type, const void *value) { - this->add_override(key, type, value); - }); + to_stored_type(value, + [&](const BundleItemValue &item_value) { this->add_override(key, item_value); }); } template inline void Bundle::add_path_override(const StringRef path, T value) { - to_stored_type(value, [&](const bke::bNodeSocketType &type, const void *value) { - this->add_path_override(path, type, value); + to_stored_type(value, [&](const BundleItemValue &item_value) { + this->add_path_override(path, item_value); }); } diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index 5a62286d740..9e5d683d897 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -191,7 +191,7 @@ class BundleValueLog : public ValueLog { public: struct Item { std::string key; - const bke::bNodeSocketType *type; + std::variant type; }; Vector items; 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 5ac51512892..74d86331603 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc @@ -116,7 +116,7 @@ static void node_geo_exec(GeoNodeExecParams params) } void *input_ptr = params.low_level_lazy_function_params().try_get_input_data_ptr(i); BLI_assert(input_ptr); - bundle.add(name, *stype, input_ptr); + bundle.add(name, BundleItemSocketValue{stype, input_ptr}); } 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 e694cd4cd11..76a21e430c7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc @@ -123,14 +123,23 @@ static void node_geo_exec(GeoNodeExecParams params) if (!stype || !stype->geometry_nodes_cpp_type) { continue; } - const std::optional value = bundle->lookup(name); + const BundleItemValue *value = bundle->lookup(name); if (!value) { params.error_message_add(NodeWarningType::Error, fmt::format(fmt::runtime(TIP_("Value not found: \"{}\"")), name)); continue; } + const auto *socket_value = std::get_if(&value->value); + if (!socket_value) { + params.error_message_add( + NodeWarningType::Error, + fmt::format("{}: \"{}\"", TIP_("Cannot get internal value from bundle"), name)); + continue; + } void *output_ptr = lf_params.get_output_data_ptr(i); - if (!implicitly_convert_socket_value(*value->type, value->value, *stype, output_ptr)) { + if (!implicitly_convert_socket_value( + *socket_value->type, socket_value->value, *stype, output_ptr)) + { construct_socket_default_value(*stype, output_ptr); } lf_params.output_set(i); diff --git a/source/blender/nodes/intern/geometry_nodes_bundle.cc b/source/blender/nodes/intern/geometry_nodes_bundle.cc index 856697bdc8e..a57379351cd 100644 --- a/source/blender/nodes/intern/geometry_nodes_bundle.cc +++ b/source/blender/nodes/intern/geometry_nodes_bundle.cc @@ -2,6 +2,8 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ +#include + #include "BKE_node_socket_value.hh" #include "BLI_cpp_type.hh" @@ -46,7 +48,11 @@ Bundle::Bundle() = default; Bundle::~Bundle() { for (StoredItem &item : items_) { - item.type->geometry_nodes_cpp_type->destruct(item.value); + 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); @@ -56,7 +62,7 @@ Bundle::~Bundle() Bundle::Bundle(const Bundle &other) { for (const StoredItem &item : other.items_) { - this->add_new(item.key, *item.type, item.value); + this->add_new(item.key, item.value); } } @@ -90,35 +96,48 @@ Bundle &Bundle::operator=(Bundle &&other) noexcept return *this; } -void Bundle::add_new(const StringRef key, const bke::bNodeSocketType &type, const void *value) +[[maybe_unused]] static bool is_valid_key(const StringRef key) { - BLI_assert(!this->contains(key)); - 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(value, buffer); - items_.append(StoredItem{std::move(key), &type, buffer}); - buffers_.append(buffer); + return key.find('/') == StringRef::not_found; } -void Bundle::add_override(const StringRef key, const bke::bNodeSocketType &type, const void *value) +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(); + } +} + +void Bundle::add_override(const StringRef key, const BundleItemValue &value) { this->remove(key); - this->add_new(key, type, value); + this->add_new(key, value); } -bool Bundle::add(const StringRef key, const bke::bNodeSocketType &type, const void *value) +bool Bundle::add(const StringRef key, const BundleItemValue &value) { if (this->contains(key)) { return false; } - this->add_new(key, type, value); + this->add_new(key, value); return true; } -void Bundle::add_path_override(const StringRef path, - const bke::bNodeSocketType &type, - const void *value) +void Bundle::add_path_override(const StringRef path, const BundleItemValue &value) { BLI_assert(!path.is_empty()); BLI_assert(!path.endswith("/")); @@ -127,15 +146,11 @@ void Bundle::add_path_override(const StringRef path, if (sep == StringRef::not_found) { const StringRef key = path; this->remove(key); - this->add_new(key, type, value); + this->add_new(key, value); return; } const StringRef first_part = path.substr(0, sep); - BundlePtr child_bundle; - const std::optional item = this->lookup(first_part); - if (item && item->type->type == SOCK_BUNDLE) { - child_bundle = static_cast(item->value)->get(); - } + BundlePtr child_bundle = this->lookup(first_part).value_or(nullptr); if (!child_bundle) { child_bundle = Bundle::create(); } @@ -144,55 +159,53 @@ void Bundle::add_path_override(const StringRef path, child_bundle = child_bundle->copy(); } child_bundle->tag_ensured_mutable(); - const_cast(*child_bundle).add_path_override(path.substr(sep + 1), type, value); + const_cast(*child_bundle).add_path_override(path.substr(sep + 1), value); bke::SocketValueVariant child_bundle_value = bke::SocketValueVariant::From( std::move(child_bundle)); - this->add(first_part, *bke::node_socket_type_find_static(SOCK_BUNDLE), &child_bundle_value); + this->add( + first_part, + BundleItemSocketValue{bke::node_socket_type_find_static(SOCK_BUNDLE), &child_bundle_value}); } -bool Bundle::add_path(StringRef path, const bke::bNodeSocketType &type, const void *value) +bool Bundle::add_path(StringRef path, const BundleItemValue &value) { if (this->contains_path(path)) { return false; } - this->add_path_new(path, type, value); + this->add_path_new(path, value); return true; } -void Bundle::add_path_new(StringRef path, const bke::bNodeSocketType &type, const void *value) +void Bundle::add_path_new(StringRef path, const BundleItemValue &value) { BLI_assert(!this->contains_path(path)); - this->add_path_override(path, type, value); + this->add_path_override(path, value); } -std::optional Bundle::lookup(const StringRef key) const +const BundleItemValue *Bundle::lookup(const StringRef key) const { for (const StoredItem &item : items_) { if (item.key == key) { - return Item{item.type, item.value}; + return &item.value; } } - return std::nullopt; + return nullptr; } -std::optional Bundle::lookup_path(const Span path) const +const BundleItemValue *Bundle::lookup_path(const Span path) const { BLI_assert(!path.is_empty()); const StringRef first_elem = path[0]; - const std::optional item = this->lookup(first_elem); + const BundleItemValue *item = this->lookup(first_elem); if (!item) { - return std::nullopt; + return nullptr; } if (path.size() == 1) { return item; } - if (item->type->type != SOCK_BUNDLE) { - return std::nullopt; - } - const BundlePtr child_bundle = - static_cast(item->value)->get(); + const BundlePtr child_bundle = item->as().value_or(nullptr); if (!child_bundle) { - return std::nullopt; + return nullptr; } return child_bundle->lookup_path(path.drop_front(1)); } @@ -213,7 +226,7 @@ static Vector split_path(const StringRef path) return path_elems; } -std::optional Bundle::lookup_path(const StringRef path) const +const BundleItemValue *Bundle::lookup_path(const StringRef path) const { const Vector path_elems = split_path(path); return this->lookup_path(path_elems); @@ -224,16 +237,21 @@ BundlePtr Bundle::copy() const BundlePtr copy_ptr = Bundle::create(); Bundle © = const_cast(*copy_ptr); for (const StoredItem &item : items_) { - copy.add_new(item.key, *item.type, item.value); + copy.add_new(item.key, item.value); } return copy_ptr; } 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) { - item.type->geometry_nodes_cpp_type->destruct(item.value); + 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; @@ -243,6 +261,7 @@ bool Bundle::remove(const StringRef key) bool Bundle::contains(const StringRef key) const { + BLI_assert(is_valid_key(key)); for (const StoredItem &item : items_) { if (item.key == key) { return true; @@ -253,7 +272,12 @@ bool Bundle::contains(const StringRef key) const bool Bundle::contains_path(const StringRef path) const { - return this->lookup_path(path).has_value(); + return this->lookup_path(path) != nullptr; +} + +std::string Bundle::combine_path(const Span path) +{ + return fmt::format("{}", fmt::join(path, "/")); } void Bundle::delete_self() diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index f2206ec9c1e..7fbb82c5bd7 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -331,7 +331,16 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons Vector items; if (const BundlePtr bundle = value_variant.extract()) { for (const Bundle::StoredItem &item : bundle->items()) { - items.append({item.key, item.type}); + if (const BundleItemSocketValue *socket_value = std::get_if( + &item.value.value)) + { + items.append({item.key, {socket_value->type}}); + } + if (const BundleItemInternalValue *internal_value = std::get_if( + &item.value.value)) + { + items.append({item.key, {internal_value->value->type_name()}}); + } } } store_logged_value(this->allocator->construct(std::move(items)));