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  ~DataClass##Factory() override \
79  { } \
80  }; \
81  static void createDataFactory(SIM_Engine *engine) \
82  { \
83  SIM_DataFactory *factory; \
84  factory = new DataClass##Factory( \
85  engine); \
86  SIM_DataFactoryCreator::addDataFactory \
87  (engine, factory); \
88  } \
89  friend class DataClass##Factory; \
90  private: \
91  DECLARE_CLASSNAME(DataClass, SuperClass); \
92  static SIM_Data *constructor(const SIM_DataFactory *factory) \
93  { return (BaseClass *)new \
94  DataClass(factory); } \
95  static void destructor(SIM_Data *data) \
96  { delete (DataClass *)data-> \
97  getPointerToType(#DataClass); } \
98  /**/
99 
100 /// Add this macro to the initialization function for your library. It uses
101 /// the declaration above to register your data type.
102 #define IMPLEMENT_DATAFACTORY(DataClass) \
103  static SIM_DataFactoryCreator \
104  DataClass##Creator(DataClass::createDataFactory);
105 
106 #endif
107