OpenVDB  11.0.0
CustomData.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file compiler/CustomData.h
5 ///
6 /// @authors Nick Avramoussis, Francisco Gochez
7 ///
8 /// @brief Access to the CustomData class which can provide custom user
9 /// user data to the OpenVDB AX Compiler.
10 ///
11 
12 #ifndef OPENVDB_AX_COMPILER_CUSTOM_DATA_HAS_BEEN_INCLUDED
13 #define OPENVDB_AX_COMPILER_CUSTOM_DATA_HAS_BEEN_INCLUDED
14 
15 #include <openvdb/version.h>
16 #include <openvdb/Metadata.h>
17 #include <openvdb/Types.h>
18 
19 #include <unordered_map>
20 #include <memory>
21 
22 namespace openvdb {
24 namespace OPENVDB_VERSION_NAME {
25 
26 namespace ax {
27 
28 /// @brief The custom data class is a simple container for named openvdb
29 /// metadata. Its primary use case is passing arbitrary "external" data to an
30 /// AX executable object when calling Compiler::compile. For example, it is
31 /// the mechanism by which we pass data held inside of a parent DCC to
32 /// executable AX code.
34 {
35 public:
36 
37  using Ptr = std::shared_ptr<CustomData>;
38  using ConstPtr = std::shared_ptr<const CustomData>;
39  using UniquePtr = std::unique_ptr<CustomData>;
40 
41  CustomData() : mData() {}
42 
43  static UniquePtr create()
44  {
45  UniquePtr data(new CustomData);
46  return data;
47  }
48 
49  /// @brief Reset the custom data. This will clear and delete all previously
50  /// added data. This will invalidated any executable which links to this
51  /// custom data.
52  inline void reset()
53  {
54  mData.clear();
55  }
56 
57  /// @brief Checks whether or not data of given name has been inserted
58  inline bool
59  hasData(const Name& name)
60  {
61  const auto iter = mData.find(name);
62  return (iter != mData.end());
63  }
64 
65  /// @brief Checks whether or not data of given name and type has been inserted
66  template <typename TypedDataCacheT>
67  inline bool
68  hasData(const Name& name)
69  {
70  const auto iter = mData.find(name);
71  if (iter == mData.end()) return false;
72  const TypedDataCacheT* const typed =
73  dynamic_cast<const TypedDataCacheT* const>(iter->second.get());
74  return typed != nullptr;
75  }
76 
77  /// @brief Retrieves a const pointer to data of given name. If it does not
78  /// exist, returns nullptr
79  inline const Metadata::ConstPtr
80  getData(const Name& name) const
81  {
82  const auto iter = mData.find(name);
83  if (iter == mData.end()) return Metadata::ConstPtr();
84  return iter->second;
85  }
86 
87  /// @brief Retrieves a const pointer to data of given name and type.
88  /// If it does not exist, returns nullptr
89  /// @param name Name of the data entry
90  /// @returns The metadata. If the type does not match, nullptr is returned.
91  template <typename TypedDataCacheT>
92  inline const TypedDataCacheT*
93  getData(const Name& name) const
94  {
95  Metadata::ConstPtr data = getData(name);
96  if (!data) return nullptr;
97  const TypedDataCacheT* const typed =
98  dynamic_cast<const TypedDataCacheT* const>(data.get());
99  return typed;
100  }
101 
102  /// @brief Retrieves or inserts typed metadata. If the data exists, it is
103  /// dynamic-casted to the expected type, which may result in a nullptr. If
104  /// the data does not exist it is guaranteed to be inserted and returned.
105  /// The value of the inserted data can then be modified
106  template <typename TypedDataCacheT>
107  inline TypedDataCacheT*
108  getOrInsertData(const Name& name)
109  {
110  const auto iter = mData.find(name);
111  if (iter == mData.end()) {
112  Metadata::Ptr data(new TypedDataCacheT());
113  mData[name] = data;
114  return static_cast<TypedDataCacheT* const>(data.get());
115  }
116  else {
117  return dynamic_cast<TypedDataCacheT* const>(iter->second.get());
118  }
119  }
120 
121  /// @brief Inserts data of specified type with given name.
122  /// @param name Name of the data
123  /// @param data Shared pointer to the data
124  /// @note If an entry of the given name already exists, will copy the data
125  /// into the existing entry rather than overwriting the pointer
126  template <typename TypedDataCacheT>
127  inline void
128  insertData(const Name& name,
129  const typename TypedDataCacheT::Ptr data)
130  {
131  if (hasData(name)) {
132  TypedDataCacheT* const dataToSet =
133  getOrInsertData<TypedDataCacheT>(name);
134  if (!dataToSet) {
135  OPENVDB_THROW(TypeError, "Custom data \"" + name +
136  "\" already exists with a different type.");
137  }
138  dataToSet->value() = data->value();
139  }
140  else {
141  mData[name] = data->copy();
142  }
143  }
144 
145  /// @brief Inserts data with given name.
146  /// @param name Name of the data
147  /// @param data The metadata
148  /// @note If an entry of the given name already exists, will copy the data
149  /// into the existing entry rather than overwriting the pointer
150  inline void
151  insertData(const Name& name,
152  const Metadata::Ptr data)
153  {
154  const auto iter = mData.find(name);
155  if (iter == mData.end()) {
156  mData[name] = data;
157  }
158  else {
159  iter->second->copy(*data);
160  }
161  }
162 
163 private:
164  std::unordered_map<Name, Metadata::Ptr> mData;
165 };
166 
167 // fwd declare the codegen::String and alias deprecated metadata type
168 namespace codegen { struct String; }
169 using AXStringMetadata [[deprecated("The ax::AXStringMetadata type has "
170  "been replaced with openvdb::TypedMetadata<ax::codegen::String>. The "
171  "new backend string definition can be found in ax/codegen/String.h")]] =
172  TypedMetadata<ax::codegen::String>;
173 
174 } // namespace ax
175 } // namespace OPENVDB_VERSION_NAME
176 } // namespace openvdb
177 
178 #endif // OPENVDB_AX_COMPILER_CUSTOM_DATA_HAS_BEEN_INCLUDED
179 
std::shared_ptr< const CustomData > ConstPtr
Definition: CustomData.h:38
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
bool hasData(const Name &name)
Checks whether or not data of given name and type has been inserted.
Definition: CustomData.h:68
static UniquePtr create()
Definition: CustomData.h:43
TypedDataCacheT * getOrInsertData(const Name &name)
Retrieves or inserts typed metadata. If the data exists, it is dynamic-casted to the expected type...
Definition: CustomData.h:108
const Metadata::ConstPtr getData(const Name &name) const
Retrieves a const pointer to data of given name. If it does not exist, returns nullptr.
Definition: CustomData.h:80
The custom data class is a simple container for named openvdb metadata. Its primary use case is passi...
Definition: CustomData.h:33
Definition: Exceptions.h:13
Definition: Exceptions.h:64
std::string Name
Definition: Name.h:19
void insertData(const Name &name, const typename TypedDataCacheT::Ptr data)
Inserts data of specified type with given name.
Definition: CustomData.h:128
SharedPtr< Metadata > Ptr
Definition: Metadata.h:26
std::unique_ptr< CustomData > UniquePtr
Definition: CustomData.h:39
bool hasData(const Name &name)
Checks whether or not data of given name has been inserted.
Definition: CustomData.h:59
void reset()
Reset the custom data. This will clear and delete all previously added data. This will invalidated an...
Definition: CustomData.h:52
SharedPtr< const Metadata > ConstPtr
Definition: Metadata.h:27
const TypedDataCacheT * getData(const Name &name) const
Retrieves a const pointer to data of given name and type. If it does not exist, returns nullptr...
Definition: CustomData.h:93
void insertData(const Name &name, const Metadata::Ptr data)
Inserts data with given name.
Definition: CustomData.h:151
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
std::shared_ptr< CustomData > Ptr
Definition: CustomData.h:37
CustomData()
Definition: CustomData.h:41
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212