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
618 lines
23 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#ifndef DMELEMENT_H |
|
#define DMELEMENT_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "tier1/utlmap.h" |
|
#include "tier1/utlhash.h" |
|
#include "tier1/utlvector.h" |
|
#include "tier1/utlsymbol.h" |
|
#include "datamodel/attributeflags.h" |
|
#include "datamodel/idatamodel.h" |
|
#include "datamodel/dmvar.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
typedef bool (CDmElement::*pfnCommandMethod)( const char *command, const char *args ); |
|
|
|
// element/element array traversal path item - assumes the full path does NOT contain cycles |
|
struct ElementPathItem_t |
|
{ |
|
ElementPathItem_t( DmElementHandle_t hElem = DMELEMENT_HANDLE_INVALID, |
|
DmAttributeHandle_t hAttr = DMATTRIBUTE_HANDLE_INVALID, |
|
int idx = -1 ) |
|
: hElement( hElem ), hAttribute( hAttr ), nIndex( idx ) |
|
{ |
|
} |
|
|
|
// only uses hElement so that it can be used to search for elements |
|
bool operator==( const ElementPathItem_t &that ) const |
|
{ |
|
return hElement == that.hElement; |
|
} |
|
|
|
DmElementHandle_t hElement; |
|
DmAttributeHandle_t hAttribute; |
|
int nIndex; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// singly-linked attribute list |
|
//----------------------------------------------------------------------------- |
|
struct DmAttributeList_t |
|
{ |
|
DmAttributeList_t() : m_hAttribute( DMATTRIBUTE_HANDLE_INVALID ), m_pNext( NULL ) {} |
|
DmAttributeHandle_t m_hAttribute; |
|
DmAttributeList_t *m_pNext; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// helper class to allow CDmeHandle access to g_pDataModelImp |
|
//----------------------------------------------------------------------------- |
|
class CDmeElementRefHelper |
|
{ |
|
protected: |
|
void Ref ( DmElementHandle_t hElement, bool bStrong ); |
|
void Unref( DmElementHandle_t hElement, bool bStrong ); |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// element reference struct - containing attribute referrers and handle refcount |
|
//----------------------------------------------------------------------------- |
|
struct DmElementReference_t |
|
{ |
|
explicit DmElementReference_t( DmElementHandle_t hElement = DMELEMENT_HANDLE_INVALID ) : |
|
m_hElement( hElement ), m_nWeakHandleCount( 0 ), m_nStrongHandleCount( 0 ) |
|
{ |
|
} |
|
DmElementReference_t( const DmElementReference_t &that ) : |
|
m_hElement( that.m_hElement ), m_nWeakHandleCount( that.m_nWeakHandleCount ), |
|
m_nStrongHandleCount( that.m_nStrongHandleCount ), m_attributes( that.m_attributes ) |
|
{ |
|
} |
|
DmElementReference_t &operator=( const DmElementReference_t &that ) |
|
{ |
|
m_hElement = that.m_hElement; |
|
m_nWeakHandleCount = that.m_nWeakHandleCount; |
|
m_nStrongHandleCount = that.m_nStrongHandleCount; |
|
m_attributes.m_hAttribute = that.m_attributes.m_hAttribute; |
|
m_attributes.m_pNext = that.m_attributes.m_pNext; |
|
return *this; |
|
} |
|
~DmElementReference_t() |
|
{ |
|
// Assert( !IsStronglyReferenced() ); |
|
} |
|
|
|
void AddAttribute( CDmAttribute *pAttribute ); |
|
void RemoveAttribute( CDmAttribute *pAttribute ); |
|
|
|
bool IsStronglyReferenced() // should this element be kept around (even if it's DmElementHandle_t is invalidated) |
|
{ |
|
return m_attributes.m_hAttribute != DMATTRIBUTE_HANDLE_INVALID || m_nStrongHandleCount > 0; |
|
} |
|
|
|
bool IsWeaklyReferenced() // should we keep this element's DmElementHandle_t mapped to it's id (even if the element is deleted) |
|
{ |
|
return IsStronglyReferenced() || m_nWeakHandleCount > 0; |
|
} |
|
|
|
int EstimateMemoryOverhead() |
|
{ |
|
int nBytes = 0; |
|
for ( DmAttributeList_t *pLink = m_attributes.m_pNext; pLink; pLink = pLink->m_pNext ) |
|
{ |
|
nBytes += sizeof( DmAttributeList_t ); |
|
} |
|
return nBytes; |
|
} |
|
|
|
DmElementHandle_t m_hElement; |
|
unsigned short m_nWeakHandleCount; // CDmeHandle<T> - for auto-hookup once the element comes back, mainly used by UI |
|
unsigned short m_nStrongHandleCount; // CDmeCountedElementRef - for preventing elements from being truly deleted, mainly used by undo and file root |
|
DmAttributeList_t m_attributes; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Base DmElement we inherit from in higher-level classes |
|
//----------------------------------------------------------------------------- |
|
class CDmElement |
|
{ |
|
public: |
|
// Can be overridden by derived classes |
|
virtual void OnAttributeChanged( CDmAttribute *pAttribute ) {} |
|
virtual void PreAttributeChanged( CDmAttribute *pAttribute ) {} |
|
virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {} |
|
virtual void OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {} |
|
virtual void Resolve() {} |
|
virtual bool IsA( UtlSymId_t typeSymbol ) const; |
|
virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const; |
|
virtual void OnElementUnserialized() {} |
|
virtual int AllocatedSize() const { return sizeof( CDmElement ); } |
|
|
|
// Returns the element handle |
|
DmElementHandle_t GetHandle() const; |
|
|
|
// Attribute iteration, finding |
|
// NOTE: Passing a type into GetAttribute will return NULL if the attribute exists but isn't that type |
|
bool HasAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const; |
|
CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ); |
|
const CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const; |
|
int AttributeCount() const; |
|
CDmAttribute* FirstAttribute(); |
|
const CDmAttribute* FirstAttribute() const; |
|
|
|
// Element name, type, ID |
|
// WARNING: SetType() should only be used by format conversion methods (dmxconvert) |
|
UtlSymId_t GetType() const; |
|
const char * GetTypeString() const; |
|
const char * GetName() const; |
|
const DmObjectId_t& GetId() const; |
|
void SetType( const char *pType ); |
|
void SetName( const char* pName ); |
|
|
|
// Attribute management |
|
CDmAttribute * AddAttribute( const char *pAttributeName, DmAttributeType_t type ); |
|
template< class E > CDmAttribute* AddAttributeElement( const char *pAttributeName ); |
|
template< class E > CDmAttribute* AddAttributeElementArray( const char *pAttributeName ); |
|
void RemoveAttribute( const char *pAttributeName ); |
|
void RemoveAttributeByPtr( CDmAttribute *pAttributeName ); |
|
void RenameAttribute( const char *pAttributeName, const char *pNewName ); |
|
|
|
// get attribute value |
|
template< class T > const T& GetValue( const char *pAttributeName ) const; |
|
template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const; |
|
const char * GetValueString( const char *pAttributeName ) const; |
|
template< class E > E* GetValueElement( const char *pAttributeName ) const; |
|
|
|
// set attribute value |
|
CDmAttribute* SetValue( const char *pAttributeName, const void *value, size_t size ); |
|
template< class T > CDmAttribute* SetValue( const char *pAttributeName, const T& value ); |
|
template< class E > CDmAttribute* SetValue( const char *pAttributeName, E* value ); |
|
|
|
// set attribute value if the attribute doesn't already exist |
|
CDmAttribute* InitValue( const char *pAttributeName, const void *value, size_t size ); |
|
template< class T > CDmAttribute* InitValue( const char *pAttributeName, const T& value ); |
|
template< class E > CDmAttribute* InitValue( const char *pAttributeName, E* value ); |
|
|
|
// Parses an attribute from a string |
|
// Doesn't create an attribute if it doesn't exist and always preserves attribute type |
|
void SetValueFromString( const char *pAttributeName, const char *value ); |
|
const char *GetValueAsString( const char *pAttributeName, char *pBuffer, size_t buflen ) const; |
|
|
|
// Helpers for our RTTI |
|
template< class E > bool IsA() const; |
|
bool IsA( const char *pTypeName ) const; |
|
int GetInheritanceDepth( const char *pTypeName ) const; |
|
static CUtlSymbol GetStaticTypeSymbol(); |
|
|
|
// Indicates whether this element should be copied or not |
|
void SetShared( bool bShared ); |
|
bool IsShared() const; |
|
|
|
// Copies an element and all its attributes |
|
CDmElement* Copy( TraversalDepth_t depth = TD_DEEP ) const; |
|
|
|
// Copies attributes from a specified element |
|
void CopyAttributesTo( CDmElement *pCopy, TraversalDepth_t depth = TD_DEEP ) const; |
|
|
|
// recursively set fileid's, with option to only change elements in the matched file |
|
void SetFileId( DmFileId_t fileid, TraversalDepth_t depth, bool bOnlyIfMatch = false ); |
|
DmFileId_t GetFileId() const; |
|
|
|
bool IsAccessible() const; |
|
void MarkAccessible( bool bAccessible ); |
|
void MarkAccessible( TraversalDepth_t depth = TD_ALL ); |
|
|
|
// returns the first path to the element found traversing all element/element |
|
// array attributes - not necessarily the shortest. |
|
// cycle-safe (skips any references to elements in the current path) |
|
// but may re-traverse elements via different paths |
|
bool FindElement( const CDmElement *pElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const; |
|
bool FindReferer( DmElementHandle_t hElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const; |
|
void RemoveAllReferencesToElement( CDmElement *pElement ); |
|
bool IsStronglyReferenced() { return m_ref.IsStronglyReferenced(); } |
|
|
|
// Estimates the memory usage of the element, its attributes, and child elements |
|
int EstimateMemoryUsage( TraversalDepth_t depth = TD_DEEP ); |
|
|
|
protected: |
|
// NOTE: These are protected to ensure that the factory is the only thing that can create these |
|
CDmElement( DmElementHandle_t handle, const char *objectType, const DmObjectId_t &id, const char *objectName, DmFileId_t fileid ); |
|
virtual ~CDmElement(); |
|
|
|
// Used by derived classes to do construction and setting up CDmaVars |
|
void OnConstruction() { } |
|
void OnDestruction() { } |
|
virtual void PerformConstruction(); |
|
virtual void PerformDestruction(); |
|
|
|
// Internal methods related to RTII |
|
static void SetTypeSymbol( CUtlSymbol sym ); |
|
static bool IsA_Implementation( CUtlSymbol typeSymbol ); |
|
static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ); |
|
|
|
// Internal method for creating a copy of this element |
|
CDmElement* CopyInternal( TraversalDepth_t depth = TD_DEEP ) const; |
|
|
|
// helper for making attributevarelementarray cleanup easier |
|
template< class T > static void DeleteAttributeVarElementArray( T &array ); |
|
|
|
private: |
|
typedef CUtlMap< DmElementHandle_t, DmElementHandle_t, int > CRefMap; |
|
|
|
// Bogus constructor |
|
CDmElement(); |
|
|
|
// internal recursive copy method - builds refmap of old element's handle -> copy's handle, and uses it to fixup references |
|
void CopyAttributesTo( CDmElement *pCopy, CRefMap &refmap, TraversalDepth_t depth ) const; |
|
void CopyElementAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const; |
|
void CopyElementArrayAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const; |
|
void FixupReferences( CUtlHashFast< DmElementHandle_t > &visited, const CRefMap &refmap, TraversalDepth_t depth ); |
|
|
|
void SetFileId( DmFileId_t fileid ); |
|
void SetFileId_R( CUtlHashFast< DmElementHandle_t > &visited, DmFileId_t fileid, TraversalDepth_t depth, DmFileId_t match, bool bOnlyIfMatch ); |
|
|
|
CDmAttribute* CreateAttribute( const char *pAttributeName, DmAttributeType_t type ); |
|
void RemoveAttribute( CDmAttribute **pAttrRef ); |
|
CDmAttribute* AddExternalAttribute( const char *pAttributeName, DmAttributeType_t type, void *pMemory ); |
|
CDmAttribute *FindAttribute( const char *pAttributeName ) const; |
|
|
|
void Purge(); |
|
void SetId( const DmObjectId_t &id ); |
|
|
|
bool IsDirty() const; |
|
void MarkDirty( bool dirty = true ); |
|
void MarkAttributesClean(); |
|
void MarkBeingUnserialized( bool beingUnserialized = true ); |
|
bool IsBeingUnserialized() const; |
|
|
|
// Used by the undo system only. |
|
void AddAttributeByPtr( CDmAttribute *ptr ); |
|
void RemoveAttributeByPtrNoDelete( CDmAttribute *ptr ); |
|
|
|
// Should only be called from datamodel, who will take care of changing the fileset entry as well |
|
void ChangeHandle( DmElementHandle_t handle ); |
|
|
|
// returns element reference struct w/ list of referrers and handle count |
|
DmElementReference_t* GetReference(); |
|
void SetReference( const DmElementReference_t &ref ); |
|
|
|
// Estimates memory usage |
|
int EstimateMemoryUsage( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ); |
|
|
|
protected: |
|
CDmaString m_Name; |
|
|
|
private: |
|
CDmAttribute *m_pAttributes; |
|
DmElementReference_t m_ref; |
|
UtlSymId_t m_Type; |
|
bool m_bDirty : 1; |
|
bool m_bBeingUnserialized : 1; |
|
bool m_bIsAcessible : 1; |
|
unsigned char m_nReserved; // Makes Id be quad aligned |
|
DmObjectId_t m_Id; |
|
DmFileId_t m_fileId; |
|
|
|
// Stores the type symbol |
|
static CUtlSymbol m_classType; |
|
|
|
// Factories can access our constructors |
|
template <class T> friend class CDmElementFactory; |
|
template <class T> friend class CDmAbstractElementFactory; |
|
template< class T > friend class CDmaVar; |
|
template< class T > friend class CDmaArray; |
|
template< class T > friend class CDmaElementArray; |
|
template< class T, class B > friend class CDmaDecorator; |
|
template< class T > friend class CDmrElementArray; |
|
|
|
friend class CDmElementFactoryDefault; |
|
friend class CDmeElementAccessor; |
|
friend class CDmeOperator; |
|
|
|
friend void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth ); |
|
}; |
|
|
|
|
|
|
|
inline void DestroyElement( CDmElement *pElement ) |
|
{ |
|
if ( pElement ) |
|
{ |
|
g_pDataModel->DestroyElement( pElement->GetHandle() ); |
|
} |
|
} |
|
|
|
void DestroyElement( CDmElement *pElement, TraversalDepth_t depth ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// copy groups of elements together so that references between them are maintained |
|
//----------------------------------------------------------------------------- |
|
void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth = TD_DEEP ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// allows elements to chain OnAttributeChanged up to their parents (or at least, referrers) |
|
//----------------------------------------------------------------------------- |
|
void InvokeOnAttributeChangedOnReferrers( DmElementHandle_t hElement, CDmAttribute *pChangedAttr ); |
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the type, name, id, fileId |
|
//----------------------------------------------------------------------------- |
|
inline UtlSymId_t CDmElement::GetType() const |
|
{ |
|
return m_Type; |
|
} |
|
|
|
inline const char *CDmElement::GetTypeString() const |
|
{ |
|
return g_pDataModel->GetString( m_Type ); |
|
} |
|
|
|
inline const char *CDmElement::GetName() const |
|
{ |
|
return m_Name.Get(); |
|
} |
|
|
|
inline void CDmElement::SetName( const char* pName ) |
|
{ |
|
m_Name.Set( pName ); |
|
} |
|
|
|
inline const DmObjectId_t& CDmElement::GetId() const |
|
{ |
|
return m_Id; |
|
} |
|
|
|
inline DmFileId_t CDmElement::GetFileId() const |
|
{ |
|
return m_fileId; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Controls whether the element should be copied by default |
|
//----------------------------------------------------------------------------- |
|
inline void CDmElement::SetShared( bool bShared ) |
|
{ |
|
if ( bShared ) |
|
{ |
|
SetValue< bool >( "shared", true ); |
|
} |
|
else |
|
{ |
|
RemoveAttribute( "shared" ); |
|
} |
|
} |
|
|
|
inline bool CDmElement::IsShared() const |
|
{ |
|
return GetValue< bool >( "shared" ); // if attribute doesn't exist, returns default bool value, which is false |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Copies attributes from a specified element |
|
//----------------------------------------------------------------------------- |
|
inline CDmElement* CDmElement::Copy( TraversalDepth_t depth ) const |
|
{ |
|
return CopyInternal( depth ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// RTTI |
|
//----------------------------------------------------------------------------- |
|
inline bool CDmElement::IsA_Implementation( CUtlSymbol typeSymbol ) |
|
{ |
|
return ( m_classType == typeSymbol ) || ( UTL_INVAL_SYMBOL == typeSymbol ); |
|
} |
|
|
|
inline int CDmElement::GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) |
|
{ |
|
return IsA_Implementation( typeSymbol ) ? nCurrentDepth : -1; |
|
} |
|
|
|
inline CUtlSymbol CDmElement::GetStaticTypeSymbol() |
|
{ |
|
return m_classType; |
|
} |
|
|
|
inline bool CDmElement::IsA( const char *pTypeName ) const |
|
{ |
|
CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); |
|
return IsA( typeSymbol ); |
|
} |
|
|
|
template< class E > inline bool CDmElement::IsA() const |
|
{ |
|
return IsA( E::GetStaticTypeSymbol() ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Helper for finding elements that refer to this element |
|
//----------------------------------------------------------------------------- |
|
template< class T > |
|
T *FindReferringElement( CDmElement *pElement, const char *pAttrName, bool bMustBeInSameFile = true ) |
|
{ |
|
return FindReferringElement< T >( pElement, g_pDataModel->GetSymbol( pAttrName ), bMustBeInSameFile ); |
|
} |
|
|
|
|
|
void RemoveElementFromRefereringAttributes( CDmElement *pElement, bool bPreserveOrder = true ); |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// element-specific unique name generation methods |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
// returns startindex if none found, 2 if only "prefix" found, and n+1 if "prefixn" found |
|
int GenerateUniqueNameIndex( const char *prefix, const CUtlVector< DmElementHandle_t > &array, int startindex = -1 ); |
|
|
|
bool GenerateUniqueName( char *name, int memsize, const char *prefix, const CUtlVector< DmElementHandle_t > &array ); |
|
|
|
void MakeElementNameUnique( CDmElement *pElement, const char *prefix, const CUtlVector< DmElementHandle_t > &array, bool forceIndex = false ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// helper for making attributevarelementarray cleanup easier |
|
//----------------------------------------------------------------------------- |
|
template< class T > |
|
inline void CDmElement::DeleteAttributeVarElementArray( T &array ) |
|
{ |
|
int nElements = array.Count(); |
|
for ( int i = 0; i < nElements; ++i ) |
|
{ |
|
g_pDataModel->DestroyElement( array.GetHandle( i ) ); |
|
} |
|
array.RemoveAll(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Default size computation |
|
//----------------------------------------------------------------------------- |
|
template< class T > |
|
int DmeEstimateMemorySize( T* pElement ) |
|
{ |
|
return sizeof( T ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Helper macro to create an element; this is used for elements that are helper base classes |
|
//----------------------------------------------------------------------------- |
|
#define DEFINE_UNINSTANCEABLE_ELEMENT( className, baseClassName ) \ |
|
protected: \ |
|
className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \ |
|
baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \ |
|
{ \ |
|
} \ |
|
virtual ~className() \ |
|
{ \ |
|
} \ |
|
void OnConstruction(); \ |
|
void OnDestruction(); \ |
|
virtual void PerformConstruction() \ |
|
{ \ |
|
BaseClass::PerformConstruction(); \ |
|
OnConstruction(); \ |
|
} \ |
|
virtual void PerformDestruction() \ |
|
{ \ |
|
OnDestruction(); \ |
|
BaseClass::PerformDestruction(); \ |
|
} \ |
|
virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \ |
|
\ |
|
private: \ |
|
typedef baseClassName BaseClass; \ |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Helper macro to create the class factory |
|
//----------------------------------------------------------------------------- |
|
#define DEFINE_ELEMENT( className, baseClassName ) \ |
|
public: \ |
|
virtual bool IsA( UtlSymId_t typeSymbol ) const \ |
|
{ \ |
|
return IsA_Implementation( typeSymbol );\ |
|
} \ |
|
\ |
|
bool IsA( const char *pTypeName ) const \ |
|
{ \ |
|
CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); \ |
|
return IsA( typeSymbol ); \ |
|
} \ |
|
\ |
|
template< class T > bool IsA() const \ |
|
{ \ |
|
return IsA( T::GetStaticTypeSymbol() ); \ |
|
} \ |
|
\ |
|
virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const \ |
|
{ \ |
|
return GetInheritanceDepth_Implementation( typeSymbol, 0 ); \ |
|
} \ |
|
\ |
|
static CUtlSymbol GetStaticTypeSymbol( ) \ |
|
{ \ |
|
return m_classType; \ |
|
} \ |
|
\ |
|
className* Copy( TraversalDepth_t depth = TD_DEEP ) const \ |
|
{ \ |
|
return static_cast< className* >( CopyInternal( depth ) ); \ |
|
} \ |
|
protected: \ |
|
className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \ |
|
baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \ |
|
{ \ |
|
} \ |
|
virtual ~className() \ |
|
{ \ |
|
} \ |
|
void OnConstruction(); \ |
|
void OnDestruction(); \ |
|
virtual void PerformConstruction() \ |
|
{ \ |
|
BaseClass::PerformConstruction(); \ |
|
OnConstruction(); \ |
|
} \ |
|
virtual void PerformDestruction() \ |
|
{ \ |
|
OnDestruction(); \ |
|
BaseClass::PerformDestruction(); \ |
|
} \ |
|
static void SetTypeSymbol( CUtlSymbol typeSymbol ) \ |
|
{ \ |
|
m_classType = typeSymbol; \ |
|
} \ |
|
\ |
|
static bool IsA_Implementation( CUtlSymbol typeSymbol ) \ |
|
{ \ |
|
if ( typeSymbol == m_classType ) \ |
|
return true; \ |
|
return BaseClass::IsA_Implementation( typeSymbol ); \ |
|
} \ |
|
\ |
|
static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) \ |
|
{ \ |
|
if ( typeSymbol == m_classType ) \ |
|
return nCurrentDepth; \ |
|
return BaseClass::GetInheritanceDepth_Implementation( typeSymbol, nCurrentDepth+1 );\ |
|
} \ |
|
virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \ |
|
\ |
|
private: \ |
|
typedef baseClassName BaseClass; \ |
|
template <class T> friend class CDmElementFactory; \ |
|
template <class T> friend class CDmAbstractElementFactory; \ |
|
static CUtlSymbol m_classType |
|
|
|
#define IMPLEMENT_ELEMENT( className ) \ |
|
CUtlSymbol className::m_classType = UTL_INVAL_SYMBOL; |
|
|
|
|
|
#endif // DMELEMENT_H
|
|
|