HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_IntrinsicManager.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: GA_IntrinsicManager.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_IntrinsicManager__
12 #define __GA_IntrinsicManager__
13 
14 #include "GA_API.h"
15 #include "GA_Types.h"
16 
17 #include <UT/UT_Options.h>
18 #include <UT/UT_Array.h>
19 #include <UT/UT_ArrayMap.h>
20 #include <UT/UT_StringHolder.h>
21 #include <UT/UT_ArrayStringMap.h>
22 
23 #include <stddef.h>
24 
25 
26 class GA_IntrinsicDef;
27 class UT_StringArray;
28 
29 
30 /// @brief Manager to keep track of global handle to name mappings
31 ///
32 /// Each GA_PrimitiveFactory maintains a list of intrinsic attributes.
33 /// These attribute provide a mechanism to query information about primitives
34 /// without having knowledge of the actual structure of the primitive.
35 ///
36 /// There is a unique handle (or id) for each attribute name. This class
37 /// maintains the mapping between name and handle.
38 ///
40 {
41 public:
42  /// Get the global id associated with a given token
43  static GA_GlobalIntrinsic getGlobalHandle(const UT_StringRef &token);
44 
45  /// Register a global token (returns the existing handle if it's found)
46  static GA_GlobalIntrinsic registerGlobalHandle(const UT_StringHolder &token);
47 
48  /// Find the token associated with the given global handle
49  static const UT_StringHolder &getGlobalName(GA_GlobalIntrinsic handle);
50 
51  /// Return the number of local handles defined in the manager
52  int getLocalEntries() const
53  { return myAttributes.entries(); }
54 
55  /// Extract all attribute names
56  void extractNames(UT_StringArray &names) const;
57 
58  /// @{
59  /// Mapping between global and local attributes
60  GA_LocalIntrinsic getLocalHandle(const UT_StringRef &token) const;
61  GA_LocalIntrinsic getLocalHandle(GA_GlobalIntrinsic ghandle) const;
63  {
64  return isValidHandle(lhandle)
65  ? myAttributes(lhandle)->getGlobalId()
67  }
68  /// @}
69 
70  /// Look up an attribute name from the given handle
72  {
73  return isValidHandle(handle)
74  ? myAttributes(handle)->getName()
76  }
77 
78  /// @{
79  /// Get the attribute storage (passed in during registration)
81  { return getStorage(getLocalHandle(name)); }
83  {
84  return isValidHandle(handle)
85  ? myAttributes(handle)->getStorage()
87  }
88  /// @}
89 
90  /// @{
91  /// Get the read-only flag (passed in during registration)
92  bool getReadOnly(const UT_StringRef &name) const
93  { return getReadOnly(getLocalHandle(name)); }
94  bool getReadOnly(GA_LocalIntrinsic handle) const
95  {
96  return isValidHandle(handle)
97  ? myAttributes(handle)->getReadOnly()
98  : true; // invalid handles are read only
99  }
100 
101  /// @{
102  /// Get the collapse singletons flag (passed in during registration)
104  { return getCollapseSingletons(getLocalHandle(name)); }
106  {
107  return isValidHandle(handle)
108  ? myAttributes(handle)->getCollapseSingletons()
109  : false; // invalid handles don't
110  }
111  /// @}
112 
113  /// @{
114  /// Get the attribute's user id (passed in during registration)
115  int getUserId(const UT_StringRef &name) const
116  { return getUserId(getLocalHandle(name)); }
117  int getUserId(GA_LocalIntrinsic handle) const
118  {
119  return isValidHandle(handle)
120  ? myAttributes(handle)->getUserId()
121  : -1;
122  }
123  /// @}
124 
125  /// @{
126  /// Get the attribute options (passed in during registration)
127  const UT_Options *getOptions(const UT_StringRef &name) const
128  { return getOptions(getLocalHandle(name)); }
130  {
131  return isValidHandle(handle)
132  ? &myAttributes(handle)->getOptions()
133  : NULL;
134  }
135  /// @}
136 
137  /// This enum is used to pass a boolean flag indicating whether tuples of
138  /// 1 element (singletons) can be collapsed to scalar values in a type
139  /// safe manner that avoids implicit conversions from other args in
140  /// existing calls to Registrar::addAttribute().
141  enum class CollapseSingletons : bool { NO=0, YES=1 };
142 
143  /// The Registrar class is used to register intrinsic attributes
144  /// Sample usage for a GA_Primitive sub-class might be something like:
145  /// @code
146  /// static GA_IntrinsicDef theClassIntrinsics;
147  ///
148  /// GA_IntrinsicManager::Registrar
149  /// MyClass::registerIntrinsics(GA_PrimitiveDefinition &def)
150  /// {
151  /// GA_IntrinsicManager::Registrar r =
152  /// MyBaseClass:registerIntrinsics(def);
153  /// if (r.start(theClassIntrinsics))
154  /// {
155  /// r.addAttribute(GA_STORECLASS_STRING, "intrinsic1", 0, true,
156  /// GA_IntrinsicManager::CollapseSingletons::YES);
157  /// r.addAttribute(GA_STORECLASS_FLOAT, "intrinsic2", 1, true,
158  /// GA_IntrinsicManager::CollapseSingletons::NO);
159  /// }
160  /// UT_ASSERT(r.getOk());
161  /// return r;
162  /// }
163  /// @endcode
164  class Registrar
165  {
166  public:
167  /// Copy constructor
169  : myManager(r.myManager)
170  , myDef(r.myDef)
171  , myOk(r.myOk)
172  {}
173  /// Destructor
175  {
176  end(); // Close off last definition
177  }
178  /// Assignment operator
180  {
181  myManager = r.myManager;
182  return *this;
183  }
184 
185  /// Start defining attributes for the given intrinsic definition
187  {
188  end();
189  if (myOk)
190  {
191  myOk = myManager->startDefinition(def);
192  myDef = &def;
193  }
194  return myOk;
195  }
196  /// Method to add an intrinsic attribute.
197  /// - The name must be unique through the inheritance hierarchy
198  /// - The @c user_id is used for evaluation (see GA_IntrinsicEval)
200  const UT_StringRef &name,
201  int user_id,
202  bool read_only,
203  CollapseSingletons collapse_singletons,
204  const UT_Options *options=NULL)
205  {
207  if (myOk)
208  {
209  h = myManager->addAttribute(store,
210  name, user_id, read_only,
211  collapse_singletons, options);
212  if (!GAisValidGlobalIntrinsic(h))
213  myOk = false;
214  }
215  else
217  return h;
218  }
219  /// Return status of the operation
220  bool getOk() const { return myOk; }
221 
222  private:
223  void end()
224  {
225  if (myOk && myDef)
226  myOk = myManager->endDefinition(*myDef);
227  }
228  Registrar(GA_IntrinsicManager &man)
229  : myManager(&man)
230  , myDef(NULL)
231  , myOk(true)
232  {
233  }
234  friend class GA_Primitive;
235  friend class GA_Detail;
236  GA_IntrinsicManager *myManager;
237  GA_IntrinsicDef *myDef;
238  bool myOk;
239  };
240 
241  /// Iterator class to iterate
242  /// Usage: @code
243  /// GA_IntrinsicManager::iterator it;
244  /// for (it = manager.begin(); !it.atEnd(); ++it) ...
245  /// @endcode
247  {
248  public:
249  /// Simple default constructor
251  : myManager(NULL),
252  myCurrent(0),
253  myEntries(0) { }
254  /// Copy constructor
256  {
257  *this = src;
258  }
259  /// Destructor
261  /// Assignment operator
263  {
264  myManager = src.myManager;
265  myCurrent = src.myCurrent;
266  myEntries = src.myEntries;
267  return *this;
268  }
269  /// Increment operator
270  iterator &operator++() { advance(); return *this; }
271 
272  // No post increment as it is harmful.
273 
274  /// Test to see if the iteration is complete
275  bool atEnd() const
276  {
277  return !myManager || myCurrent >= myEntries;
278  }
279  /// Advance to the next iteration
280  void advance() { myCurrent++; }
281 
282  /// Get the current attribute token
283  const UT_StringHolder &getToken() const
284  { return myManager->getName(myCurrent); }
286  { return myCurrent; }
287  /// Get the current attribute handle (global id)
288  int getIndex() const
289  { return myCurrent; }
290  private:
291  /// Private c-tor: Access this through the begin() method
292  iterator(const GA_IntrinsicManager *manager)
293  : myManager(manager),
294  myCurrent(0),
295  myEntries(manager->getLocalEntries())
296  {
297  }
298  const GA_IntrinsicManager *myManager;
299  GA_LocalIntrinsic myCurrent; // Iterate over the locals
300  int myEntries;
301 
302  friend class GA_IntrinsicManager;
303  };
304 
305  /// Start traversal of intrinsic attributes names
306  iterator begin() const { return iterator(this); }
307 
308 private:
309  /// Check to see if handle is in bounds
310  inline bool isValidHandle(GA_LocalIntrinsic h) const
311  { return h >= 0 && h < myAttributes.entries(); }
312 
313  /// The internal definition of an attribute
314  class ga_IntrinsicAttribute
315  {
316  public:
317  ga_IntrinsicAttribute(GA_StorageClass store,
318  const UT_StringHolder &name,
319  GA_GlobalIntrinsic global_id,
320  GA_LocalIntrinsic local_id,
321  int user_id,
322  bool read_only,
323  bool collapse_singletons,
324  const UT_Options *options)
325  : myOptions()
326  , myName(name)
327  , myGlobalId(global_id)
328  , myLocalId(local_id)
329  , myUserId(user_id)
330  , myStorage(store)
331  , myReadOnly(read_only)
332  , myCollapseSingletons(collapse_singletons)
333  {
334  if (options)
335  myOptions = *options;
336  }
337  ~ga_IntrinsicAttribute() {}
338 
339  const UT_StringHolder &getName() const { return myName; }
340  GA_StorageClass getStorage() const { return myStorage; }
341  const UT_Options &getOptions() const { return myOptions; }
342  int getGlobalId() const { return myGlobalId; }
343  int getLocalId() const { return myLocalId; }
344  int getUserId() const { return myUserId; }
345  bool getReadOnly() const { return myReadOnly; }
346  bool getCollapseSingletons() const
347  { return myCollapseSingletons; }
348  private:
349  UT_Options myOptions;
350  UT_StringHolder myName;
351  GA_GlobalIntrinsic myGlobalId;
352  GA_LocalIntrinsic myLocalId;
353  int myUserId;
354  GA_StorageClass myStorage;
355  bool myReadOnly;
356  bool myCollapseSingletons;
357  };
358 
359  /// @{
360  /// When registering attributes, you *must* bracket the attribute
361  /// definitions within a startDefinition/endDefinition pair. Code usually
362  /// looks like: @code
363  /// static GA_IntrinsicDef theIntrinsicDef;
364  /// MyClass::registerIntrinsicAttributes(GA_IntrinsicManager &man) {
365  /// MyBaseClass::registerIntrinsicAttributes(man);
366  /// man.startDefinition(theIntrinsicDef);
367  /// man.addAttribute(storage, "foo", 0, ...);
368  /// man.addAttribute(storage, "bar", 1, ...);
369  /// man.endDefinition(theIntrinsicDef);
370  /// }
371  /// @endcode
372  /// @see GA_IntrinsicEval
373  bool startDefinition(GA_IntrinsicDef &def);
374  bool endDefinition(GA_IntrinsicDef &def);
375  /// @}
376  /// Add an local intrinsic. If there's a name collision within this
377  /// object, this method will fail by returning an invalid handle (see
378  /// GAisValidGlobalIntrinsic()) The user_id is the value returned by @c
379  /// getUserId() and usually refers to an enum private to the caller.
380  /// A copy is made of the options if passed in.
381  GA_GlobalIntrinsic addAttribute(GA_StorageClass store, const UT_StringRef &name,
382  int user_id, bool read_only,
383  CollapseSingletons collapse_singletons,
384  const UT_Options *options);
385 
386 
389 
390  UT_ArrayStringMap<ga_IntrinsicAttribute *> myTokenToLocalTable;
391  UT::ArrayMap<GA_GlobalIntrinsic, int> myGlobalToLocalTable;
393 
394  friend class GA_PrimitiveFactory;
396  friend class Registrar;
397 };
398 
399 #endif
GA_GlobalIntrinsic getGlobalHandle(GA_LocalIntrinsic lhandle) const
bool getOk() const
Return status of the operation.
const UT_StringHolder & getToken() const
Get the current attribute token.
GA_StorageClass
Definition: GA_Types.h:73
GA_GlobalIntrinsic addAttribute(GA_StorageClass store, const UT_StringRef &name, int user_id, bool read_only, CollapseSingletons collapse_singletons, const UT_Options *options=NULL)
int getLocalEntries() const
Return the number of local handles defined in the manager.
Manager to keep track of global handle to name mappings.
#define GA_API
Definition: GA_API.h:14
Stores information about intrinsic attributes for classes.
bool getCollapseSingletons(const UT_StringRef &name) const
int GA_GlobalIntrinsic
Definition: GA_Types.h:704
int GA_LocalIntrinsic
Definition: GA_Types.h:703
iterator(const iterator &src)
Copy constructor.
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
static const UT_StringHolder theEmptyString
GLuint GLuint end
Definition: glcorearb.h:475
const UT_Options * getOptions(GA_LocalIntrinsic handle) const
void advance()
Advance to the next iteration.
const UT_Options * getOptions(const UT_StringRef &name) const
GLuint const GLchar * name
Definition: glcorearb.h:786
bool getReadOnly(GA_LocalIntrinsic handle) const
const iterator & operator=(const iterator &src)
Assignment operator.
int getUserId(GA_LocalIntrinsic handle) const
GA_StorageClass getStorage(const UT_StringRef &name) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
A map of string to various well defined value types.
Definition: UT_Options.h:84
Registrar & operator=(const Registrar &r)
Assignment operator.
iterator & operator++()
Increment operator.
bool start(GA_IntrinsicDef &def)
Start defining attributes for the given intrinsic definition.
Registrar(const Registrar &r)
Copy constructor.
bool getReadOnly(const UT_StringRef &name) const
const UT_StringHolder & getName(GA_LocalIntrinsic handle) const
Look up an attribute name from the given handle.
int getIndex() const
Get the current attribute handle (global id)
Container class for all geometry.
Definition: GA_Detail.h:96
bool getCollapseSingletons(GA_LocalIntrinsic handle) const
bool atEnd() const
Test to see if the iteration is complete.
iterator()
Simple default constructor.
Definition of a geometric primitive.
GLboolean r
Definition: glcorearb.h:1222
GA_LocalIntrinsic getLocalHandle() const
iterator begin() const
Start traversal of intrinsic attributes names.
int getUserId(const UT_StringRef &name) const
GA_StorageClass getStorage(GA_LocalIntrinsic handle) const
#define GA_INVALID_INTRINSIC_HANDLE
Definition: GA_Types.h:705
GLenum src
Definition: glcorearb.h:1793