diff options
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_key.h')
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_key.h | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h new file mode 100644 index 00000000000..4f8b2dc9f8f --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2013 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup depsgraph + */ + +#pragma once + +#include "intern/builder/deg_builder_rna.h" +#include "intern/depsgraph_type.h" +#include "intern/node/deg_node_component.h" +#include "intern/node/deg_node_id.h" +#include "intern/node/deg_node_operation.h" + +#include "DNA_ID.h" + +#include "RNA_access.h" +#include "RNA_types.h" + +struct ID; +struct PropertyRNA; + +namespace blender::deg { + +struct TimeSourceKey { + TimeSourceKey() = default; + + string identifier() const; +}; + +struct ComponentKey { + ComponentKey() = default; + + inline ComponentKey(const ID *id, NodeType type, const char *name = "") + : id(id), type(type), name(name) + { + } + + string identifier() const; + + const ID *id = nullptr; + NodeType type = NodeType::UNDEFINED; + const char *name = ""; +}; + +struct OperationKey { + OperationKey() = default; + + inline OperationKey(const ID *id, NodeType component_type, const char *name, int name_tag = -1) + : id(id), + component_type(component_type), + component_name(""), + opcode(OperationCode::OPERATION), + name(name), + name_tag(name_tag) + { + } + + OperationKey(const ID *id, + NodeType component_type, + const char *component_name, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(OperationCode::OPERATION), + name(name), + name_tag(name_tag) + { + } + + OperationKey(const ID *id, NodeType component_type, OperationCode opcode) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(""), + name_tag(-1) + { + } + + OperationKey(const ID *id, + NodeType component_type, + const char *component_name, + OperationCode opcode) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(""), + name_tag(-1) + { + } + + OperationKey(const ID *id, + NodeType component_type, + OperationCode opcode, + const char *name, + int name_tag = -1) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(name), + name_tag(name_tag) + { + } + + OperationKey(const ID *id, + NodeType component_type, + const char *component_name, + OperationCode opcode, + const char *name, + int name_tag = -1) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(name), + name_tag(name_tag) + { + } + + OperationKey(OperationKey &&other) noexcept = default; + OperationKey &operator=(OperationKey &&other) = default; + + OperationKey(const OperationKey &other) = default; + OperationKey &operator=(const OperationKey &other) = default; + + string identifier() const; + + const ID *id = nullptr; + NodeType component_type = NodeType::UNDEFINED; + const char *component_name = ""; + OperationCode opcode = OperationCode::OPERATION; + const char *name = ""; + int name_tag = -1; +}; + +/* Similar to the the OperationKey but does not contain external references, which makes it + * suitable to identify operations even after the original database or graph was destroyed. + * The downside of this key over the OperationKey is that it performs string allocation upon + * the key construction. */ +struct PersistentOperationKey : public OperationKey { + /* Create the key which identifies the given operation node. */ + PersistentOperationKey(const OperationNode *operation_node) + { + const ComponentNode *component_node = operation_node->owner; + const IDNode *id_node = component_node->owner; + + /* Copy names over to our object, so that the key stays valid even after the `operation_node` + * is destroyed.*/ + component_name_storage_ = component_node->name; + name_storage_ = operation_node->name; + + /* Assign fields used by the OperationKey API. */ + id = id_node->id_orig; + component_type = component_node->type; + component_name = component_name_storage_.c_str(); + opcode = operation_node->opcode; + name = name_storage_.c_str(); + name_tag = operation_node->name_tag; + } + + PersistentOperationKey(PersistentOperationKey &&other) noexcept : OperationKey(other) + { + component_name_storage_ = std::move(other.component_name_storage_); + name_storage_ = std::move(other.name_storage_); + + /* Re-assign pointers to the strings. + * This is needed because string content can actually change address if the string uses the + * small string optimization. */ + component_name = component_name_storage_.c_str(); + name = name_storage_.c_str(); + } + + PersistentOperationKey &operator=(PersistentOperationKey &&other) = delete; + + PersistentOperationKey(const PersistentOperationKey &other) = delete; + PersistentOperationKey &operator=(const PersistentOperationKey &other) = delete; + + private: + string component_name_storage_; + string name_storage_; +}; + +struct RNAPathKey { + RNAPathKey(ID *id, const char *path, RNAPointerSource source); + RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop, RNAPointerSource source); + + string identifier() const; + + ID *id; + PointerRNA ptr; + PropertyRNA *prop; + RNAPointerSource source; +}; + +} // namespace blender::deg |