#ifndef DMXATTRIBUTE_H #define DMXATTRIBUTE_H #ifdef _WIN32 #pragma once #endif #include "dmattributetypes.h" #include "utlvector.h" #include "utlrbtree.h" #include "utlsymbol.h" #include "mempool.h" #include "dmxloader.h" class CDmxElement; #define DECLARE_DMX_ATTRIBUTE_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName, _defaultSetStatement ) \ template< > class CDmAttributeInfo< _className > \ { \ private: \ enum { ATTRIBUTE_TYPE = _attributeType }; \ typedef _storageType StorageType_t; \ static DmAttributeType_t AttributeType() { return _attributeType; } \ static const char *AttributeTypeName() { return _attributeName; } \ static void SetDefaultValue( _className& value ) { _defaultSetStatement } \ friend class CDmxAttribute; \ friend class CDmxElement; \ }; \ #define DECLARE_DMX_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName ) \ template< > class CDmAttributeInfo< CUtlVector<_className> > \ { \ private: \ enum { ATTRIBUTE_TYPE = _attributeType }; \ typedef _storageType StorageType_t; \ static DmAttributeType_t AttributeType() { return _attributeType; } \ static const char *AttributeTypeName() { return _attributeName; } \ static void SetDefaultValue( CUtlVector< _className >& value ) { value.RemoveAll(); } \ friend class CDmxAttribute; \ friend class CDmxElement; \ }; \ #define DECLARE_DMX_ATTRIBUTE_TYPE( _className, _attributeType, _attributeName, _defaultSetStatement ) \ DECLARE_DMX_ATTRIBUTE_TYPE_INTERNAL( _className, _className, _attributeType, _attributeName, _defaultSetStatement ) #define DECLARE_DMX_ATTRIBUTE_ARRAY_TYPE( _className, _attributeType, _attributeName )\ DECLARE_DMX_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, CUtlVector< _className >, _attributeType, _attributeName ) DECLARE_DMX_ATTRIBUTE_TYPE(CDmxElement*, AT_ELEMENT, "element", value = 0; ) DECLARE_DMX_ATTRIBUTE_ARRAY_TYPE(CDmxElement*, AT_ELEMENT_ARRAY, "element_array") DECLARE_DMX_ATTRIBUTE_TYPE(CUtlString, AT_STRING, "string", value.Set(NULL); ) DECLARE_DMX_ATTRIBUTE_ARRAY_TYPE(CUtlString, AT_STRING_ARRAY, "string_array") class CDmxAttribute { DECLARE_DMX_ALLOCATOR(); public: DmAttributeType_t GetType() const; const char* GetTypeString() const; template< class T > bool IsA() const; const char* GetName() const; CUtlSymbolLarge GetNameSymbol() const; void SetName(const char* pName); template< class T > const T& GetValue() const; template< class T > const CUtlVector< T >& GetArray() const; const char* GetValueString() const; template< class T > void SetValue(const T& value); void SetValue(const char* pString); void SetValue(char* pString); void SetValue(const void* pBuffer, size_t nLen); void SetValue(const CDmxAttribute* pAttribute); template< class T > CUtlVector< T >& GetArrayForEdit(); void SetToDefaultValue(); void SetValueFromString(const char* pValue); const char* GetValueAsString(char* pBuffer, size_t nBufLen) const; int GetArrayCount() const; bool Unserialize(DmAttributeType_t type, CUtlBuffer& buf); bool UnserializeElement(DmAttributeType_t type, CUtlBuffer& buf); bool Serialize(CUtlBuffer& buf) const; bool SerializeElement(int nIndex, CUtlBuffer& buf) const; bool SerializesOnMultipleLines() const; static int AttributeDataSize(DmAttributeType_t type); static DmAttributeType_t ArrayAttributeBasicType(DmAttributeType_t type); private: CDmxAttribute(const char* pAttributeName); CDmxAttribute(CUtlSymbolLarge attributeName); ~CDmxAttribute(); void AllocateDataMemory(DmAttributeType_t type); void AllocateDataMemory_AndConstruct(DmAttributeType_t type); void FreeDataMemory(); void SetValue(DmAttributeType_t type, const void* pSrc, int nLen); void SetArrayValue(DmAttributeType_t type, const void* pSrc, int nDataTypeSize, int nArrayLength, int nSrcStride); void GetArrayValue(DmAttributeType_t type, void* pDest, int nDataTypeSize, int nArrayLength, const char* pDefaultString = NULL) const; void SetArrayCount(int nArrayCount); const void* GetArrayBase(void) const; template < class VT, class T > void ConstructDataMemory(void); template < class VT, class T > void DestructDataMemory(void); template < class VT, class T > void SetArrayCount(int nArrayCount); template < class VT, class T > void GetArrayCount(int& nArrayCount) const; template < class VT, class T > void GetArrayBase(const void*& pBasePtr) const; template < class VT, class T > void SerializesOnMultipleLines(bool& bResult) const; template < class VT, class T > void SerializeType(bool& bSuccess, CUtlBuffer& buf) const; template < class VT, class T > void SerializeTypedElement(bool& bSuccess, int nIndex, CUtlBuffer& buf) const; template < class VT, class T > void UnserializeType(bool& bSuccess, CUtlBuffer& buf); template < class VT, class T > void UnserializeTypedElement(bool& bSuccess, CUtlBuffer& buf); template < class VT, class T > void SetDefaultValue(void); DmAttributeType_t m_Type; CUtlSymbolLarge m_Name; void* m_pData; static CUtlSymbolTableLargeMT s_AttributeNameSymbols; friend class CDmxElement; public: static const char* s_pAttributeTypeName[AT_TYPE_COUNT]; }; inline DmAttributeType_t CDmxAttribute::GetType() const { return m_Type; } template< class T > inline bool CDmxAttribute::IsA() const { return GetType() == CDmAttributeInfo< T >::ATTRIBUTE_TYPE; } inline CUtlSymbolLarge CDmxAttribute::GetNameSymbol() const { return m_Name; } template< class T > void CDmxAttribute::SetValue(const T& value) { AllocateDataMemory(CDmAttributeInfo::AttributeType()); CopyConstruct((T*)m_pData, value); } inline const char* CDmxAttribute::GetValueString() const { if (m_Type == AT_STRING) return *(CUtlString*)m_pData; return ""; } template< class T > inline const T& CDmxAttribute::GetValue() const { if (CDmAttributeInfo::AttributeType() == m_Type) return *(T*)m_pData; static T defaultValue; CDmAttributeInfo::SetDefaultValue(defaultValue); return defaultValue; } template< class T > inline const CUtlVector< T >& CDmxAttribute::GetArray() const { if (CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type) return *(CUtlVector< T >*)m_pData; static CUtlVector defaultArray; return defaultArray; } template< class T > inline CUtlVector< T >& CDmxAttribute::GetArrayForEdit() { if (CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type) return *(CUtlVector< T >*)m_pData; AllocateDataMemory(CDmAttributeInfo< CUtlVector< T > >::AttributeType()); Construct((CUtlVector*)m_pData); return *(CUtlVector< T >*)m_pData; } #endif