HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_AttributeHolder.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  * COMMENTS:
7  */
8 
9 #ifndef __PDG_ATTRIBUTE_HOLDER_H__
10 #define __PDG_ATTRIBUTE_HOLDER_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_AttributeData.h"
15 
16 #include <UT/UT_NonCopyable.h>
17 #include <SYS/SYS_Types.h>
18 
19 /**
20  * Reference to a PDG attribute instance, either owned or shared. Contains the
21  * type information for the attribute as well as various flags (no copy, export,
22  * etc).
23  */
25 {
26 public:
27  /// Constructs an invalid attribute holder
29  : myAttribute(nullptr)
30  , myType(PDG_AttributeType::eUndefined)
31  , myFlags(0)
32  , myIsOwner(false)
33  , myIsStale(false)
34  , myIsConcat(false)
35  , myIsChanged(false)
36  {
37  }
38 
39  /// Move constructs an attribute holder
41  : myType(other.myType)
42  , myFlags(other.myFlags)
43  , myIsOwner(other.myIsOwner)
44  , myIsStale(other.myIsStale)
45  , myIsConcat(other.myIsConcat)
46  , myIsChanged(other.myIsChanged)
47  {
48  myAttribute = other.myAttribute;
49 
50  other.myAttribute = nullptr;
51  other.myIsOwner = false;
52  other.myIsStale = false;
53  other.myIsConcat = false;
54  other.myIsChanged = false;
55  }
56 
57  /// Constructs an attribute holder from an attribute data pointer, with
58  /// the specified ownership
61  uint16 flags,
62  bool owner,
63  bool stale)
64  : myAttribute(attribute)
65  , myType(type)
66  , myFlags(flags)
67  , myIsOwner(owner)
68  , myIsStale(stale)
69  , myIsConcat(false)
70  , myIsChanged(false)
71  {
72  }
73 
74  /// Destroys the attribute own by this holder if it exists, and the own
75  /// flag is set
77  {
78  if (myAttribute && myIsOwner)
79  delete myAttribute;
80  }
81 
82  /// Move assignment is permitted
84  {
85  if (this != &other)
86  {
87  reset(other.myAttribute, other.myType, other.myFlags,
88  other.myIsOwner, other.myIsStale, other.myIsConcat);
89 
90  other.myAttribute = nullptr;
91  other.myIsOwner = false;
92  other.myIsStale = false;
93  other.myIsConcat = false;
94  other.myIsChanged = false;
95  }
96 
97  return *this;
98  }
99 
100  /// Returns the memory usage of the attribute, including the data only if
101  /// this holder owns it.
102  int64 getMemoryUsage(bool inclusive) const
103  {
104  int64 mem = inclusive ? sizeof(*this) : 0;
105  if (myIsOwner)
106  mem += myAttribute->getMemoryUsage(true);
107  return mem;
108  }
109 
110  /// Returns whether or not this holder has taken ownership of the attribute
111  inline bool isOwner() const
112  {
113  return myIsOwner;
114  }
115 
116  /// Returns true if this is a stale owned attribute, which happens during
117  /// deserialization
118  inline bool isStale() const
119  {
120  return myIsStale;
121  }
122 
123  /// Returns true if this attribute contains data that was concatenated
124  /// from multiple input attributes
125  inline bool isConcat() const
126  {
127  return myIsConcat;
128  }
129 
130  /// Returns true if this attribute has been modified since the changed
131  /// flag was cleared
132  inline bool isChanged() const
133  {
134  return myIsChanged;
135  }
136 
137  /// Takes ownership of the attribute pointer if it is not already owned. If
138  /// it is, the pointer is returned back directly
140  {
141  if (!myAttribute || myIsOwner)
142  return myAttribute;
143 
144  myAttribute = myAttribute->clone();
145  myIsOwner = true;
146  return myAttribute;
147  }
148 
149  /// Swaps the attributes in this holder and the specified holder, but
150  /// leaves the flags unmodified.
151  inline void swapAttributes(PDG_AttributeHolder& holder)
152  {
153  std::swap(myAttribute, holder.myAttribute);
154 
155  bool is_owner = myIsOwner;
156  bool is_concat = myIsConcat;
157  bool is_changed = myIsChanged;
158 
159  myIsOwner = holder.myIsOwner;
160  myIsConcat = holder.myIsConcat;
161  myIsChanged = holder.myIsChanged;
162 
163  holder.myIsOwner = is_owner;
164  holder.myIsConcat = is_concat;
165  holder.myIsChanged = is_changed;
166  }
167 
168  /// Resets the holder to a nullptr, thus making it an invalid holder
169  inline void reset()
170  {
171  if (myAttribute && myIsOwner)
172  delete myAttribute;
173 
174  myAttribute = nullptr;
175  myIsOwner = false;
176  myIsStale = false;
177  myIsConcat = false;
178  myIsChanged = false;
179  }
180 
181  /// Changes the attribute owned by this holder, and deletes the existing
182  /// attribute if one existed and was owned by this holder.
185  uint16 flags,
186  bool own,
187  bool stale,
188  bool concat)
189  {
190  if (myAttribute && myIsOwner)
191  delete myAttribute;
192 
193  if (!attribute)
194  {
195  myAttribute = nullptr;
196  myIsOwner = false;
197  myIsStale = false;
198  myIsConcat = false;
199  myIsChanged = false;
201  myFlags = 0;
202  }
203  else
204  {
205  myAttribute = (PDG_AttributeData*)(attribute);
206  myIsOwner = own;
207  myIsStale = (own && stale);
208  myIsConcat = concat;
209  myIsChanged = false;
210  myType = type;
211  myFlags = flags;
212  }
213 
214  return myAttribute;
215  }
216 
217  /// Changes the attribute owned by this holder so that it has a shallow
218  /// holder to the one owned by the specififed attribute, or copies it
219  /// depending on the own arg. Deletes the existing attribute if one existed
220  /// and was owned by this holder
222  bool own,
223  bool sync_flags)
224  {
225  if (myAttribute && myIsOwner)
226  delete myAttribute;
227 
228  if (!holder)
229  {
230  myAttribute = nullptr;
231  myIsOwner = false;
232  myIsStale = false;
233  myIsConcat = false;
234  myIsChanged = false;
235 
237  myFlags = 0;
238  return nullptr;
239  }
240 
241  if (own)
242  {
243  myAttribute = holder.myAttribute->clone();
244  myIsOwner = true;
245  myIsStale = false;
246  myIsConcat = false;
247  myIsChanged = false;
248  }
249  else
250  {
251  myAttribute = holder.myAttribute;
252  myIsOwner = false;
253  myIsStale = false;
254  myIsConcat = false;
255  myIsChanged = false;
256  }
257 
258  myType = holder.myType;
259  if (sync_flags)
260  myFlags = holder.myFlags;
261 
262  return myAttribute;
263  }
264 
265  /// Const accessor for the own attribute - could be nullptr
266  template <typename Attribute=PDG_AttributeData>
267  inline const Attribute* attribute() const
268  {
269  return ((const Attribute*)myAttribute);
270  }
271 
272  /// Non-const accessor for the own attribute - could be nullptr
273  template <typename Attribute=PDG_AttributeData>
275  {
276  return ((Attribute*)myAttribute);
277  }
278 
279  /// Returns true if the underlying attribute has any data
280  template <typename Attribute=PDG_AttributeData>
281  inline bool hasData() const
282  {
283  const Attribute* attrib = attribute<Attribute>();
284  if (!attrib || !attrib->hasData())
285  return false;
286  return true;
287  }
288 
289  /// Const arrow operator, invalid to use if this holder refers to a
290  /// null attribute.
291  inline const PDG_AttributeData* operator->() const
292  {
293  return myAttribute;
294  }
295 
296  /// Nonconst arrow operator, invalid to use if this holder refers to a
297  /// null attribute.
299  {
300  return myAttribute;
301  }
302 
303  /// Const dereference, invalid to use if this holder refers to a
304  /// null attribute.
305  inline const PDG_AttributeData& operator*() const
306  {
307  return *myAttribute;
308  }
309 
310  /// Nonconst dereference, invalid to use if this holder refers to a
311  /// null attribute.
313  {
314  return *myAttribute;
315  }
316 
317  /// Compares two attribute holders and returns true if they're the same.
318  /// The data is only compared if all other aspects are the same.
319  inline bool operator==(const PDG_AttributeHolder& other) const
320  {
321  // Null holders are never equal
322  if (!myAttribute || !other.myAttribute)
323  return false;
324 
325  // Type and flag check
326  if ((myFlags != other.myFlags) || (myType != other.myType))
327  return false;
328 
329  // Identical attribute pointers are always equal
330  if (myAttribute == other.myAttribute)
331  return true;
332 
333  // Compare data
334  return (myAttribute->compare(other.myAttribute));
335  }
336 
337  /// Compares two attribute holders for inequality - the inverse of the above
338  /// function.
339  inline bool operator!=(const PDG_AttributeHolder& other) const
340  {
341  return !(*this == other);
342  }
343 
344  /// Returns true if this holder refers to a valid attribute pointer,
345  /// else false.
346  inline operator bool() const
347  {
348  return (myAttribute != nullptr);
349  }
350 
351  /// Returns true if the type of the template argumented is a match for the
352  /// the type of this holder
353  template <typename Attribute>
354  inline bool typeMatch() const
355  {
356  return (Attribute::TypeEnum == myType) ||
357  (Attribute::TypeEnum == PDG_AttributeType::eUndefined);
358  }
359 
360  /// Returns the attribute type
361  inline PDG_AttributeType type() const
362  {
363  return myType;
364  }
365 
366  /// Returns the attribute flags
367  inline uint16 flags() const
368  {
369  return myFlags;
370  }
371 
372  /// Returns true if this attribute has at least one flag set
373  inline bool hasAnyFlags() const
374  {
375  return (myFlags != 0);
376  }
377 
378  /// Returns true if this attribute has the specified flag
379  inline bool hasFlag(PDG_AttributeFlag flag) const
380  {
381  return (myFlags & (uint16)flag);
382  }
383 
384  /// Returns true if this attribute has all of the specified flags set
385  inline bool hasFlags(uint16 flags) const
386  {
387  return ((myFlags & (uint16)flags) == (uint16)flags);
388  }
389 
390  /// Returns true if this attribute has any of the specified flags set
391  inline bool hasAnyFlags(uint16 flags) const
392  {
393  return ((myFlags & flags) != 0);
394  }
395 
396  /// Sets a flag on the attribute. Returns true if the flag was changed
397  /// as a result of this operation.
398  inline bool setFlag(PDG_AttributeFlag flag,
399  bool set)
400  {
401  bool has_flag = hasFlag(flag);
402 
403  if (set)
404  {
405  myFlags |= (uint16)flag;
406  myIsChanged |= !has_flag;
407 
408  return !has_flag;
409  }
410  else
411  {
412  myFlags &= ~((uint16)flag);
413  myIsChanged |= has_flag;
414 
415  return has_flag;
416  }
417  }
418 
419  /// Sets the flags on the attribute directly. Returns true if any of the
420  /// flags were modified.
421  inline bool setFlags(uint16 flags)
422  {
423  bool changed = (myFlags != flags);
424  myFlags = flags;
425  myIsChanged |= changed;
426 
427  return changed;
428  }
429 
430  /// Sets the concat bit to the specified value
431  inline void setIsConcat(bool is_concat)
432  {
433  myIsConcat = is_concat;
434  }
435 
436  /// Sets the changed bit to the specified value
437  inline void setIsChanged(bool is_changed)
438  {
439  myIsChanged = is_changed;
440  }
441 
442  /// Concats the specified attribute with the attribute in this holder
443  template <typename Attribute>
444  inline bool concat(const PDG_AttributeHolder& other)
445  {
446  myIsConcat = true;
447  return attribute<Attribute>()->concat(other.attribute<Attribute>());
448  }
449 
450  /// Sets the size of the attribute
451  template <typename Attribute>
452  inline bool adjustSize(int offset)
453  {
454  return attribute<Attribute>()->adjustSize(offset);
455  }
456 
457  /// Clears the attribute
458  template <typename Attribute>
459  inline void clear()
460  {
461  return attribute<Attribute>()->clear();
462  }
463 
464  /// Swaps the specified attribute with the attribute in this holder
465  template <typename Attribute>
466  inline void swap(PDG_AttributeHolder& other)
467  {
468  attribute<Attribute>()->swap(other.attribute<Attribute>());
469  }
470 
471 private:
472  PDG_AttributeData* myAttribute;
473  uint16 myFlags : 16;
474  PDG_AttributeType myType : 8;
475  bool myIsOwner : 1;
476  bool myIsStale : 1;
477  bool myIsConcat : 1;
478  bool myIsChanged : 1;
479 };
480 
481 #endif
bool setFlag(PDG_AttributeFlag flag, bool set)
GLbitfield flags
Definition: glcorearb.h:1596
unsigned short uint16
Definition: SYS_Types.h:38
PDG_AttributeData * reset(const PDG_AttributeHolder &holder, bool own, bool sync_flags)
PDG_AttributeType type() const
Returns the attribute type.
PDG_AttributeData * own()
bool hasFlag(PDG_AttributeFlag flag) const
Returns true if this attribute has the specified flag.
bool adjustSize(int offset)
Sets the size of the attribute.
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1639
bool isOwner() const
Returns whether or not this holder has taken ownership of the attribute.
Undefined or uninitialized attribute type.
PDG_AttributeHolder()
Constructs an invalid attribute holder.
#define PDG_API
Definition: PDG_API.h:23
void clear()
Clears the attribute.
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7172
Attribute * attribute()
Non-const accessor for the own attribute - could be nullptr.
bool hasAnyFlags(uint16 flags) const
Returns true if this attribute has any of the specified flags set.
bool hasFlags(uint16 flags) const
Returns true if this attribute has all of the specified flags set.
const PDG_AttributeData * operator->() const
void reset()
Resets the holder to a nullptr, thus making it an invalid holder.
PDG_AttributeHolder(PDG_AttributeHolder &&other)
Move constructs an attribute holder.
GLintptr offset
Definition: glcorearb.h:665
GLboolean reset
Definition: glad.h:5138
PDG_AttributeData * operator->()
bool operator!=(const PDG_AttributeHolder &other) const
PDG_AttributeData * reset(const PDG_AttributeData *attribute, PDG_AttributeType type, uint16 flags, bool own, bool stale, bool concat)
bool concat(const PDG_AttributeHolder &other)
Concats the specified attribute with the attribute in this holder.
PDG_AttributeHolder(PDG_AttributeData *attribute, PDG_AttributeType type, uint16 flags, bool owner, bool stale)
bool setFlags(uint16 flags)
void setIsChanged(bool is_changed)
Sets the changed bit to the specified value.
long long int64
Definition: SYS_Types.h:116
PDG_AttributeType
Enumeration of possible attribute types.
bool operator==(const PDG_AttributeHolder &other) const
const PDG_AttributeData & operator*() const
PDG_AttributeFlag
Enumeration of extra attribute flags. Flags can be ORed together.
PDG_AttributeHolder & operator=(PDG_AttributeHolder &&other)
Move assignment is permitted.
int64 getMemoryUsage(bool inclusive) const
void swap(PDG_AttributeHolder &other)
Swaps the specified attribute with the attribute in this holder.
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
bool hasAnyFlags() const
Returns true if this attribute has at least one flag set.
uint16 flags() const
Returns the attribute flags.
void setIsConcat(bool is_concat)
Sets the concat bit to the specified value.
void swapAttributes(PDG_AttributeHolder &holder)
const Attribute * attribute() const
Const accessor for the own attribute - could be nullptr.
type
Definition: core.h:1059
std::string OIIO_UTIL_API concat(string_view s, string_view t)
virtual PDG_AttributeData * clone() const =0
Deep copies this attribute.
bool hasData() const
Returns true if the underlying attribute has any data.
PDG_AttributeData & operator*()