Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

618 lines
23 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef DMELEMENT_H
  7. #define DMELEMENT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "tier1/utlmap.h"
  12. #include "tier1/utlhash.h"
  13. #include "tier1/utlvector.h"
  14. #include "tier1/utlsymbol.h"
  15. #include "datamodel/attributeflags.h"
  16. #include "datamodel/idatamodel.h"
  17. #include "datamodel/dmvar.h"
  18. //-----------------------------------------------------------------------------
  19. //
  20. //-----------------------------------------------------------------------------
  21. typedef bool (CDmElement::*pfnCommandMethod)( const char *command, const char *args );
  22. // element/element array traversal path item - assumes the full path does NOT contain cycles
  23. struct ElementPathItem_t
  24. {
  25. ElementPathItem_t( DmElementHandle_t hElem = DMELEMENT_HANDLE_INVALID,
  26. DmAttributeHandle_t hAttr = DMATTRIBUTE_HANDLE_INVALID,
  27. int idx = -1 )
  28. : hElement( hElem ), hAttribute( hAttr ), nIndex( idx )
  29. {
  30. }
  31. // only uses hElement so that it can be used to search for elements
  32. bool operator==( const ElementPathItem_t &that ) const
  33. {
  34. return hElement == that.hElement;
  35. }
  36. DmElementHandle_t hElement;
  37. DmAttributeHandle_t hAttribute;
  38. int nIndex;
  39. };
  40. //-----------------------------------------------------------------------------
  41. // singly-linked attribute list
  42. //-----------------------------------------------------------------------------
  43. struct DmAttributeList_t
  44. {
  45. DmAttributeList_t() : m_hAttribute( DMATTRIBUTE_HANDLE_INVALID ), m_pNext( NULL ) {}
  46. DmAttributeHandle_t m_hAttribute;
  47. DmAttributeList_t *m_pNext;
  48. };
  49. //-----------------------------------------------------------------------------
  50. // helper class to allow CDmeHandle access to g_pDataModelImp
  51. //-----------------------------------------------------------------------------
  52. class CDmeElementRefHelper
  53. {
  54. protected:
  55. void Ref ( DmElementHandle_t hElement, bool bStrong );
  56. void Unref( DmElementHandle_t hElement, bool bStrong );
  57. };
  58. //-----------------------------------------------------------------------------
  59. // element reference struct - containing attribute referrers and handle refcount
  60. //-----------------------------------------------------------------------------
  61. struct DmElementReference_t
  62. {
  63. explicit DmElementReference_t( DmElementHandle_t hElement = DMELEMENT_HANDLE_INVALID ) :
  64. m_hElement( hElement ), m_nWeakHandleCount( 0 ), m_nStrongHandleCount( 0 )
  65. {
  66. }
  67. DmElementReference_t( const DmElementReference_t &that ) :
  68. m_hElement( that.m_hElement ), m_nWeakHandleCount( that.m_nWeakHandleCount ),
  69. m_nStrongHandleCount( that.m_nStrongHandleCount ), m_attributes( that.m_attributes )
  70. {
  71. }
  72. DmElementReference_t &operator=( const DmElementReference_t &that )
  73. {
  74. m_hElement = that.m_hElement;
  75. m_nWeakHandleCount = that.m_nWeakHandleCount;
  76. m_nStrongHandleCount = that.m_nStrongHandleCount;
  77. m_attributes.m_hAttribute = that.m_attributes.m_hAttribute;
  78. m_attributes.m_pNext = that.m_attributes.m_pNext;
  79. return *this;
  80. }
  81. ~DmElementReference_t()
  82. {
  83. // Assert( !IsStronglyReferenced() );
  84. }
  85. void AddAttribute( CDmAttribute *pAttribute );
  86. void RemoveAttribute( CDmAttribute *pAttribute );
  87. bool IsStronglyReferenced() // should this element be kept around (even if it's DmElementHandle_t is invalidated)
  88. {
  89. return m_attributes.m_hAttribute != DMATTRIBUTE_HANDLE_INVALID || m_nStrongHandleCount > 0;
  90. }
  91. bool IsWeaklyReferenced() // should we keep this element's DmElementHandle_t mapped to it's id (even if the element is deleted)
  92. {
  93. return IsStronglyReferenced() || m_nWeakHandleCount > 0;
  94. }
  95. int EstimateMemoryOverhead()
  96. {
  97. int nBytes = 0;
  98. for ( DmAttributeList_t *pLink = m_attributes.m_pNext; pLink; pLink = pLink->m_pNext )
  99. {
  100. nBytes += sizeof( DmAttributeList_t );
  101. }
  102. return nBytes;
  103. }
  104. DmElementHandle_t m_hElement;
  105. unsigned short m_nWeakHandleCount; // CDmeHandle<T> - for auto-hookup once the element comes back, mainly used by UI
  106. unsigned short m_nStrongHandleCount; // CDmeCountedElementRef - for preventing elements from being truly deleted, mainly used by undo and file root
  107. DmAttributeList_t m_attributes;
  108. };
  109. //-----------------------------------------------------------------------------
  110. // Base DmElement we inherit from in higher-level classes
  111. //-----------------------------------------------------------------------------
  112. class CDmElement
  113. {
  114. public:
  115. // Can be overridden by derived classes
  116. virtual void OnAttributeChanged( CDmAttribute *pAttribute ) {}
  117. virtual void PreAttributeChanged( CDmAttribute *pAttribute ) {}
  118. virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {}
  119. virtual void OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {}
  120. virtual void Resolve() {}
  121. virtual bool IsA( UtlSymId_t typeSymbol ) const;
  122. virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const;
  123. virtual void OnElementUnserialized() {}
  124. virtual int AllocatedSize() const { return sizeof( CDmElement ); }
  125. // Returns the element handle
  126. DmElementHandle_t GetHandle() const;
  127. // Attribute iteration, finding
  128. // NOTE: Passing a type into GetAttribute will return NULL if the attribute exists but isn't that type
  129. bool HasAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const;
  130. CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN );
  131. const CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const;
  132. int AttributeCount() const;
  133. CDmAttribute* FirstAttribute();
  134. const CDmAttribute* FirstAttribute() const;
  135. // Element name, type, ID
  136. // WARNING: SetType() should only be used by format conversion methods (dmxconvert)
  137. UtlSymId_t GetType() const;
  138. const char * GetTypeString() const;
  139. const char * GetName() const;
  140. const DmObjectId_t& GetId() const;
  141. void SetType( const char *pType );
  142. void SetName( const char* pName );
  143. // Attribute management
  144. CDmAttribute * AddAttribute( const char *pAttributeName, DmAttributeType_t type );
  145. template< class E > CDmAttribute* AddAttributeElement( const char *pAttributeName );
  146. template< class E > CDmAttribute* AddAttributeElementArray( const char *pAttributeName );
  147. void RemoveAttribute( const char *pAttributeName );
  148. void RemoveAttributeByPtr( CDmAttribute *pAttributeName );
  149. void RenameAttribute( const char *pAttributeName, const char *pNewName );
  150. // get attribute value
  151. template< class T > const T& GetValue( const char *pAttributeName ) const;
  152. template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const;
  153. const char * GetValueString( const char *pAttributeName ) const;
  154. template< class E > E* GetValueElement( const char *pAttributeName ) const;
  155. // set attribute value
  156. CDmAttribute* SetValue( const char *pAttributeName, const void *value, size_t size );
  157. template< class T > CDmAttribute* SetValue( const char *pAttributeName, const T& value );
  158. template< class E > CDmAttribute* SetValue( const char *pAttributeName, E* value );
  159. // set attribute value if the attribute doesn't already exist
  160. CDmAttribute* InitValue( const char *pAttributeName, const void *value, size_t size );
  161. template< class T > CDmAttribute* InitValue( const char *pAttributeName, const T& value );
  162. template< class E > CDmAttribute* InitValue( const char *pAttributeName, E* value );
  163. // Parses an attribute from a string
  164. // Doesn't create an attribute if it doesn't exist and always preserves attribute type
  165. void SetValueFromString( const char *pAttributeName, const char *value );
  166. const char *GetValueAsString( const char *pAttributeName, char *pBuffer, size_t buflen ) const;
  167. // Helpers for our RTTI
  168. template< class E > bool IsA() const;
  169. bool IsA( const char *pTypeName ) const;
  170. int GetInheritanceDepth( const char *pTypeName ) const;
  171. static CUtlSymbol GetStaticTypeSymbol();
  172. // Indicates whether this element should be copied or not
  173. void SetShared( bool bShared );
  174. bool IsShared() const;
  175. // Copies an element and all its attributes
  176. CDmElement* Copy( TraversalDepth_t depth = TD_DEEP ) const;
  177. // Copies attributes from a specified element
  178. void CopyAttributesTo( CDmElement *pCopy, TraversalDepth_t depth = TD_DEEP ) const;
  179. // recursively set fileid's, with option to only change elements in the matched file
  180. void SetFileId( DmFileId_t fileid, TraversalDepth_t depth, bool bOnlyIfMatch = false );
  181. DmFileId_t GetFileId() const;
  182. bool IsAccessible() const;
  183. void MarkAccessible( bool bAccessible );
  184. void MarkAccessible( TraversalDepth_t depth = TD_ALL );
  185. // returns the first path to the element found traversing all element/element
  186. // array attributes - not necessarily the shortest.
  187. // cycle-safe (skips any references to elements in the current path)
  188. // but may re-traverse elements via different paths
  189. bool FindElement( const CDmElement *pElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const;
  190. bool FindReferer( DmElementHandle_t hElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const;
  191. void RemoveAllReferencesToElement( CDmElement *pElement );
  192. bool IsStronglyReferenced() { return m_ref.IsStronglyReferenced(); }
  193. // Estimates the memory usage of the element, its attributes, and child elements
  194. int EstimateMemoryUsage( TraversalDepth_t depth = TD_DEEP );
  195. protected:
  196. // NOTE: These are protected to ensure that the factory is the only thing that can create these
  197. CDmElement( DmElementHandle_t handle, const char *objectType, const DmObjectId_t &id, const char *objectName, DmFileId_t fileid );
  198. virtual ~CDmElement();
  199. // Used by derived classes to do construction and setting up CDmaVars
  200. void OnConstruction() { }
  201. void OnDestruction() { }
  202. virtual void PerformConstruction();
  203. virtual void PerformDestruction();
  204. // Internal methods related to RTII
  205. static void SetTypeSymbol( CUtlSymbol sym );
  206. static bool IsA_Implementation( CUtlSymbol typeSymbol );
  207. static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth );
  208. // Internal method for creating a copy of this element
  209. CDmElement* CopyInternal( TraversalDepth_t depth = TD_DEEP ) const;
  210. // helper for making attributevarelementarray cleanup easier
  211. template< class T > static void DeleteAttributeVarElementArray( T &array );
  212. private:
  213. typedef CUtlMap< DmElementHandle_t, DmElementHandle_t, int > CRefMap;
  214. // Bogus constructor
  215. CDmElement();
  216. // internal recursive copy method - builds refmap of old element's handle -> copy's handle, and uses it to fixup references
  217. void CopyAttributesTo( CDmElement *pCopy, CRefMap &refmap, TraversalDepth_t depth ) const;
  218. void CopyElementAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const;
  219. void CopyElementArrayAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const;
  220. void FixupReferences( CUtlHashFast< DmElementHandle_t > &visited, const CRefMap &refmap, TraversalDepth_t depth );
  221. void SetFileId( DmFileId_t fileid );
  222. void SetFileId_R( CUtlHashFast< DmElementHandle_t > &visited, DmFileId_t fileid, TraversalDepth_t depth, DmFileId_t match, bool bOnlyIfMatch );
  223. CDmAttribute* CreateAttribute( const char *pAttributeName, DmAttributeType_t type );
  224. void RemoveAttribute( CDmAttribute **pAttrRef );
  225. CDmAttribute* AddExternalAttribute( const char *pAttributeName, DmAttributeType_t type, void *pMemory );
  226. CDmAttribute *FindAttribute( const char *pAttributeName ) const;
  227. void Purge();
  228. void SetId( const DmObjectId_t &id );
  229. bool IsDirty() const;
  230. void MarkDirty( bool dirty = true );
  231. void MarkAttributesClean();
  232. void MarkBeingUnserialized( bool beingUnserialized = true );
  233. bool IsBeingUnserialized() const;
  234. // Used by the undo system only.
  235. void AddAttributeByPtr( CDmAttribute *ptr );
  236. void RemoveAttributeByPtrNoDelete( CDmAttribute *ptr );
  237. // Should only be called from datamodel, who will take care of changing the fileset entry as well
  238. void ChangeHandle( DmElementHandle_t handle );
  239. // returns element reference struct w/ list of referrers and handle count
  240. DmElementReference_t* GetReference();
  241. void SetReference( const DmElementReference_t &ref );
  242. // Estimates memory usage
  243. int EstimateMemoryUsage( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories );
  244. protected:
  245. CDmaString m_Name;
  246. private:
  247. CDmAttribute *m_pAttributes;
  248. DmElementReference_t m_ref;
  249. UtlSymId_t m_Type;
  250. bool m_bDirty : 1;
  251. bool m_bBeingUnserialized : 1;
  252. bool m_bIsAcessible : 1;
  253. unsigned char m_nReserved; // Makes Id be quad aligned
  254. DmObjectId_t m_Id;
  255. DmFileId_t m_fileId;
  256. // Stores the type symbol
  257. static CUtlSymbol m_classType;
  258. // Factories can access our constructors
  259. template <class T> friend class CDmElementFactory;
  260. template <class T> friend class CDmAbstractElementFactory;
  261. template< class T > friend class CDmaVar;
  262. template< class T > friend class CDmaArray;
  263. template< class T > friend class CDmaElementArray;
  264. template< class T, class B > friend class CDmaDecorator;
  265. template< class T > friend class CDmrElementArray;
  266. friend class CDmElementFactoryDefault;
  267. friend class CDmeElementAccessor;
  268. friend class CDmeOperator;
  269. friend void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth );
  270. };
  271. inline void DestroyElement( CDmElement *pElement )
  272. {
  273. if ( pElement )
  274. {
  275. g_pDataModel->DestroyElement( pElement->GetHandle() );
  276. }
  277. }
  278. void DestroyElement( CDmElement *pElement, TraversalDepth_t depth );
  279. //-----------------------------------------------------------------------------
  280. // copy groups of elements together so that references between them are maintained
  281. //-----------------------------------------------------------------------------
  282. void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth = TD_DEEP );
  283. //-----------------------------------------------------------------------------
  284. // allows elements to chain OnAttributeChanged up to their parents (or at least, referrers)
  285. //-----------------------------------------------------------------------------
  286. void InvokeOnAttributeChangedOnReferrers( DmElementHandle_t hElement, CDmAttribute *pChangedAttr );
  287. //-----------------------------------------------------------------------------
  288. // Returns the type, name, id, fileId
  289. //-----------------------------------------------------------------------------
  290. inline UtlSymId_t CDmElement::GetType() const
  291. {
  292. return m_Type;
  293. }
  294. inline const char *CDmElement::GetTypeString() const
  295. {
  296. return g_pDataModel->GetString( m_Type );
  297. }
  298. inline const char *CDmElement::GetName() const
  299. {
  300. return m_Name.Get();
  301. }
  302. inline void CDmElement::SetName( const char* pName )
  303. {
  304. m_Name.Set( pName );
  305. }
  306. inline const DmObjectId_t& CDmElement::GetId() const
  307. {
  308. return m_Id;
  309. }
  310. inline DmFileId_t CDmElement::GetFileId() const
  311. {
  312. return m_fileId;
  313. }
  314. //-----------------------------------------------------------------------------
  315. // Controls whether the element should be copied by default
  316. //-----------------------------------------------------------------------------
  317. inline void CDmElement::SetShared( bool bShared )
  318. {
  319. if ( bShared )
  320. {
  321. SetValue< bool >( "shared", true );
  322. }
  323. else
  324. {
  325. RemoveAttribute( "shared" );
  326. }
  327. }
  328. inline bool CDmElement::IsShared() const
  329. {
  330. return GetValue< bool >( "shared" ); // if attribute doesn't exist, returns default bool value, which is false
  331. }
  332. //-----------------------------------------------------------------------------
  333. // Copies attributes from a specified element
  334. //-----------------------------------------------------------------------------
  335. inline CDmElement* CDmElement::Copy( TraversalDepth_t depth ) const
  336. {
  337. return CopyInternal( depth );
  338. }
  339. //-----------------------------------------------------------------------------
  340. // RTTI
  341. //-----------------------------------------------------------------------------
  342. inline bool CDmElement::IsA_Implementation( CUtlSymbol typeSymbol )
  343. {
  344. return ( m_classType == typeSymbol ) || ( UTL_INVAL_SYMBOL == typeSymbol );
  345. }
  346. inline int CDmElement::GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth )
  347. {
  348. return IsA_Implementation( typeSymbol ) ? nCurrentDepth : -1;
  349. }
  350. inline CUtlSymbol CDmElement::GetStaticTypeSymbol()
  351. {
  352. return m_classType;
  353. }
  354. inline bool CDmElement::IsA( const char *pTypeName ) const
  355. {
  356. CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName );
  357. return IsA( typeSymbol );
  358. }
  359. template< class E > inline bool CDmElement::IsA() const
  360. {
  361. return IsA( E::GetStaticTypeSymbol() );
  362. }
  363. //-----------------------------------------------------------------------------
  364. // Helper for finding elements that refer to this element
  365. //-----------------------------------------------------------------------------
  366. template< class T >
  367. T *FindReferringElement( CDmElement *pElement, const char *pAttrName, bool bMustBeInSameFile = true )
  368. {
  369. return FindReferringElement< T >( pElement, g_pDataModel->GetSymbol( pAttrName ), bMustBeInSameFile );
  370. }
  371. void RemoveElementFromRefereringAttributes( CDmElement *pElement, bool bPreserveOrder = true );
  372. //-----------------------------------------------------------------------------
  373. //
  374. // element-specific unique name generation methods
  375. //
  376. //-----------------------------------------------------------------------------
  377. // returns startindex if none found, 2 if only "prefix" found, and n+1 if "prefixn" found
  378. int GenerateUniqueNameIndex( const char *prefix, const CUtlVector< DmElementHandle_t > &array, int startindex = -1 );
  379. bool GenerateUniqueName( char *name, int memsize, const char *prefix, const CUtlVector< DmElementHandle_t > &array );
  380. void MakeElementNameUnique( CDmElement *pElement, const char *prefix, const CUtlVector< DmElementHandle_t > &array, bool forceIndex = false );
  381. //-----------------------------------------------------------------------------
  382. // helper for making attributevarelementarray cleanup easier
  383. //-----------------------------------------------------------------------------
  384. template< class T >
  385. inline void CDmElement::DeleteAttributeVarElementArray( T &array )
  386. {
  387. int nElements = array.Count();
  388. for ( int i = 0; i < nElements; ++i )
  389. {
  390. g_pDataModel->DestroyElement( array.GetHandle( i ) );
  391. }
  392. array.RemoveAll();
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Default size computation
  396. //-----------------------------------------------------------------------------
  397. template< class T >
  398. int DmeEstimateMemorySize( T* pElement )
  399. {
  400. return sizeof( T );
  401. }
  402. //-----------------------------------------------------------------------------
  403. // Helper macro to create an element; this is used for elements that are helper base classes
  404. //-----------------------------------------------------------------------------
  405. #define DEFINE_UNINSTANCEABLE_ELEMENT( className, baseClassName ) \
  406. protected: \
  407. className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \
  408. baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \
  409. { \
  410. } \
  411. virtual ~className() \
  412. { \
  413. } \
  414. void OnConstruction(); \
  415. void OnDestruction(); \
  416. virtual void PerformConstruction() \
  417. { \
  418. BaseClass::PerformConstruction(); \
  419. OnConstruction(); \
  420. } \
  421. virtual void PerformDestruction() \
  422. { \
  423. OnDestruction(); \
  424. BaseClass::PerformDestruction(); \
  425. } \
  426. virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \
  427. \
  428. private: \
  429. typedef baseClassName BaseClass; \
  430. //-----------------------------------------------------------------------------
  431. // Helper macro to create the class factory
  432. //-----------------------------------------------------------------------------
  433. #define DEFINE_ELEMENT( className, baseClassName ) \
  434. public: \
  435. virtual bool IsA( UtlSymId_t typeSymbol ) const \
  436. { \
  437. return IsA_Implementation( typeSymbol );\
  438. } \
  439. \
  440. bool IsA( const char *pTypeName ) const \
  441. { \
  442. CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); \
  443. return IsA( typeSymbol ); \
  444. } \
  445. \
  446. template< class T > bool IsA() const \
  447. { \
  448. return IsA( T::GetStaticTypeSymbol() ); \
  449. } \
  450. \
  451. virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const \
  452. { \
  453. return GetInheritanceDepth_Implementation( typeSymbol, 0 ); \
  454. } \
  455. \
  456. static CUtlSymbol GetStaticTypeSymbol( ) \
  457. { \
  458. return m_classType; \
  459. } \
  460. \
  461. className* Copy( TraversalDepth_t depth = TD_DEEP ) const \
  462. { \
  463. return static_cast< className* >( CopyInternal( depth ) ); \
  464. } \
  465. protected: \
  466. className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \
  467. baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \
  468. { \
  469. } \
  470. virtual ~className() \
  471. { \
  472. } \
  473. void OnConstruction(); \
  474. void OnDestruction(); \
  475. virtual void PerformConstruction() \
  476. { \
  477. BaseClass::PerformConstruction(); \
  478. OnConstruction(); \
  479. } \
  480. virtual void PerformDestruction() \
  481. { \
  482. OnDestruction(); \
  483. BaseClass::PerformDestruction(); \
  484. } \
  485. static void SetTypeSymbol( CUtlSymbol typeSymbol ) \
  486. { \
  487. m_classType = typeSymbol; \
  488. } \
  489. \
  490. static bool IsA_Implementation( CUtlSymbol typeSymbol ) \
  491. { \
  492. if ( typeSymbol == m_classType ) \
  493. return true; \
  494. return BaseClass::IsA_Implementation( typeSymbol ); \
  495. } \
  496. \
  497. static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) \
  498. { \
  499. if ( typeSymbol == m_classType ) \
  500. return nCurrentDepth; \
  501. return BaseClass::GetInheritanceDepth_Implementation( typeSymbol, nCurrentDepth+1 );\
  502. } \
  503. virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \
  504. \
  505. private: \
  506. typedef baseClassName BaseClass; \
  507. template <class T> friend class CDmElementFactory; \
  508. template <class T> friend class CDmAbstractElementFactory; \
  509. static CUtlSymbol m_classType
  510. #define IMPLEMENT_ELEMENT( className ) \
  511. CUtlSymbol className::m_classType = UTL_INVAL_SYMBOL;
  512. #endif // DMELEMENT_H