Counter Strike : Global Offensive Source Code
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.

532 lines
22 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef DMXELEMENT_H
  7. #define DMXELEMENT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "datamodel/dmattributetypes.h"
  12. #include "tier1/utlvector.h"
  13. #include "tier1/utlrbtree.h"
  14. #include "tier1/utlsymbol.h"
  15. #include "tier1/mempool.h"
  16. #include "tier1/utlsortvector.h"
  17. #include "dmxloader/dmxattribute.h"
  18. //-----------------------------------------------------------------------------
  19. // Sort functor class for attributes
  20. //-----------------------------------------------------------------------------
  21. class CDmxAttributeLess
  22. {
  23. public:
  24. bool Less( const CDmxAttribute * pAttribute1, const CDmxAttribute *pAttribute2, void *pContext )
  25. {
  26. return (pAttribute1?pAttribute1->GetNameSymbol():CUtlSymbolLarge(UTL_INVAL_SYMBOL_LARGE)) < (pAttribute2?pAttribute2->GetNameSymbol():CUtlSymbolLarge(UTL_INVAL_SYMBOL_LARGE));
  27. }
  28. };
  29. enum BitfieldType_t
  30. {
  31. BITFIELD_TYPE_NONE,
  32. BITFIELD_TYPE_BOOL,
  33. BITFIELD_TYPE_CHAR,
  34. BITFIELD_TYPE_UNSIGNED_CHAR,
  35. BITFIELD_TYPE_BYTE = BITFIELD_TYPE_UNSIGNED_CHAR,
  36. BITFIELD_TYPE_SHORT,
  37. BITFIELD_TYPE_UNSIGNED_SHORT,
  38. BITFIELD_TYPE_INT,
  39. BITFIELD_TYPE_UNSIGNED_INT,
  40. };
  41. //-----------------------------------------------------------------------------
  42. // Used to unpack elements into a structure. Does not recurse
  43. // Also does not work with arrays.
  44. //-----------------------------------------------------------------------------
  45. struct DmxElementUnpackStructure_t
  46. {
  47. const char *m_pAttributeName;
  48. const char *m_pDefaultString;
  49. DmAttributeType_t m_AttributeType;
  50. int m_nOffset;
  51. int m_nSize; // If size is -1 the AT_STRING datatype is considered to be a UtlString, rather than a char array.
  52. int m_nBitOffset; // Default value for this should be -1. A non-negative value indicates that the attribute is a bitfield and
  53. // m_nSize should be interpreted as number of bits
  54. BitfieldType_t m_BitfieldType; // the data type of your variable in the bitfield.
  55. const void *m_pUserData; // If you want to associate some app-specific data with each field
  56. // Embedded structure / Baseclass ptr
  57. const char *m_pTypeName;
  58. const DmxElementUnpackStructure_t *m_pSub;
  59. int m_nArrayLength; // For fixed-size arrays, this is a positive value (default is 0). For arrays, m_nSize is the size of an array element and m_pDefaultString is the default element value.
  60. };
  61. #define NO_BIT_OFFSET -1
  62. #define UTL_STRING_SIZE -1
  63. #define NO_USER_DATA NULL
  64. #define NO_EMBEDDED_TYPENAME NULL
  65. #define NO_EMBEDDED_STRUCT_PTR NULL
  66. #define NOT_A_BITFIELD BITFIELD_TYPE_NONE
  67. #define NOT_AN_ARRAY 0
  68. #define DECLARE_DMXELEMENT_UNPACK() \
  69. template <typename T> friend DmxElementUnpackStructure_t *DmxElementUnpackInit(T *);
  70. #define BEGIN_DMXELEMENT_UNPACK( _structName ) \
  71. template <typename T> DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); \
  72. template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ); \
  73. namespace _structName##_UnpackInit \
  74. { \
  75. static DmxElementUnpackStructure_t *s_pUnpack = DmxElementUnpackInit( (_structName *)NULL ); \
  76. } \
  77. \
  78. template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ) \
  79. { \
  80. typedef _structName DestStructType_t; \
  81. static DmxElementUnpackStructure_t unpack[] = \
  82. { \
  83. #define DMXELEMENT_UNPACK_FLTX4( _attributeName, _defaultString, _varName ) \
  84. { _attributeName, _defaultString, CDmAttributeInfo<float>::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( fltx4 ), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  85. #define DMXELEMENT_UNPACK_EMBEDDED( _typeName, _attributeName, _varName, _embeddedUnpackStructure ) \
  86. { _attributeName, "", AT_TYPE_COUNT, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, _typeName, _embeddedUnpackStructure, NOT_AN_ARRAY },
  87. #define DMXELEMENT_UNPACK_BASECLASS( _structName, _baseClass ) \
  88. { "Baseclass unpack", "", AT_TYPE_COUNT, size_cast< int >((intp) static_cast< _baseClass * >( (_structName*)0)), 0, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, #_baseClass, DmxElementUnpackInit<_baseClass>( (_baseClass *)0 ), NOT_AN_ARRAY },
  89. #define DMXELEMENT_UNPACK_BASECLASS_NAMESPACE( _namespace, _structName, _baseClass ) \
  90. { "Baseclass unpack", "", AT_TYPE_COUNT, size_cast< int >((intp) static_cast< _baseClass * >( (_structName*)0)), 0, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, #_baseClass, DmxElementUnpackInit##_namespace<_baseClass>( (_baseClass *)0 ), NOT_AN_ARRAY },
  91. #define VGUI_UNPACK_BASEPANEL() \
  92. DMXELEMENT_UNPACK_BASECLASS_NAMESPACE( vgui, DestStructType_t, DestStructType_t::BaseClass ) \
  93. #define DMXELEMENT_UNPACK_FIELD( _attributeName, _defaultString, _type, _varName ) \
  94. { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  95. // Use for preallocated char array
  96. #define DMXELEMENT_UNPACK_FIELD_STRING( _attributeName, _defaultString, _varName ) \
  97. { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  98. // Use for UtlString datatype
  99. #define DMXELEMENT_UNPACK_FIELD_UTLSTRING( _attributeName, _defaultString, _varName ) \
  100. { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), UTL_STRING_SIZE, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  101. #define DMXELEMENT_UNPACK_SHORT( _attributeName, _defaultString, _varName ) \
  102. { _attributeName, _defaultString, AT_INT, offsetof( DestStructType_t, _varName ), sizeof( short ), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  103. #define DMXELEMENT_UNPACK_CHAR( _attributeName, _defaultString, _varName ) \
  104. { _attributeName, _defaultString, AT_INT, offsetof( DestStructType_t, _varName ), sizeof( char ), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  105. #define DMXELEMENT_UNPACK_BITFIELD( _attributeName, _defaultString, _bitfieldType, _varName ) \
  106. { _attributeName, _defaultString, CDmAttributeInfo<int>::AttributeType(), DestStructType_t::Get##_varName##ByteOffset(), DestStructType_t::Get##_varName##BitCount(), DestStructType_t::Get##_varName##BitOffset(), _bitfieldType, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  107. // NOTE: DMXELEMENT_UNPACK_FIELD_ARRAY is for fixed-size arrays, not pointers or CUtlVectors (TODO: doesn't work for strings or bitfields yet!)
  108. #define DMXELEMENT_UNPACK_FIELD_ARRAY( _attributeName, _defaultString, _type, _varName ) \
  109. { _attributeName, _defaultString, CDmAttributeInfo< CUtlVector< _type > >::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName[0]), NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, ARRAYSIZE( ((DestStructType_t *)0)->_varName ) },
  110. #define DMXELEMENT_UNPACK_FIELD_USERDATA( _attributeName, _defaultString, _type, _varName, _userData ) \
  111. { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NO_BIT_OFFSET, NOT_A_BITFIELD, _userData, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  112. #define DMXELEMENT_UNPACK_FIELD_STRING_USERDATA( _attributeName, _defaultString, _varName, _userData ) \
  113. { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NO_BIT_OFFSET, NOT_A_BITFIELD, _userData, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  114. #define DMXELEMENT_UNPACK_FIELD_UTLSTRING_USERDATA( _attributeName, _defaultString, _varName, _userData ) \
  115. { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), UTL_STRING_SIZE, NO_BIT_OFFSET, NOT_A_BITFIELD, _userData, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR, NOT_AN_ARRAY },
  116. #define END_DMXELEMENT_UNPACK( _structName, _varName ) \
  117. { NULL, NULL, AT_UNKNOWN, 0, 0, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR } \
  118. }; \
  119. return unpack; \
  120. } \
  121. DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack;
  122. #define END_DMXELEMENT_UNPACK_TEMPLATE( _structName, _varName ) \
  123. { NULL, NULL, AT_UNKNOWN, 0, 0, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR } \
  124. }; \
  125. return unpack; \
  126. } \
  127. template<> DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack;
  128. // Macros for when your class is inside a namespace.
  129. #define BEGIN_DMXELEMENT_NAMESPACE_UNPACK( _nameSpace, _structName ) \
  130. template <typename T> DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); \
  131. template <> DmxElementUnpackStructure_t *_nameSpace::DmxElementUnpackInit<_nameSpace::_structName>( _nameSpace::_structName * ); \
  132. namespace _structName##_UnpackInit \
  133. { \
  134. static DmxElementUnpackStructure_t *s_pUnpack = _nameSpace::DmxElementUnpackInit( (_nameSpace::_structName *)NULL ); \
  135. } \
  136. \
  137. template <> DmxElementUnpackStructure_t *_nameSpace::DmxElementUnpackInit<_nameSpace::_structName>( _nameSpace::_structName * ) \
  138. { \
  139. typedef _nameSpace::_structName DestStructType_t; \
  140. static DmxElementUnpackStructure_t unpack[] = \
  141. { \
  142. //#define DECLARE_DMXELEMENT_UNPACK_NAMESPACE( _namespace ) \
  143. // template <typename T> friend DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace(T *);
  144. // Adds serialization unpack structure and unpack func to your class.
  145. #if defined( _PS3 ) && defined( __GCC__ )
  146. #define DECLARE_DMXELEMENT_UNPACK_NAMESPACE( _namespace ) \
  147. template <typename T> friend DmxElementUnpackStructure_t *_namespace::DmxElementUnpackInit##_namespace(T *); \
  148. private: \
  149. static DmxElementUnpackStructure_t *s_pUnpackParams; \
  150. public: \
  151. virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const { return s_pUnpackParams; }
  152. #else
  153. #define DECLARE_DMXELEMENT_UNPACK_NAMESPACE( _namespace ) \
  154. template <typename T> friend DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace(T *); \
  155. private: \
  156. static DmxElementUnpackStructure_t *s_pUnpackParams; \
  157. public: \
  158. virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const { return s_pUnpackParams; }
  159. #endif
  160. // Use when your panel class is derived from another baseclass
  161. #define BEGIN_DMXELEMENT_UNPACK_NAMESPACE_SIMPLE( _namespace, _structName ) \
  162. BEGIN_DMXELEMENT_UNPACK_NAMESPACE( _namespace, _structName ) \
  163. VGUI_UNPACK_BASEPANEL() \
  164. // Use when your panel class has no base class
  165. #define BEGIN_DMXELEMENT_UNPACK_NAMESPACE_SIMPLE_NO_BASE( _namespace, _structName ) \
  166. BEGIN_DMXELEMENT_UNPACK_NAMESPACE( _namespace, _structName ) \
  167. #define BEGIN_DMXELEMENT_UNPACK_NAMESPACE( _namespace, _structName ) \
  168. namespace _namespace { \
  169. template <typename T> DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace(T *); \
  170. template <> DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace<_structName>( _namespace::_structName * ); \
  171. namespace _namespace##_structName##_UnpackInit \
  172. { \
  173. static DmxElementUnpackStructure_t *s_pUnpack = _namespace::DmxElementUnpackInit##_namespace( (_namespace::_structName *)NULL ); \
  174. } \
  175. \
  176. template <> DmxElementUnpackStructure_t *DmxElementUnpackInit##_namespace<_structName>( _namespace::_structName * ) \
  177. { \
  178. typedef _structName DestStructType_t; \
  179. static DmxElementUnpackStructure_t unpack[] = \
  180. { \
  181. // Use to end BEGIN_DMXELEMENT_UNPACK_NAMESPACE* macros
  182. #define END_DMXELEMENT_UNPACK_NAMESPACE( _namespace, _structName, _varName ) \
  183. { NULL, NULL, AT_UNKNOWN, 0, 0, NO_BIT_OFFSET, NOT_A_BITFIELD, NO_USER_DATA, NO_EMBEDDED_TYPENAME, NO_EMBEDDED_STRUCT_PTR } \
  184. }; \
  185. return unpack; \
  186. } \
  187. DmxElementUnpackStructure_t *_structName::_varName = _namespace##_structName##_UnpackInit::s_pUnpack; \
  188. } \
  189. // Return a variable of type 'T' with all bits set
  190. template <typename T> inline T GetAllOnesNumber()
  191. {
  192. T temp = 0; /* Temp variable to avoid gcc warnings */
  193. return (T)~temp;
  194. }
  195. // Special case of GetAllOnesVar for bool to avoid
  196. // warnings from VC++.
  197. template <> inline bool GetAllOnesNumber<bool>()
  198. {
  199. return true;
  200. }
  201. #define DECLARE_DMXELEMENT_BITFIELD( _fieldName, _type, _structName ) \
  202. class CBitFieldInfo_##_fieldName \
  203. { \
  204. public: \
  205. CBitFieldInfo_##_fieldName () \
  206. { \
  207. const int nSize = ( sizeof(_structName) + 3 ) & ~0x3; \
  208. unsigned char pBuf[nSize] = {}; \
  209. (( _structName * )pBuf)->_fieldName = GetAllOnesNumber<_type>(); \
  210. _type *pTest = (_type *)pBuf; \
  211. for ( int i = 0; i < sizeof(_structName); ++i ) \
  212. { \
  213. if ( pTest[i] == 0 ) \
  214. continue; \
  215. \
  216. for ( int j = 0; j < 8*sizeof(_type); ++j ) \
  217. { \
  218. unsigned int temp = ((unsigned int)pTest[i]) & ( 1 << j ) ; \
  219. if ( temp == 0 ) \
  220. continue; \
  221. \
  222. m_nByteOffset = i*sizeof(_type) + j / 8; \
  223. m_nBitOffset = j & 0x7; \
  224. \
  225. int k; \
  226. for ( k = j+1; k < 8*sizeof(_type); ++k ) \
  227. { \
  228. unsigned int temp = ((unsigned int)pTest[i]) & ( 1 << k ) ; \
  229. if ( temp != 0 ) \
  230. continue; \
  231. break; \
  232. } \
  233. m_nBitCount = k - j; \
  234. break; \
  235. } \
  236. break; \
  237. } \
  238. } \
  239. \
  240. int GetByteOffset() const \
  241. { \
  242. return m_nByteOffset; \
  243. } \
  244. \
  245. int GetBitCount() const \
  246. { \
  247. return m_nBitCount; \
  248. } \
  249. \
  250. int GetBitOffset() const \
  251. { \
  252. return m_nBitOffset; \
  253. } \
  254. \
  255. private: \
  256. int m_nByteOffset; \
  257. int m_nBitCount; \
  258. int m_nBitOffset; \
  259. }; \
  260. \
  261. static int Get##_fieldName##BitCount() \
  262. { \
  263. CBitFieldInfo_##_fieldName info; \
  264. return info.GetBitCount(); \
  265. } \
  266. \
  267. static int Get##_fieldName##ByteOffset() \
  268. { \
  269. CBitFieldInfo_##_fieldName info; \
  270. return info.GetByteOffset(); \
  271. } \
  272. \
  273. static int Get##_fieldName##BitOffset() \
  274. { \
  275. CBitFieldInfo_##_fieldName info; \
  276. return info.GetBitOffset(); \
  277. } \
  278. friend class CBitFieldInfo_##_fieldName; \
  279. // A bit of a hack, but we don't have access to
  280. extern CUtlSymbolTableLargeMT g_DmxAttributeStrings;
  281. //-----------------------------------------------------------------------------
  282. // Element used to read dmx files from mod code. Similar to keyvalues.
  283. //-----------------------------------------------------------------------------
  284. class CDmxElement
  285. {
  286. DECLARE_DMX_ALLOCATOR( );
  287. public:
  288. bool HasAttribute( const char *pAttributeName ) const;
  289. CDmxAttribute *GetAttribute( const char *pAttributeName );
  290. const CDmxAttribute *GetAttribute( const char *pAttributeName ) const;
  291. int AttributeCount() const;
  292. CDmxAttribute *GetAttribute( int nIndex );
  293. const CDmxAttribute *GetAttribute( int nIndex ) const;
  294. CUtlSymbolLarge GetType() const;
  295. const char* GetTypeString() const;
  296. const char* GetName() const;
  297. const DmObjectId_t &GetId() const;
  298. // Add+remove+rename can only occur during lock
  299. // NOTE: AddAttribute will find or add; returning an existing attribute if
  300. // one with the appropriate name exists
  301. void LockForChanges( bool bLock );
  302. CDmxAttribute *AddAttribute( const char *pAttributeName );
  303. void RemoveAttribute( const char *pAttributeName );
  304. void RemoveAttributeByPtr( CDmxAttribute *pAttribute );
  305. void RemoveAllAttributes();
  306. void RenameAttribute( const char *pAttributeName, const char *pNewName );
  307. // Simple methods to read attributes
  308. const char *GetValueString( const char *pAttributeName ) const;
  309. template< class T > const T& GetValue( const char *pAttributeName ) const;
  310. template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const;
  311. template< class T > const CUtlVector<T>& GetArray( const char *pAttributeName ) const;
  312. template< class T > const CUtlVector<T>& GetArray( const char *pAttributeName, const CUtlVector<T>& defaultValue ) const;
  313. // Set methods
  314. void SetName( const char *pName );
  315. CDmxAttribute* SetValue( const char *pAttributeName, const char *pString );
  316. CDmxAttribute* SetValue( const char *pAttributeName, void *pBuffer, int nLen );
  317. template< class T > CDmxAttribute* SetValue( const char *pAttributeName, const T& value );
  318. // Method to unpack data into a structure
  319. void UnpackIntoStructure( void *pData, const DmxElementUnpackStructure_t *pUnpack ) const;
  320. // Creates attributes based on the unpack structure
  321. void AddAttributesFromStructure( const void *pData, const DmxElementUnpackStructure_t *pUnpack );
  322. private:
  323. typedef CUtlSortVector< CDmxAttribute*, CDmxAttributeLess > AttributeList_t;
  324. CDmxElement( const char *pType );
  325. ~CDmxElement();
  326. // Removes all elements recursively
  327. void RemoveAllElementsRecursive();
  328. // Adds elements to delete to the deletion list
  329. void AddElementsToDelete( CUtlVector< CDmxElement * >& elementsToDelete );
  330. // Sorts the vector when a change has occurred
  331. void Resort( ) const;
  332. // Finds an attribute by name
  333. int FindAttribute( const char *pAttributeName ) const;
  334. int FindAttribute( CUtlSymbolLarge attributeName ) const;
  335. // Sets the object id
  336. void SetId( const DmObjectId_t &id );
  337. // Are we locked?
  338. bool IsLocked() const;
  339. template <typename T> void UnpackBitfield( T *pDest2, const DmxElementUnpackStructure_t *pUnpack, const CDmxAttribute *pAttribute ) const;
  340. AttributeList_t m_Attributes;
  341. DmObjectId_t m_Id; // We need this strictly because we support serialization
  342. CUtlSymbolLarge m_Type;
  343. char m_nLockCount;
  344. mutable bool m_bResortNeeded : 1;
  345. bool m_bIsMarkedForDeletion : 1;
  346. static CUtlSymbolTableLargeMT s_TypeSymbols;
  347. friend class CDmxSerializer;
  348. friend class CDmxSerializerKeyValues2;
  349. friend void CleanupDMX( CDmxElement* pElement );
  350. friend CDmxElement* CreateDmxElement( const char *pType );
  351. };
  352. //-----------------------------------------------------------------------------
  353. // inline methods
  354. //-----------------------------------------------------------------------------
  355. // Are we locked?
  356. inline bool CDmxElement::IsLocked() const
  357. {
  358. return m_nLockCount > 0;
  359. }
  360. inline const char *CDmxElement::GetValueString( const char *pAttributeName ) const
  361. {
  362. const CDmxAttribute* pAttribute = GetAttribute( pAttributeName );
  363. if ( pAttribute )
  364. return pAttribute->GetValueString();
  365. return "";
  366. }
  367. template< class T >
  368. inline const T& CDmxElement::GetValue( const char *pAttributeName ) const
  369. {
  370. const CDmxAttribute* pAttribute = GetAttribute( pAttributeName );
  371. if ( pAttribute )
  372. return pAttribute->GetValue<T>();
  373. static T defaultValue;
  374. CDmAttributeInfo<T>::SetDefaultValue( defaultValue );
  375. return defaultValue;
  376. }
  377. template< class T >
  378. inline const T& CDmxElement::GetValue( const char *pAttributeName, const T& defaultValue ) const
  379. {
  380. const CDmxAttribute* pAttribute = GetAttribute( pAttributeName );
  381. if ( pAttribute )
  382. return pAttribute->GetValue<T>();
  383. return defaultValue;
  384. }
  385. template< class T >
  386. inline const CUtlVector<T>& CDmxElement::GetArray( const char *pAttributeName ) const
  387. {
  388. const CDmxAttribute* pAttribute = GetAttribute( pAttributeName );
  389. if ( pAttribute )
  390. return pAttribute->GetArray<T>();
  391. static CUtlVector<T> defaultValue;
  392. return defaultValue;
  393. }
  394. template< class T >
  395. inline const CUtlVector<T>& CDmxElement::GetArray( const char *pAttributeName, const CUtlVector<T>& defaultValue ) const
  396. {
  397. const CDmxAttribute* pAttribute = GetAttribute( pAttributeName );
  398. if ( pAttribute )
  399. return pAttribute->GetArray<T>();
  400. return defaultValue;
  401. }
  402. //-----------------------------------------------------------------------------
  403. // Creates a dmx element
  404. //-----------------------------------------------------------------------------
  405. CDmxElement* CreateDmxElement( const char *pType );
  406. //-----------------------------------------------------------------------------
  407. // Helper class to lock elements for changes
  408. //-----------------------------------------------------------------------------
  409. class CDmxElementModifyScope
  410. {
  411. public:
  412. CDmxElementModifyScope( CDmxElement *pElement ) : m_pElement( pElement )
  413. {
  414. m_pElement->LockForChanges( true );
  415. }
  416. ~CDmxElementModifyScope()
  417. {
  418. Release();
  419. }
  420. void Release()
  421. {
  422. if ( m_pElement )
  423. {
  424. m_pElement->LockForChanges( false );
  425. m_pElement = NULL;
  426. }
  427. }
  428. private:
  429. CDmxElement *m_pElement;
  430. };
  431. //-----------------------------------------------------------------------------
  432. // Set methods
  433. //-----------------------------------------------------------------------------
  434. inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const char *pString )
  435. {
  436. CDmxElementModifyScope modify( this );
  437. CDmxAttribute *pAttribute = AddAttribute( pAttributeName );
  438. pAttribute->SetValue( pString );
  439. return pAttribute;
  440. }
  441. inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, void *pBuffer, int nLen )
  442. {
  443. CDmxElementModifyScope modify( this );
  444. CDmxAttribute *pAttribute = AddAttribute( pAttributeName );
  445. pAttribute->SetValue( pBuffer, nLen );
  446. return pAttribute;
  447. }
  448. template< class T >
  449. inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const T& value )
  450. {
  451. CDmxElementModifyScope modify( this );
  452. CDmxAttribute *pAttribute = AddAttribute( pAttributeName );
  453. pAttribute->SetValue( value );
  454. return pAttribute;
  455. }
  456. #endif // DMXELEMENT_H