diff options
Diffstat (limited to 'source/blender/blenkernel/intern/viewer_path.cc')
-rw-r--r-- | source/blender/blenkernel/intern/viewer_path.cc | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/viewer_path.cc b/source/blender/blenkernel/intern/viewer_path.cc new file mode 100644 index 00000000000..3074a007af4 --- /dev/null +++ b/source/blender/blenkernel/intern/viewer_path.cc @@ -0,0 +1,270 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_lib_query.h" +#include "BKE_lib_remap.h" +#include "BKE_viewer_path.h" + +#include "BLI_index_range.hh" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_string_ref.hh" + +#include "MEM_guardedalloc.h" + +#include "BLO_read_write.h" + +using blender::IndexRange; +using blender::StringRef; + +void BKE_viewer_path_init(ViewerPath *viewer_path) +{ + BLI_listbase_clear(&viewer_path->path); +} + +void BKE_viewer_path_clear(ViewerPath *viewer_path) +{ + LISTBASE_FOREACH_MUTABLE (ViewerPathElem *, elem, &viewer_path->path) { + BKE_viewer_path_elem_free(elem); + } + BLI_listbase_clear(&viewer_path->path); +} + +void BKE_viewer_path_copy(ViewerPath *dst, const ViewerPath *src) +{ + BKE_viewer_path_init(dst); + LISTBASE_FOREACH (const ViewerPathElem *, src_elem, &src->path) { + ViewerPathElem *new_elem = BKE_viewer_path_elem_copy(src_elem); + BLI_addtail(&dst->path, new_elem); + } +} + +bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b) +{ + const ViewerPathElem *elem_a = static_cast<const ViewerPathElem *>(a->path.first); + const ViewerPathElem *elem_b = static_cast<const ViewerPathElem *>(b->path.first); + + while (elem_a != nullptr && elem_b != nullptr) { + if (!BKE_viewer_path_elem_equal(elem_a, elem_b)) { + return false; + } + elem_a = elem_a->next; + elem_b = elem_b->next; + } + if (elem_a == nullptr && elem_b == nullptr) { + return true; + } + return false; +} + +void BKE_viewer_path_blend_write(struct BlendWriter *writer, const ViewerPath *viewer_path) +{ + LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) { + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto typed_elem = reinterpret_cast<IDViewerPathElem *>(elem); + BLO_write_struct(writer, IDViewerPathElem, typed_elem); + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + auto typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem); + BLO_write_struct(writer, ModifierViewerPathElem, typed_elem); + BLO_write_string(writer, typed_elem->modifier_name); + break; + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + auto typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem); + BLO_write_struct(writer, NodeViewerPathElem, typed_elem); + BLO_write_string(writer, typed_elem->node_name); + break; + } + } + } +} + +void BKE_viewer_path_blend_read_data(struct BlendDataReader *reader, ViewerPath *viewer_path) +{ + BLO_read_list(reader, &viewer_path->path); + LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) { + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + auto typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem); + BLO_read_data_address(reader, &typed_elem->modifier_name); + break; + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + auto typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem); + BLO_read_data_address(reader, &typed_elem->node_name); + break; + } + } + } +} + +void BKE_viewer_path_blend_read_lib(BlendLibReader *reader, Library *lib, ViewerPath *viewer_path) +{ + LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) { + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto typed_elem = reinterpret_cast<IDViewerPathElem *>(elem); + BLO_read_id_address(reader, lib, &typed_elem->id); + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: + case VIEWER_PATH_ELEM_TYPE_NODE: { + break; + } + } + } +} + +void BKE_viewer_path_foreach_id(LibraryForeachIDData *data, ViewerPath *viewer_path) +{ + LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) { + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto typed_elem = reinterpret_cast<IDViewerPathElem *>(elem); + BKE_LIB_FOREACHID_PROCESS_ID(data, typed_elem->id, IDWALK_CB_NOP); + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: + case VIEWER_PATH_ELEM_TYPE_NODE: { + break; + } + } + } +} + +void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const IDRemapper *mappings) +{ + LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) { + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto typed_elem = reinterpret_cast<IDViewerPathElem *>(elem); + BKE_id_remapper_apply(mappings, &typed_elem->id, ID_REMAP_APPLY_DEFAULT); + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: + case VIEWER_PATH_ELEM_TYPE_NODE: { + break; + } + } + } +} + +ViewerPathElem *BKE_viewer_path_elem_new(const ViewerPathElemType type) +{ + switch (type) { + case VIEWER_PATH_ELEM_TYPE_ID: { + IDViewerPathElem *elem = MEM_cnew<IDViewerPathElem>(__func__); + elem->base.type = type; + return &elem->base; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + ModifierViewerPathElem *elem = MEM_cnew<ModifierViewerPathElem>(__func__); + elem->base.type = type; + return &elem->base; + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + NodeViewerPathElem *elem = MEM_cnew<NodeViewerPathElem>(__func__); + elem->base.type = type; + return &elem->base; + } + } + BLI_assert_unreachable(); + return nullptr; +} + +IDViewerPathElem *BKE_viewer_path_elem_new_id() +{ + return reinterpret_cast<IDViewerPathElem *>(BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_ID)); +} + +ModifierViewerPathElem *BKE_viewer_path_elem_new_modifier() +{ + return reinterpret_cast<ModifierViewerPathElem *>( + BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_MODIFIER)); +} + +NodeViewerPathElem *BKE_viewer_path_elem_new_node() +{ + return reinterpret_cast<NodeViewerPathElem *>( + BKE_viewer_path_elem_new(VIEWER_PATH_ELEM_TYPE_NODE)); +} + +ViewerPathElem *BKE_viewer_path_elem_copy(const ViewerPathElem *src) +{ + ViewerPathElem *dst = BKE_viewer_path_elem_new(ViewerPathElemType(src->type)); + switch (ViewerPathElemType(src->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto old_elem = reinterpret_cast<const IDViewerPathElem *>(src); + auto new_elem = reinterpret_cast<IDViewerPathElem *>(dst); + new_elem->id = old_elem->id; + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + auto old_elem = reinterpret_cast<const ModifierViewerPathElem *>(src); + auto new_elem = reinterpret_cast<ModifierViewerPathElem *>(dst); + if (old_elem->modifier_name != nullptr) { + new_elem->modifier_name = BLI_strdup(old_elem->modifier_name); + } + break; + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + auto old_elem = reinterpret_cast<const NodeViewerPathElem *>(src); + auto new_elem = reinterpret_cast<NodeViewerPathElem *>(dst); + if (old_elem->node_name != nullptr) { + new_elem->node_name = BLI_strdup(old_elem->node_name); + } + break; + } + } + return dst; +} + +bool BKE_viewer_path_elem_equal(const ViewerPathElem *a, const ViewerPathElem *b) +{ + if (a->type != b->type) { + return false; + } + switch (ViewerPathElemType(a->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + auto a_elem = reinterpret_cast<const IDViewerPathElem *>(a); + auto b_elem = reinterpret_cast<const IDViewerPathElem *>(b); + return a_elem->id == b_elem->id; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + auto a_elem = reinterpret_cast<const ModifierViewerPathElem *>(a); + auto b_elem = reinterpret_cast<const ModifierViewerPathElem *>(b); + return StringRef(a_elem->modifier_name) == StringRef(b_elem->modifier_name); + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + auto a_elem = reinterpret_cast<const NodeViewerPathElem *>(a); + auto b_elem = reinterpret_cast<const NodeViewerPathElem *>(b); + return StringRef(a_elem->node_name) == StringRef(b_elem->node_name); + } + } + return false; +} + +void BKE_viewer_path_elem_free(ViewerPathElem *elem) +{ + switch (ViewerPathElemType(elem->type)) { + case VIEWER_PATH_ELEM_TYPE_ID: { + break; + } + case VIEWER_PATH_ELEM_TYPE_MODIFIER: { + auto typed_elem = reinterpret_cast<ModifierViewerPathElem *>(elem); + MEM_SAFE_FREE(typed_elem->modifier_name); + break; + } + case VIEWER_PATH_ELEM_TYPE_NODE: { + auto typed_elem = reinterpret_cast<NodeViewerPathElem *>(elem); + MEM_SAFE_FREE(typed_elem->node_name); + break; + } + } + MEM_freeN(elem); +} |