HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_DataUtils.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  */
7 
8 #ifndef __SIM_DataUtils_h__
9 #define __SIM_DataUtils_h__
10 
11 #include "SIM_Data.h"
12 #include "SIM_DataFactory.h"
13 #include "SIM_Utils.h"
14 #include <UT/UT_StringArray.h>
15 #include <UT/UT_StringHolder.h>
16 #include <SYS/SYS_Compiler.h>
17 
18 /// This macro provides a quick way to define a static function called
19 /// classname() which returns the provided class name as a string.
20 #define DECLARE_CLASSNAME(DataClass, SuperClass) \
21  private: \
22  typedef SuperClass BaseClass; \
23  typedef DataClass ThisClass; \
24  public: \
25  static inline const UT_StringHolder &classname() \
26  { \
27  static constexpr UT_StringLit theType(#DataClass); \
28  return theType.asHolder(); \
29  } \
30  private: \
31  const UT_StringHolder &getDataTypeSubclass() const override \
32  { \
33  return classname(); \
34  } \
35  protected: \
36  static void getDataTypeSuperclasses(UT_StringArray& classes) \
37  { \
38  static constexpr UT_StringLit theSuperType(#SuperClass); \
39  classes.append(theSuperType.asHolder()); \
40  SuperClass::getDataTypeSuperclasses(classes); \
41  } \
42  private: \
43  /**/
44 
45 /// This function implements a standard version of getDistanceToType().
46 /// Only if your subclass uses multiple inheritance will it be necessary to
47 /// write a customized version of this function. Be sure to add this
48 /// declaration to your class definition or the DECLARE_DATAFACTORY()
49 /// macro will not compile properly.
50 #define DECLARE_STANDARD_GETCASTTOTYPE() \
51  protected: \
52  void *getCastToType(const UT_StringRef &totype) const override \
53  { \
54  if( classname() == totype ) \
55  return (void *)this; \
56  return BaseClass::getCastToType(totype); \
57  } \
58  /**/
59 
60 /// This macro simplifies the calling and casting the return value from
61 /// This macro quickly defines all the static functions needed to declare
62 /// a SIM_DataFactory for a SIM_Data subclass.
63 #define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms) \
64  public: \
65  class DataClass##Factory : public SIM_DataFactory \
66  { \
67  public: \
68  DataClass##Factory(SIM_Engine *engine) \
69  : SIM_DataFactory(\
70  SYS_CONCAT(#DataClass,_UTsh), \
71  SYS_CONCAT(Description,_UTsh), \
72  DataClass::getDataTypeSuperclasses, \
73  DataClass::constructor, \
74  DataClass::destructor, \
75  DataClass::DopParms, \
76  engine) \
77  { } \
78  }; \
79  static void createDataFactory(SIM_Engine *engine) \
80  { \
81  SIM_DataFactory *factory; \
82  factory = new DataClass##Factory( \
83  engine); \
84  SIM_DataFactoryCreator::addDataFactory \
85  (engine, factory); \
86  } \
87  friend class DataClass##Factory; \
88  private: \
89  DECLARE_CLASSNAME(DataClass, SuperClass); \
90  static SIM_Data *constructor(const SIM_DataFactory *factory) \
91  { return (BaseClass *)new \
92  DataClass(factory); } \
93  static void destructor(SIM_Data *data) \
94  { delete (DataClass *)data-> \
95  getPointerToType(#DataClass); } \
96  /**/
97 
98 /// Add this macro to the initialization function for your library. It uses
99 /// the declaration above to register your data type.
100 #define IMPLEMENT_DATAFACTORY(DataClass) \
101  static SIM_DataFactoryCreator \
102  DataClass##Creator(DataClass::createDataFactory);
103 
104 #endif
105