HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UN_Data.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: UN_Data.h ( UN Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __UN_Data_h__
13 #define __UN_Data_h__
14 
15 #include "UN_API.h"
16 #include "UN_CustomData.h"
17 #include "UN_DataBuffer.h"
18 #include "UN_DataIndexMap.h"
19 #include "UN_GenericData.h"
20 #include "UN_Include.h"
21 
22 // ============================================================================
23 /// A generic container of the data buffers.
24 ///
25 /// NOTE: This class is generally not trivially relocatable, because it sets
26 /// a pointer to its member (myIndexMap) on another member (myCustomData).
27 
29 {
30 public:
31  /// Constructors and destructors.
32  UN_Data( UN_CustomDataPtr custom_data = UN_CustomDataPtr() );
33  ~UN_Data() = default;
34 
35  /// Move operators.
36  UN_Data(UN_Data&&);
38 
39 protected:
40  /// This container can have large data, so generally, forbid
41  /// the costly copy operations to the public.
42  UN_Data(const UN_Data&);
43  UN_Data & operator=(const UN_Data &);
44 
45 public:
46  /// @{ Returns the custom data container, if one was provided.
48  { return myCustomData.get(); }
49  const UN_CustomData * customData() const
50  { return myCustomData.get(); }
51  /// @}
52 
53  /// Returns a range for iterating valid IDs
55  IDRange idRange() const
56  { return myIndexMap.idRange(); }
57 
58  /// Returns a range for iterating valid IDs in an ascending order.
61  { return myIndexMap.orderedIDRange(); }
62 
63  /// Returns a list of all the valid IDs in this container
65  { return myIndexMap.ids(); }
66 
67  /// Returns a sorted list of all the valid IDs in this container
69  { return myIndexMap.sortedIDs(); }
70 
71  /// Returns the number of valid data items in the buffer.
72  UN_DataSize size() const
73  { return myIndexMap.size(); }
74 
75  /// Returns the upper limit on the valid indices issued by this container.
76  /// Ie, maximum index value plus one.
78  { return myIndexMap.indexSize(); }
79 
80  /// Returns the upper limit on the numerical value of the valid data IDs
81  /// issued by this container. Ie, maximum ID plus one.
83  { return myIndexMap.idSize(); }
84 
85 protected:
86  /// Merges another data container into this one.
87  ///
88  /// If @p fuse_id_zero is true, the data for the ID zero is not copied
89  /// to a brand new data slot, but is combined with existing slot ID of zero.
90  /// Some data containers (subclasses) use ID of zero for a special
91  /// entity that is treated differently than the rest.
92  /// Notably, the node data container uses ID of zero for the root node,
93  /// and the root node from the src should not become a regular node here.
94  /// Instead, src root ID maps to dst root ID and their data is combined.
96  bool combine_id_zero = false )
97  {
98  return myIndexMap.merge(
99  src_data.myIndexMap,
100  combine_id_zero );
101  }
102 
103  /// Adds a slot for new data in the data buffers of this container,
104  /// and returns the data ID by which this slot can be refered to,
105  /// and also at which index in a buffer the data slot is expected to be.
106  /// A slot usually corresponds to a concrete graph element (eg, a node),
107  /// and data buffer slots store some info about it, (eg, a name or a type).
108  /// NOTE: The derived classes must insert a corresponding entry in all
109  /// of their data buffers, at the given index.
110  /// The index can also be found by `dataIndex(ID)`.
111  std::pair< UN_DataID, UN_DataIndex >
113  { return myIndexMap.addEntry(); }
114 
115  /// Returns an existing data buffer index for the given data ID,
116  /// if already exists in the container, or adds a new slot for the
117  /// data and returns the newly created index for it.
118  std::pair< UN_DataID, UN_DataIndex >
120  { return myIndexMap.findOrAddEntry( data_id ); }
121 
122  /// Removes the data slot from this container and frees the slot
123  /// it used to occupy. The slot may be reused in the future for other
124  /// data item (but with different data ID).
125  /// After calling this method the container will have no knowledge
126  /// of the data by this ID.
127  /// Returns true on successs; false if the data was not found.
128  bool removeData( UN_DataID data_id )
129  { return myIndexMap.removeEntry( data_id ); }
130 
131  /// Frees the data slots occupied by all the data.
132  /// @param 'reset_next_id' If true, the data ID generator is reset to zero.
133  void removeAllData( bool reset_next_id )
134  { myIndexMap.removeAllEntries( reset_next_id );}
135 
136 
137  /// Returns true if the given ID refers to a valid data slot (entries)
138  /// in the data buffers.
139  /// Eg, for node data buffers, if such a node exists and is valid.
140  bool isValid( UN_DataID data_id ) const
141  { return myIndexMap.isValid( data_id ); }
142 
143  /// Returns the data index into the data buffer arrays
144  /// (ie, arrays implemented and owned by the sub-classes).
145  /// The data index locates a slot (entries in the data buffers)
146  /// for the graph element (eg, for a node) by the given ID.
148  { return myIndexMap.indexFromID(id); }
149 
150  /// Returns the size of the data buffers that use indexing based
151  /// on the `dataIndex()` lookup call that maps IDs to indices.
152  /// The size is the lagest index ever issued plus one.
153  /// Ie, it is the number of data entries a buffer can currently hold.
155  { return myIndexMap.dataBufferSize(); }
156 
157  /// Returns the number of free slots in the data buffer.
158  /// Ie, the buffer consists of data entry slots that are either occupied
159  /// or free, and this menthod returns the free slots count.
161  { return myIndexMap.freeDataBufferSize(); }
162 
163  /// Returns the number of valid data entries in the data buffer.
164  /// Ie, the buffer consists of data entry slots that are either occupied
165  /// or free, and this menthod returns the occupied slots count.
167  { return myIndexMap.usedDataBufferSize(); }
168 
169 protected:
170  /// Helper method to copy-assign the value to an entry in the data buffer.
171  template<typename V, typename B>
172  inline void
173  setData( B &buffer, UN_DataID id, const V &value )
174  {
175  UN_DataBufferUtils::setData( buffer, dataIndex(id), value );
176  }
177 
178  /// Helper method to move-assign the value to an entry in the data buffer.
179  template<typename V, typename B>
180  inline void
182  {
183  UN_DataBufferUtils::setData( buffer, dataIndex(id),
184  std::forward<V>(value));
185  }
186 
187  /// Helper method to return a const ref to an entry in the data buffer.
188  template<typename V, typename B>
189  inline const V &
190  getDataRef( const B &buffer, UN_DataID id, const V &default_value ) const
191  {
192  return UN_DataBufferUtils::getDataRef( buffer, dataIndex(id),
193  default_value );
194  }
195 
196  /// Helper method to return a value constructed from an entry
197  /// in the data buffer. This is useful when the type returned here
198  /// differs from the underlying entry type.
199  /// In particular, this is needed for UN_BoolDataBuffer whose underlying
200  /// entries are bits (for which we can't return a const reference)
201  /// while here we are returning bool (byte).
202  template<typename V, typename B>
203  inline V
204  getDataVal( const B &buffer, UN_DataID id, const V &default_value ) const
205  {
206  return UN_DataBufferUtils::getDataVal( buffer, dataIndex(id),
207  default_value );
208  }
209 
210  /// Helper method to return a value moved from an entry in the data buffer.
211  template<typename V, typename B>
212  inline V
213  stealData( B &buffer, UN_DataID id, const V &default_value )
214  {
215  return UN_DataBufferUtils::stealData( buffer, dataIndex(id),
216  default_value );
217  }
218 
219  /// Helper method to update an entry value in the data buffer.
220  /// It updates a data value in-place in the data buffer,
221  /// which for complex data values (eg, dictionaries or arrays) is faster
222  /// than getting and setting the value (although stealing and setting
223  /// may be comparable). This is a convenient and useful idiom, that
224  /// tries to avoid the buffer data aliasing issues.
225  /// Intended usage:
226  /// updateData(buff, id, [&key, &value](auto &x) { x[key] = value; });
227  template<typename OP, typename B>
228  inline void
229  updateData( B &buffer, UN_DataID id, const OP &op )
230  {
231  UN_DataBufferUtils::updateData( buffer, dataIndex(id), op );
232  }
233 
234 public:
235  /// Adds a new named generic data buffer with a caller-specified default
236  /// value. If a buffer with the same name already exists and the type
237  /// matches, its existing ID is returned. If the name exists but the
238  /// type conflicts, an invalid ID is returned.
239  template<typename D>
243  const D &default_value )
244  {
245  return myGenericData.addBuffer( name, type, default_value,
246  dataBufferSize() );
247  }
248 
249  /// Returns the type of the generic buffer identified by the given ID.
252  {
253  return myGenericData.bufferType( id );
254  }
255 
256  /// Returns the ID of the generic buffer with the given name, or an
257  /// invalid ID if no such buffer exists.
260  {
261  return myGenericData.findBuffer( name );
262  }
263 
264  /// Returns the name of the generic buffer identified by the given ID.
265  const UT_StringHolder &
267  {
268  return myGenericData.bufferName( id );
269  }
270 
271 protected:
272  /// Sets the data value in a generic buffer for a given data ID.
273  template<typename T>
274  inline void
276  const T &value )
277  {
278  myGenericData.setData( buf_id, dataIndex(id), value );
279  }
280 
281  /// Sets the data value in a generic buffer via move.
282  template<typename T>
283  inline void
285  {
286  myGenericData.setData( buf_id, dataIndex(id),
287  std::forward<T>(value) );
288  }
289 
290  /// Returns a const ref to the data value in a generic buffer.
291  template<typename T>
292  inline const T &
294  {
295  return myGenericData.getDataRef<T>( buf_id, dataIndex(id) );
296  }
297 
298  /// Returns a copy of a data value from a generic buffer.
299  /// Useful when cannot call genericDataRef() for types that cannot return
300  /// by reference (eg, bool with bit-packed UN_DataBuffer<bool>).
301  template<typename T>
302  inline T
304  {
305  return myGenericData.getDataVal<T>( buf_id, dataIndex(id) );
306  }
307 
308  /// Moves the data value out of a generic buffer.
309  template<typename T>
310  inline T
312  {
313  return myGenericData.stealData<T>( buf_id, dataIndex(id) );
314  }
315 
316  /// Updates the data value in a generic buffer in-place via a callable.
317  template<typename T, typename OP>
318  inline void
320  const OP &op )
321  {
322  myGenericData.updateData<T>( buf_id, dataIndex(id), op );
323  }
324 
325 
326 
327  /// Adds a data slot at the given index to all generic buffers.
329  { myGenericData.addData( index ); }
330 
331  /// Clears the generic data at the given index to defaults.
333  { myGenericData.clearData( index ); }
334 
335  /// Removes all data from all generic buffers.
337  { myGenericData.removeAllData(); }
338 
339  /// Grows all generic buffers to the given minimum capacity.
341  UN_DataSize min_capacity )
342  { myGenericData.setCapacityIfNeeded(
343  min_capacity ); }
344 
345  /// Merges generic data from another UN_Data container.
347  const UN_DataMergeInfo &merge_info )
348  { myGenericData.mergeData(
349  src.myGenericData, merge_info ); }
350 
351  /// Returns true if all generic buffers have the expected size.
353  UN_DataSize expected_size ) const
354  { return myGenericData.isDataSizeConsistent(
355  expected_size ); }
356 
357 private:
358  /// A mapping from a data ID to the index into the data buffer arrays.
359  /// An index locates the slot (entries in the data buffers)
360  /// for the graph element (eg, for a node) the given by the data ID.
361  UN_DataIndexMap myIndexMap;
362 
363  /// Cointainer for custom data buffers.
364  UN_CustomDataPtr myCustomData;
365 
366  /// Container for dynamically added generic data buffers.
367  UN_GenericData myGenericData;
368 };
369 
370 #endif
371 
IDRange idRange() const
Definition: UN_Data.h:55
UN_GenericBufferType
Supported types for generic data buffers.
V getDataVal(const B &buffer, UN_DataIndex index, const V &default_value)
UN_DataSize indexSize() const
Definition: UN_Data.h:77
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void addGenericData(UN_DataIndex index)
Adds a data slot at the given index to all generic buffers.
Definition: UN_Data.h:328
UN_DataSize idSize() const
Definition: UN_Data.h:82
T genericDataVal(UN_GenericBufferID buf_id, UN_DataID id) const
Definition: UN_Data.h:303
std::pair< UN_DataID, UN_DataIndex > findOrAddData(UN_DataID data_id)
Definition: UN_Data.h:119
bool isValid(UN_DataID data_id) const
Definition: UN_Data.h:140
void updateGenericData(UN_GenericBufferID buf_id, UN_DataID id, const OP &op)
Updates the data value in a generic buffer in-place via a callable.
Definition: UN_Data.h:319
std::pair< UN_DataID, UN_DataIndex > addData()
Definition: UN_Data.h:112
UN_DataSize usedDataBufferSize() const
Definition: UN_Data.h:166
#define UN_API
Definition: UN_API.h:11
GLuint buffer
Definition: glcorearb.h:660
bool removeData(UN_DataID data_id)
Definition: UN_Data.h:128
UT_IteratorRange< IDIterator > IDRange
UN_DataIndex dataIndex(UN_DataID id) const
Definition: UN_Data.h:147
UN_DataSize dataBufferSize() const
Definition: UN_Data.h:154
void setData(B &buffer, UN_DataID id, V &&value)
Helper method to move-assign the value to an entry in the data buffer.
Definition: UN_Data.h:181
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
V stealData(B &buffer, UN_DataID id, const V &default_value)
Helper method to return a value moved from an entry in the data buffer.
Definition: UN_Data.h:213
UN_CustomData * customData()
Returns the custom data container, if one was provided.
Definition: UN_Data.h:47
void setGenericData(UN_GenericBufferID buf_id, UN_DataID id, const T &value)
Sets the data value in a generic buffer for a given data ID.
Definition: UN_Data.h:275
const UN_CustomData * customData() const
Returns the custom data container, if one was provided.
Definition: UN_Data.h:49
const T & genericDataRef(UN_GenericBufferID buf_id, UN_DataID id) const
Returns a const ref to the data value in a generic buffer.
Definition: UN_Data.h:293
void setGenericData(UN_GenericBufferID buf_id, UN_DataID id, T &&value)
Sets the data value in a generic buffer via move.
Definition: UN_Data.h:284
UN_DataIDList dataIDs() const
Returns a list of all the valid IDs in this container.
Definition: UN_Data.h:64
UN_DataSize freeDataBufferSize() const
Definition: UN_Data.h:160
GLuint const GLchar * name
Definition: glcorearb.h:786
T stealGenericData(UN_GenericBufferID buf_id, UN_DataID id)
Moves the data value out of a generic buffer.
Definition: UN_Data.h:311
V getDataVal(const B &buffer, UN_DataID id, const V &default_value) const
Definition: UN_Data.h:204
void updateData(B &buffer, UN_DataID id, const OP &op)
Definition: UN_Data.h:229
void removeAllGenericData()
Removes all data from all generic buffers.
Definition: UN_Data.h:336
Maintains a mapping from data ID to data index in the data buffer.
void setGenericDataCapacityIfNeeded(UN_DataSize min_capacity)
Grows all generic buffers to the given minimum capacity.
Definition: UN_Data.h:340
bool isGenericDataSizeConsistent(UN_DataSize expected_size) const
Returns true if all generic buffers have the expected size.
Definition: UN_Data.h:352
const UT_StringHolder & genericBufferName(UN_GenericBufferID id) const
Returns the name of the generic buffer identified by the given ID.
Definition: UN_Data.h:266
void mergeGenericData(const UN_Data &src, const UN_DataMergeInfo &merge_info)
Merges generic data from another UN_Data container.
Definition: UN_Data.h:346
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
void setData(B &buffer, UN_DataID id, const V &value)
Helper method to copy-assign the value to an entry in the data buffer.
Definition: UN_Data.h:173
void removeAllData(bool reset_next_id)
Definition: UN_Data.h:133
UN_GenericBufferType genericBufferType(UN_GenericBufferID id) const
Returns the type of the generic buffer identified by the given ID.
Definition: UN_Data.h:251
UN_GenericBufferID findGenericBuffer(const UT_StringRef &name) const
Definition: UN_Data.h:259
UN_DataMergeInfo mergeData(const UN_Data &src_data, bool combine_id_zero=false)
Definition: UN_Data.h:95
UN_DataSize size() const
Returns the number of valid data items in the buffer.
Definition: UN_Data.h:72
UN_DataIDList sortedDataIDs() const
Returns a sorted list of all the valid IDs in this container.
Definition: UN_Data.h:68
void clearGenericData(UN_DataIndex index)
Clears the generic data at the given index to defaults.
Definition: UN_Data.h:332
UT_UniquePtr< UN_CustomData > UN_CustomDataPtr
Definition: UN_CustomData.h:23
UN_GenericBufferID addGenericBuffer(const UT_StringRef &name, UN_GenericBufferType type, const D &default_value)
Definition: UN_Data.h:241
Definition: UNI_ID.h:25
const V & getDataRef(const B &buffer, UN_DataID id, const V &default_value) const
Helper method to return a const ref to an entry in the data buffer.
Definition: UN_Data.h:190
UT_IteratorRange< OrderedIDIterator > OrderedIDRange
OrderedIDRange orderedIDRange() const
Definition: UN_Data.h:60
GLenum src
Definition: glcorearb.h:1793