GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/compiler/CustomData.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 27 32 84.4%
Functions: 5 6 83.3%
Branches: 8 32 25.0%

Line Branch Exec Source
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 {
23 OPENVDB_USE_VERSION_NAMESPACE
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.
33 225 class CustomData
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
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
225 CustomData() : mData() {}
42
43 206 static UniquePtr create()
44 {
45 206 UniquePtr data(new CustomData);
46 206 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 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 104 getData(const Name& name) const
81 {
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 const auto iter = mData.find(name);
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 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 104 getData(const Name& name) const
94 {
95 104 Metadata::ConstPtr data = getData(name);
96 104 if (!data) return nullptr;
97 104 const TypedDataCacheT* const typed =
98 104 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 78 getOrInsertData(const Name& name)
109 {
110
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
78 const auto iter = mData.find(name);
111
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
78 if (iter == mData.end()) {
112 1 Metadata::Ptr data(new TypedDataCacheT());
113 mData[name] = data;
114 return static_cast<TypedDataCacheT* const>(data.get());
115 }
116 else {
117
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
77 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 1 insertData(const Name& name,
129 const typename TypedDataCacheT::Ptr data)
130 {
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 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 2 mData[name] = data->copy();
142 }
143 1 }
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 22 insertData(const Name& name,
152 const Metadata::Ptr data)
153 {
154
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 const auto iter = mData.find(name);
155
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if (iter == mData.end()) {
156 mData[name] = data;
157 }
158 else {
159 iter->second->copy(*data);
160 }
161 22 }
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
180