HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
APEX_ParmDict.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: APEX_ParmDict.h (APEX Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __APEX_FLEXIBLEDICT_H__
12 #define __APEX_FLEXIBLEDICT_H__
13 
14 #include "APEX_API.h"
15 #include "APEX_Buffer.h"
16 #include "APEX_COW.h" // IWYU pragma: export
17 #include "APEX_Include.h"
18 #include "APEX_Types.h"
19 #include <GU/GU_Detail.h>
20 #include <UT/UT_Array.h>
21 #include <UT/UT_ArrayMap.h>
22 #include <UT/UT_ArrayStringMap.h>
23 #include <UT/UT_Assert.h>
24 #include <UT/UT_Base64.h>
25 #include <UT/UT_OptionEntry.h>
26 #include <UT/UT_Options.h>
27 #include <UT/UT_StringArray.h>
28 #include <UT/UT_StringHolder.h>
29 #include <UT/UT_StringStream.h>
30 #include <UT/UT_UniquePtr.h>
31 #include <UT/UT_ValArray.h>
32 #include <UT/UT_WorkBuffer.h>
33 #include <SYS/SYS_Types.h>
34 
35 #include <new>
36 #include <typeindex>
37 #include <utility>
38 
39 // For UT::ArraySet.
40 namespace UT
41 {
42 template <typename T>
43 struct DefaultClearer;
44 
45 template <>
46 struct DefaultClearer<apex::APEX_TrackedArgument>
47 {
49  static bool isClear(const apex::APEX_TrackedArgument &v) { return v.offset == -1; }
51  {
52  new ((void *)p) apex::APEX_TrackedArgument();
53  }
54  static const bool clearNeedsDestruction = true;
55 };
56 
57 }; // namespace UT
58 
59 namespace apex
60 {
61 
62 class APEX_ParmDict;
65 
66 class APEX_Graph;
67 class APEX_Signature;
68 
70 {
71 public:
72  static constexpr UT_StringLit theTypeSuffix = ".__type__";
73 
75  {
76  myBuffer = UTmakeUnique<APEX_Buffer>();
77  myExternalBuffer = nullptr;
78  }
79 
80  APEX_ParmDict(APEX_Buffer *external);
81 
83  {
84  myBuffer = UTmakeUnique<APEX_Buffer>();
85  myExternalBuffer = nullptr;
86  mergeUtOptions(opt, true);
87  }
88 
89  void operator=(const UT_OptionsHolder &opt)
90  {
91  myMap.clear();
92  myBuffer = UTmakeUnique<APEX_Buffer>();
93  myExternalBuffer = nullptr;
94  mergeUtOptions(opt, true);
95  }
96 
98  {
99  // UTdebugPrint("copy construct ParmDict");
100  // utZoneScopedN("APEX_ParmDict copy assign");
101  if (&other == this)
102  return *this;
103  myBuffer = UTmakeUnique<APEX_Buffer>();
104  myExternalBuffer = other.myExternalBuffer;
105  if (!myExternalBuffer)
106  {
107  myMap.clear();
108  update(other, true, true);
109  }
110 
111  myDataId = other.myDataId;
112  return *this;
113  }
114 
115  APEX_ParmDict(const APEX_ParmDict &other) { *this = other; }
116 
117  bool contains(const UT_StringRef &key) const
118  {
119  return myMap.contains(key);
120  }
121 
122  bool empty() const
123  {
124  return myMap.empty();
125  }
126 
127  exint size() const
128  {
129  return myMap.size();
130  }
131 
132  void bindGraphData(const APEX_Graph &graph, const APEX_PortIDRange &ports);
133  APEX_TrackedArgument *getHandle(const UT_StringRef &key);
134  const APEX_TrackedArgument *getHandle(const UT_StringRef &key) const;
135 
136  template <typename T>
137  const T *get(const UT_StringRef &key) const
138  {
139  auto it = myMap.find(key);
140  if (it.atEnd())
141  return nullptr;
142  return castArg<T>(&it->second);
143  }
144 
145  template <typename T>
146  T *get(const UT_StringRef &key)
147  {
148  auto it = myMap.find(key);
149  if (it.atEnd())
150  return nullptr;
151  return castArg<T>(&it->second);
152  }
153 
154  template <typename T>
155  void set(
156  const UT_StringRef &key,
157  const T &value,
158  bool add_missing = true,
159  bool allow_type_change = false,
160  bool bump_data_id = true)
161  {
162  if (!isValidKey(key))
163  {
164  UT_WorkBuffer msg;
165  msg.format("set() called with invalid key {}", key);
166  UT_ASSERT_MSG(false, msg.buffer());
167  return;
168  }
169 
170  auto it = myMap.find(key);
171  const APEX_TypeDefinitionBase *type_defn = findTypeDef<T>();
172  if (!type_defn)
173  {
174  UT_ASSERT_MSG(false, "set() called with unregistered type");
175  return;
176  }
178  if (it.atEnd())
179  {
180  if (!add_missing)
181  return;
182  myMap[key] = appendTrackedArgument(type_defn);
183  arg = &myMap[key];
184  }
185  else
186  {
187  arg = &it->second;
188  if (type_defn != arg->type_defn)
189  {
190  if (!allow_type_change)
191  return;
192  // playing it safe and not allowing type change on a buffer we
193  // don't own
194  // FIXME: currently not deallocating on the buffer if we change
195  // the type of any entry
196  else
197  it->second = appendTrackedArgument(type_defn);
198  }
199  }
200  T &dst = *castArg<T>(arg);
201  dst = value;
202  arg->bumpDataId();
203  if (bump_data_id)
204  bumpDataId();
205  // UTdebugPrint(key, arg->modCounter);
206  }
207 
208  bool set(
209  const UT_StringRef &key,
210  const APEX_Argument &arg,
211  bool add_missing = true,
212  bool allow_type_change = false,
213  bool force_update = false,
214  bool bump_data_id = true,
215  bool bump_data_id_on_conversion = true);
216 
217  bool set(
218  const UT_StringRef &key,
219  const APEX_TrackedArgument &arg,
220  bool add_missing = true,
221  bool allow_type_change = false,
222  bool force_update = false,
223  bool bump_data_id = true,
224  bool bump_data_id_on_conversion = true);
225 
226  void renameEntry(const UT_StringRef &key, const UT_StringRef &newname);
227 
228  bool sharesBuffer(const APEX_ParmDict &other) const;
229 
230  // void setPyDict(void *pydict);
231 
232  // void writeToUtOptions(UT_Options &opt);
233  // void writeToPyDict(void *pydict);
234 
235  // FIXME: No const-correctness here! As the buffer is pending a rewrite
236  // I won't clutter the current API
237  // APEX_Buffer *buffer();
238  APEX_Buffer *buffer() const;
239 
240  UT_StringArray compareDataIds(const APEX_ParmDict &other, bool check_missing = false);
241 
242  void update(
243  const APEX_ParmDict &other,
244  bool add_missing = false,
245  bool allow_type_change = false,
246  bool force_copy = false,
247  UT_StringArray *changelist = nullptr,
248  bool bump_data_id_on_conversion = true);
249  void mergeUtOptions(
250  const UT_OptionsHolder &opt_h,
251  bool clear = false,
252  bool add_missing = true,
253  bool allow_type_change = true,
254  const APEX_Signature *signature = nullptr);
255  void updateUtOptions(
256  UT_Options &opt_h,
257  bool clear = false,
258  bool include_geometry = false,
259  bool include_typeinfo = true) const;
260  void updateUtOptions(
261  UT_OptionsHolder &opt_h,
262  bool clear = false,
263  bool include_geometry = false,
264  bool include_typeinfo = true) const;
265 
267  const UT_ArrayStringMap<APEX_TrackedArgument> &map() const { return myMap; }
268 
269  void clear()
270  {
271  myMap.clear();
272  if (!myExternalBuffer)
273  myBuffer->clear();
274  bumpDataId();
275  }
276 
277  /// This function removes any previously set value, so that subsequent
278  /// execution will act as if set() were never called on that key. However,
279  /// this does not destruct the previously-created value for this key, and
280  /// that data will persist until this whole dictionary is cleared!
281  bool remove(const UT_StringRef &key);
282 
283  APEX_DataID dataId() const { return myDataId; }
284  void bumpDataId() { myDataId = APEX_Buffer::nextDataId(); }
285  void copyDataId(const APEX_ParmDict &other) { myDataId = other.dataId(); }
286 
287  static bool isValidKey(const UT_StringRef &key,
288  UT_StringHolder *err_msg=nullptr);
289 
290 private:
291  template <typename T>
292  void setReinterpretFloatArray(
293  const UT_StringRef &name,
294  const UT_Array<Float> &src,
295  bool add_missing)
296  {
297  static_assert(std::is_same_v<typename T::value_type, Float>);
298  auto tmp = ApexArray<T>();
299  tmp->append((T *)src.data(), src.size() / T::tuple_size);
300  set<ApexArray<T>>(name, tmp, add_missing, false, false);
301  }
302 
303  APEX_TrackedArgument appendTrackedArgument(const APEX_TypeDefinitionBase *type_defn)
304  {
305  APEX_Argument arg = buffer()->append(type_defn);
306  return {{arg.buffer, arg.type_defn, arg.offset}, /*default*/};
307  }
308 
310  UT_UniquePtr<APEX_Buffer> myBuffer;
311  APEX_Buffer *myExternalBuffer;
313 };
314 
315 template <typename T>
316 static std::type_index
317 typeIndexT()
318 {
319  return std::type_index(typeid(T));
320 }
321 
322 void
324  UT_Options &opt,
325  const UT_StringRef &key,
326  const APEX_Argument &arg,
327  bool include_geometry = false,
328  bool include_typeinfo = true);
329 
330 } // namespace apex
331 
332 #endif // header guard
static APEX_DataID nextDataId()
Get a new unique data ID.
APEX_ParmDict & operator=(const APEX_ParmDict &other)
Definition: APEX_ParmDict.h:97
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
APEX_ParmDict(const APEX_ParmDict &other)
#define APEX_API
Definition: APEX_API.h:21
bool empty() const
int64 exint
Definition: SYS_Types.h:125
SYS_FORCE_INLINE const char * buffer() const
void setUtOption(UT_Options &opt, const UT_StringRef &key, const APEX_Argument &arg, bool include_geometry=false, bool include_typeinfo=true)
bool contains(const UT_StringRef &key) const
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1859
GLuint buffer
Definition: glcorearb.h:660
exint size() const
Definition: UT_Array.h:653
Holds all of the memory for execution state of a compiled APEX graph.
Definition: APEX_Buffer.h:96
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
void operator=(const UT_OptionsHolder &opt)
Definition: APEX_ParmDict.h:89
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
const UT_ArrayStringMap< APEX_TrackedArgument > & map() const
static void clear(apex::APEX_TrackedArgument &v)
Definition: APEX_ParmDict.h:48
int64 APEX_DataID
Definition: APEX_Buffer.h:85
APEX_DataID dataId() const
static void clearConstruct(apex::APEX_TrackedArgument *p)
Definition: APEX_ParmDict.h:50
constexpr auto set(type rhs) -> int
Definition: core.h:610
const APEX_TypeDefinitionBase * type_defn
Definition: APEX_Buffer.h:180
UT_ArrayStringMap< APEX_TrackedArgument > & map()
exint append(const T &v)
Definition: APEX_COW.h:58
GLuint const GLchar * name
Definition: glcorearb.h:786
GLenum GLenum dst
Definition: glcorearb.h:1793
A map of string to various well defined value types.
Definition: UT_Options.h:84
size_t format(const char *fmt, const Args &...args)
exint size() const
void copyDataId(const APEX_ParmDict &other)
void set(const UT_StringRef &key, const T &value, bool add_missing=true, bool allow_type_change=false, bool bump_data_id=true)
T * data()
Definition: UT_Array.h:849
APEX_ParmDict(const UT_OptionsHolder &opt)
Definition: APEX_ParmDict.h:82
Represents a location for a single object inside of an APEX_Buffer.
Definition: APEX_Buffer.h:176
static bool isClear(const apex::APEX_TrackedArgument &v)
Definition: APEX_ParmDict.h:49
GLenum src
Definition: glcorearb.h:1793