rxboiler.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //
  2. ////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Copyright 2015 Autodesk, Inc. All rights reserved.
  5. //
  6. // Use of this software is subject to the terms of the Autodesk license
  7. // agreement provided at the time of installation or download, or which
  8. // otherwise accompanies this software in either electronic or hard copy form.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. //
  12. // DESCRIPTION: ARX Class Boilerplate Macros
  13. #ifndef AC_RXBOILER_H
  14. #define AC_RXBOILER_H
  15. #include "AdAChar.h"
  16. #include "rxnames.h"
  17. #include "acbasedefs.h"
  18. #pragma pack (push, 8)
  19. // ACRX_DECLARE_MEMBERS(CLASS_NAME)
  20. //
  21. // Use this macro to declare the member-functions "isA()", "desc()"
  22. // and "cast()" for the class "CLASS_NAME" which is derived (at some
  23. // level) from AcRxObject. Declaring these functions is required for
  24. // the class to participate in the AcRxObject runtime type identification
  25. // mechanism.
  26. //
  27. // Note that you don't have to declare the class member-functions "isA()",
  28. // "desc()" and "cast()" (i.e., this macro isn't needed) if you don't need
  29. // to distinguish a class at runtime any further than one of its Rx-defined
  30. // base classes.
  31. //
  32. // The static "rxInit()" function and the static "gpDesc" pointer, also
  33. // declared by this macro, exist to allow us to implement the methods
  34. // "isA()", "desc()" and "cast()". The macros ACRX_DEFINE_MEMBERS()
  35. // and ACRX_xxx_DEFINE_MEMBERS() allow you to define the various
  36. // functions and static variables declared with this macro.
  37. //
  38. // This macro MUST BE used inside the "public" section of the class
  39. // declaration. For example, use it like this:
  40. //
  41. // class Foo : public AcRxObject
  42. // {
  43. // public:
  44. // ACRX_DECLARE_MEMBERS(Foo);
  45. // ...etc...
  46. // };
  47. //
  48. #define ACRX_DECLARE_MEMBERS_EXPIMP(CLASS_NAME, EXPIMP) \
  49. EXPIMP virtual AcRxClass* isA() const; \
  50. static AcRxClass* gpDesc; \
  51. EXPIMP static AcRxClass* desc(); \
  52. static CLASS_NAME* cast(const AcRxObject* inPtr) \
  53. { return ((inPtr == NULL) || !inPtr->isKindOf(CLASS_NAME::desc())) \
  54. ? NULL : (CLASS_NAME*)inPtr; }; \
  55. static void rxInit(); \
  56. static void rxInit(AppNameChangeFuncPtr)
  57. #define ACRX_EMPTY
  58. #define ACRX_DECLARE_MEMBERS(CLASS_NAME) \
  59. ACRX_DECLARE_MEMBERS_EXPIMP(CLASS_NAME, ACRX_EMPTY )
  60. // ACRX_DEFINE_MEMBERS(CLASS_NAME)
  61. //
  62. // Use this macro to define the member functions declared with
  63. // the ACRX_DECLARE_MEMBERS() macro.
  64. //
  65. // This macro does not create the associated AcRxClass object; that is
  66. // the responsibility of a service implementation, i.e., the "rxInit()"
  67. // static member-function declared by the ACRX_DECLARE_MEMBERS() macro.
  68. //
  69. // The ACRX_xxx_DEFINE_MEMBERS() macros defined below use this macro,
  70. // as well as provide alternate definitions for the "rxInit()" function.
  71. //
  72. #define ACRX_DEFINE_MEMBERS(CLASS_NAME) \
  73. AcRxClass* CLASS_NAME::desc() \
  74. { \
  75. if (CLASS_NAME::gpDesc != NULL) \
  76. return CLASS_NAME::gpDesc; \
  77. return CLASS_NAME::gpDesc \
  78. = (AcRxClass*)((AcRxDictionary*)acrxSysRegistry() \
  79. ->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#CLASS_NAME)); \
  80. } \
  81. AcRxClass* CLASS_NAME::isA() const \
  82. { \
  83. if (CLASS_NAME::gpDesc != NULL) \
  84. return CLASS_NAME::gpDesc; \
  85. return CLASS_NAME::gpDesc \
  86. = (AcRxClass*)((AcRxDictionary*)acrxSysRegistry() \
  87. ->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#CLASS_NAME)); \
  88. } \
  89. AcRxClass* CLASS_NAME::gpDesc = NULL
  90. // ACRX_NO_CONS_DEFINE_MEMBERS()
  91. // ACRX_CONS_DEFINE_MEMBERS()
  92. // ACRX_DXF_DEFINE_MEMBERS()
  93. //
  94. // These macros are similar to the ACRX_DEFINE_MEMBERS() macro,
  95. // except they also provide implementations for the static "rxInit()"
  96. // function.
  97. //
  98. // The differences between the three macros are manifested in how
  99. // the AcRxClass object responds to AcRxClass::create() and
  100. // AcRxClass::dxfName() member functions.
  101. //
  102. // ACRX_NO_CONS_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS)
  103. //
  104. // For abstract classes and desired concrete classes, for
  105. // which no pseudo-constructor function is associated with
  106. // its AcRxClass object. For example, a class with a
  107. // protected/private default constructor should use
  108. // this macro. <ClassName>::desc()->create()
  109. // returns NULL for AcRxClass objects defined this way.
  110. // The class has no direct DWG or DXF file representation.
  111. //
  112. // ACRX_CONS_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS)
  113. //
  114. // For concrete classes with a meaningful default constructor.
  115. // Causes <ClassName::desc()->create() to return an instance of the
  116. // object created with its default constructor. Causes
  117. // <ClassName::desc()->dxfName() to return NULL.
  118. //
  119. // ACRX_DXF_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS,PROXY_FLAGS,DXF_NAME,APP)
  120. //
  121. // For classes directly instantiated in DWG and DXF,
  122. // <ClassName::desc()->create() returns an instance of the
  123. // object created with its default constructor.
  124. // <ClassName::desc()->dxfName() defines a string that
  125. // the AutoCAD database queries as the preferred DXF
  126. // "object type" name.
  127. //
  128. // ACRX_STATIC_CHECK(CLASS_NAME)
  129. // Helper macro used by the various rxInit() implementations.
  130. // It makes sure that the static varible gpDesc is appropriately
  131. // reinitialized when necessary.
  132. #include "AdAChar.h"
  133. extern "C" void ACBASE_PORT acrx_abort (const ACHAR * format, ...);
  134. #define ACRX_STATIC_CHECK(CLASS_NAME) \
  135. if (CLASS_NAME::gpDesc) { \
  136. AcRxClass *pClass = \
  137. (AcRxClass*)((AcRxDictionary*)acrxSysRegistry() \
  138. ->at(ACRX_CLASS_DICTIONARY))->at(ACRX_T(#CLASS_NAME)); \
  139. if (pClass) { \
  140. if (CLASS_NAME::gpDesc == pClass) \
  141. return; \
  142. else \
  143. acrx_abort(ACRX_T(/*MSGO*/"Class mismatch")); \
  144. } \
  145. }
  146. #define ACRX_NO_CONS_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS) \
  147. ACRX_DEFINE_MEMBERS(CLASS_NAME); \
  148. void CLASS_NAME::rxInit() { \
  149. ACRX_STATIC_CHECK(CLASS_NAME); \
  150. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS)); \
  151. }
  152. #define ACRX_NO_CONS_DEFINE_MEMBERS_WITH_PROPERTIES(CLASS_NAME,PARENT_CLASS, MAKEPROPS) \
  153. ACRX_DEFINE_MEMBERS(CLASS_NAME); \
  154. void CLASS_NAME::rxInit() { \
  155. ACRX_STATIC_CHECK(CLASS_NAME); \
  156. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  157. 0, 0, 0, \
  158. 0, 0, 0, 0, MAKEPROPS); \
  159. }
  160. #define ACRX_CONS_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS,VERNO) \
  161. ACRX_DEFINE_MEMBERS(CLASS_NAME); \
  162. static AcRxObject * make##CLASS_NAME() { return new CLASS_NAME(); } \
  163. void CLASS_NAME::rxInit() { \
  164. ACRX_STATIC_CHECK(CLASS_NAME); \
  165. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  166. VERNO, &make##CLASS_NAME); \
  167. }
  168. #define ACRX_DXF_DEFINE_MEMBERS(CLASS_NAME,PARENT_CLASS,DWG_VERSION,\
  169. MAINTENANCE_VERSION,PROXY_FLAGS,DXF_NAME,APP) \
  170. ACRX_DEFINE_MEMBERS(CLASS_NAME); \
  171. static AcRxObject * make##CLASS_NAME() { return new CLASS_NAME(); } \
  172. void CLASS_NAME::rxInit() { \
  173. ACRX_STATIC_CHECK(CLASS_NAME); \
  174. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  175. DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, \
  176. &make##CLASS_NAME, ACRX_T(#DXF_NAME), ACRX_T(#APP)); \
  177. } \
  178. void CLASS_NAME::rxInit(AppNameChangeFuncPtr ptr) { \
  179. ACRX_STATIC_CHECK(CLASS_NAME); \
  180. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  181. DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, \
  182. &make##CLASS_NAME, ACRX_T(#DXF_NAME), ACRX_T(#APP), ptr); \
  183. }
  184. #define ACRX_DXF_DEFINE_MEMBERS_WITH_PROPERTIES(CLASS_NAME,PARENT_CLASS,DWG_VERSION,\
  185. MAINTENANCE_VERSION,PROXY_FLAGS,DXF_NAME,APP, MAKEPROPS) \
  186. ACRX_DEFINE_MEMBERS(CLASS_NAME); \
  187. static AcRxObject * make##CLASS_NAME() { return new CLASS_NAME(); } \
  188. void CLASS_NAME::rxInit() { \
  189. ACRX_STATIC_CHECK(CLASS_NAME); \
  190. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  191. DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, \
  192. &make##CLASS_NAME, ACRX_T(#DXF_NAME), ACRX_T(#APP), NULL, MAKEPROPS); \
  193. } \
  194. void CLASS_NAME::rxInit(AppNameChangeFuncPtr ptr) { \
  195. ACRX_STATIC_CHECK(CLASS_NAME); \
  196. CLASS_NAME::gpDesc = newAcRxClass(ACRX_T(#CLASS_NAME), ACRX_T(#PARENT_CLASS), \
  197. DWG_VERSION,MAINTENANCE_VERSION,PROXY_FLAGS, \
  198. &make##CLASS_NAME, ACRX_T(#DXF_NAME), ACRX_T(#APP), ptr, MAKEPROPS); \
  199. }
  200. #pragma pack (pop)
  201. #endif