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.

440 lines
13 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef DMATTRIBUTE_H
  7. #define DMATTRIBUTE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "datamodel/attributeflags.h"
  12. #include "datamodel/idatamodel.h"
  13. #include "datamodel/dmattributetypes.h"
  14. #include "datamodel/dmvar.h"
  15. #include "tier1/utlhash.h"
  16. //-----------------------------------------------------------------------------
  17. // Forward declarations
  18. //-----------------------------------------------------------------------------
  19. class CDmElement;
  20. class CUtlBuffer;
  21. //-----------------------------------------------------------------------------
  22. // Used for in-place modification
  23. //-----------------------------------------------------------------------------
  24. typedef void *DmAttributeModifyHandle_t;
  25. //-----------------------------------------------------------------------------
  26. // Purpose: A general purpose pAttribute. Eventually will be extensible to arbitrary user types
  27. //-----------------------------------------------------------------------------
  28. class CDmAttribute
  29. {
  30. public:
  31. // Returns the type
  32. DmAttributeType_t GetType() const;
  33. const char *GetTypeString() const;
  34. template< class T > bool IsA() const;
  35. // ChangeType fails (and returns false) for external attributes (ones who's data is owned by their element)
  36. bool ChangeType_UNSAFE( DmAttributeType_t type );
  37. bool IsStandard() const;
  38. // Returns the name. NOTE: The utlsymbol
  39. // can be turned into a string by using g_pDataModel->String();
  40. const char *GetName() const;
  41. CUtlSymbolLarge GetNameSymbol() const;
  42. void SetName( const char *newName );
  43. // Gets the attribute value
  44. // NOTE: GetValueUntyped is used with GetType() for use w/ SetValue( type, void* )
  45. template< class T > const T& GetValue() const;
  46. template< class T > const T& GetValue( const T& defaultValue ) const;
  47. const char *GetValueString() const;
  48. template< class E > E *GetValueElement() const;
  49. const void *GetValueUntyped() const;
  50. // Sets the attribute value
  51. template< class T > void SetValue( const T &value );
  52. template< class E > void SetValue( E* pValue );
  53. void SetValue( const void *pValue, size_t nSize );
  54. // Copies w/ type conversion (if possible) from another attribute
  55. void SetValue( const CDmAttribute *pAttribute );
  56. void SetValue( CDmAttribute *pAttribute );
  57. void SetValue( DmAttributeType_t valueType, const void *pValue );
  58. // Sets the attribute to its default value based on its type
  59. void SetToDefaultValue();
  60. // Convert to and from string
  61. void SetValueFromString( const char *pValue );
  62. const char *GetValueAsString( char *pBuffer, size_t nBufLen ) const;
  63. // Used for in-place modification of the data; preferable to set value
  64. // for large data like arrays or binary blocks
  65. template< class T > T& BeginModifyValueInPlace( DmAttributeModifyHandle_t *pHandle );
  66. template< class T > void EndModifyValueInPlace( DmAttributeModifyHandle_t handle );
  67. // Used for element and element array attributes; it specifies which type of
  68. // elements are valid to be referred to by this attribute
  69. void SetElementTypeSymbol( CUtlSymbolLarge typeSymbol );
  70. CUtlSymbolLarge GetElementTypeSymbol() const;
  71. // Returns the next attribute
  72. CDmAttribute *NextAttribute();
  73. const CDmAttribute *NextAttribute() const;
  74. // Returns the owner
  75. CDmElement *GetOwner();
  76. // Methods related to flags
  77. void AddFlag( int flags );
  78. void RemoveFlag( int flags );
  79. void ClearFlags();
  80. int GetFlags() const;
  81. bool IsFlagSet( int flags ) const;
  82. // Serialization
  83. bool Serialize( CUtlBuffer &buf ) const;
  84. bool Unserialize( CUtlBuffer &buf );
  85. bool IsIdenticalToSerializedValue( CUtlBuffer &buf ) const;
  86. // Serialization of a single element.
  87. // First version of UnserializeElement adds to tail if it worked
  88. // Second version overwrites, but does not add, the element at the specified index
  89. bool SerializeElement( int nElement, CUtlBuffer &buf ) const;
  90. bool UnserializeElement( CUtlBuffer &buf );
  91. bool UnserializeElement( int nElement, CUtlBuffer &buf );
  92. // Does this attribute serialize on multiple lines?
  93. bool SerializesOnMultipleLines() const;
  94. // Get the attribute/create an attribute handle
  95. DmAttributeHandle_t GetHandle( bool bCreate = true );
  96. // estimate memory overhead
  97. int EstimateMemoryUsage( TraversalDepth_t depth ) const;
  98. private:
  99. // Class factory
  100. static CDmAttribute *CreateAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
  101. static CDmAttribute *CreateExternalAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pExternalMemory );
  102. static void DestroyAttribute( CDmAttribute *pAttribute );
  103. // Constructor, destructor
  104. CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
  105. CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pMemory );
  106. ~CDmAttribute();
  107. // Used when constructing CDmAttributes
  108. void Init( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
  109. // Used when shutting down, indicates DmAttributeHandle_t referring to this are invalid
  110. void InvalidateHandle();
  111. // Called when the attribute changes
  112. void OnChanged( bool bArrayCountChanged = false, bool bIsTopological = false );
  113. // Is modification allowed in this phase?
  114. bool ModificationAllowed() const;
  115. // Mark the attribute as being dirty
  116. bool MarkDirty();
  117. // Is the data inline in a containing element class?
  118. bool IsDataInline() const;
  119. // Allocates, frees internal data storage
  120. void CreateAttributeData();
  121. void DeleteAttributeData();
  122. // Gets at the internal data storage
  123. void* GetAttributeData();
  124. const void* GetAttributeData() const;
  125. template < class T > typename CDmAttributeInfo< T >::StorageType_t* GetData();
  126. template < class T > const typename CDmAttributeInfo< T >::StorageType_t* GetData() const;
  127. template < class T > typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData();
  128. template < class T > const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData() const;
  129. // Used by CDmElement to manage the list of attributes it owns
  130. CDmAttribute **GetNextAttributeRef();
  131. // Implementational function used for memory consumption estimation computation
  132. int EstimateMemoryUsageInternal( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ) const;
  133. // Called by elements after unserialization of their attributes is complete
  134. void OnUnserializationFinished();
  135. template< class T > bool IsTypeConvertable() const;
  136. template< class T > bool ShouldModify( const T& src );
  137. template< class T > void CopyData( const T& src );
  138. template< class T > void CopyDataOut( T& dest ) const;
  139. private:
  140. CDmAttribute *m_pNext;
  141. void *m_pData;
  142. CDmElement *m_pOwner;
  143. DmAttributeHandle_t m_Handle;
  144. uint16 m_nFlags;
  145. CUtlSymbolLarge m_Name;
  146. friend class CDmElement;
  147. friend class CDmAttributeAccessor;
  148. template< class T > friend class CDmrElementArray;
  149. template< class E > friend class CDmrElementArrayConst;
  150. template< class T > friend class CDmaArrayAccessor;
  151. template< class T, class B > friend class CDmrDecorator;
  152. template< class T, class B > friend class CDmrDecoratorConst;
  153. template< class T > friend class CDmArrayAttributeOp;
  154. };
  155. //-----------------------------------------------------------------------------
  156. // Inline methods
  157. //-----------------------------------------------------------------------------
  158. inline DmAttributeType_t CDmAttribute::GetType() const
  159. {
  160. return (DmAttributeType_t)( m_nFlags & FATTRIB_TYPEMASK );
  161. }
  162. template< class T > inline bool CDmAttribute::IsA() const
  163. {
  164. return GetType() == CDmAttributeInfo< T >::AttributeType();
  165. }
  166. inline const char *CDmAttribute::GetName() const
  167. {
  168. return m_Name.String();
  169. }
  170. inline CUtlSymbolLarge CDmAttribute::GetNameSymbol() const
  171. {
  172. return m_Name;
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Iteration
  176. //-----------------------------------------------------------------------------
  177. inline CDmAttribute *CDmAttribute::NextAttribute()
  178. {
  179. return m_pNext;
  180. }
  181. inline const CDmAttribute *CDmAttribute::NextAttribute() const
  182. {
  183. return m_pNext;
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Returns the owner
  187. //-----------------------------------------------------------------------------
  188. inline CDmElement *CDmAttribute::GetOwner()
  189. {
  190. return m_pOwner;
  191. }
  192. //-----------------------------------------------------------------------------
  193. // Value getting methods
  194. //-----------------------------------------------------------------------------
  195. template< class T >
  196. inline const T& CDmAttribute::GetValue( const T& defaultValue ) const
  197. {
  198. if ( (int)GetType() == (int)CDmAttributeInfo< T >::ATTRIBUTE_TYPE )
  199. return *reinterpret_cast< const T* >( m_pData );
  200. if ( IsTypeConvertable< T >() )
  201. {
  202. static T tempVal;
  203. CopyDataOut( tempVal );
  204. return tempVal;
  205. }
  206. Assert( 0 );
  207. return defaultValue;
  208. }
  209. template< class T >
  210. inline const T& CDmAttribute::GetValue() const
  211. {
  212. static CDmaVar< T > defaultVal;
  213. return GetValue( defaultVal.Get() );
  214. }
  215. inline const char *CDmAttribute::GetValueString() const
  216. {
  217. Assert( GetType() == AT_STRING );
  218. if ( GetType() != AT_STRING )
  219. return NULL;
  220. CUtlSymbolLarge symbol = GetValue< CUtlSymbolLarge >();
  221. return symbol.String();
  222. }
  223. // used with GetType() for use w/ SetValue( type, void* )
  224. inline const void* CDmAttribute::GetValueUntyped() const
  225. {
  226. return m_pData;
  227. }
  228. #ifndef POSIX
  229. template< class E >
  230. inline E* CDmAttribute::GetValueElement() const
  231. {
  232. Assert( GetType() == AT_ELEMENT );
  233. if ( GetType() == AT_ELEMENT )
  234. return GetElement<E>( this->GetValue<DmElementHandle_t>( ) );
  235. return NULL;
  236. }
  237. #endif
  238. //-----------------------------------------------------------------------------
  239. // Value setting methods
  240. //-----------------------------------------------------------------------------
  241. template< class E >
  242. inline void CDmAttribute::SetValue( E* pValue )
  243. {
  244. Assert( GetType() == AT_ELEMENT );
  245. if ( GetType() == AT_ELEMENT )
  246. {
  247. SetValue( pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID );
  248. }
  249. }
  250. template<>
  251. inline void CDmAttribute::SetValue( const char *pValue )
  252. {
  253. CUtlSymbolLarge symbol = g_pDataModel->GetSymbol( pValue );
  254. return SetValue( symbol );
  255. }
  256. template<>
  257. inline void CDmAttribute::SetValue( char *pValue )
  258. {
  259. return SetValue( (const char *)pValue );
  260. }
  261. inline void CDmAttribute::SetValue( const void *pValue, size_t nSize )
  262. {
  263. CUtlBinaryBlock buf( pValue, nSize );
  264. return SetValue( buf );
  265. }
  266. //-----------------------------------------------------------------------------
  267. // Methods related to flags
  268. //-----------------------------------------------------------------------------
  269. inline void CDmAttribute::AddFlag( int nFlags )
  270. {
  271. m_nFlags |= ( nFlags & ~FATTRIB_TYPEMASK );
  272. }
  273. inline void CDmAttribute::RemoveFlag( int nFlags )
  274. {
  275. m_nFlags &= ~nFlags | FATTRIB_TYPEMASK;
  276. }
  277. inline void CDmAttribute::ClearFlags()
  278. {
  279. RemoveFlag( 0xffffffff );
  280. }
  281. inline int CDmAttribute::GetFlags() const
  282. {
  283. return m_nFlags & ~FATTRIB_TYPEMASK;
  284. }
  285. inline bool CDmAttribute::IsFlagSet( int nFlags ) const
  286. {
  287. return ( nFlags & GetFlags() ) != 0;
  288. }
  289. inline bool CDmAttribute::IsDataInline() const
  290. {
  291. return !IsFlagSet( FATTRIB_EXTERNAL );
  292. }
  293. //-----------------------------------------------------------------------------
  294. // Gets at the internal data storage
  295. //-----------------------------------------------------------------------------
  296. inline void* CDmAttribute::GetAttributeData()
  297. {
  298. return m_pData;
  299. }
  300. inline const void* CDmAttribute::GetAttributeData() const
  301. {
  302. return m_pData;
  303. }
  304. template < class T >
  305. inline typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData()
  306. {
  307. return ( typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
  308. }
  309. template < class T >
  310. inline typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData()
  311. {
  312. return ( typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
  313. }
  314. template < class T >
  315. inline const typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData() const
  316. {
  317. return ( const typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
  318. }
  319. template < class T >
  320. inline const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData() const
  321. {
  322. return ( const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Used by CDmElement to manage the list of attributes it owns
  326. //-----------------------------------------------------------------------------
  327. inline CDmAttribute **CDmAttribute::GetNextAttributeRef()
  328. {
  329. return &m_pNext;
  330. }
  331. //-----------------------------------------------------------------------------
  332. // helper function for determining which attributes/elements to traverse during copy/find/save/etc.
  333. //-----------------------------------------------------------------------------
  334. inline bool ShouldTraverse( const CDmAttribute *pAttr, TraversalDepth_t depth )
  335. {
  336. switch ( depth )
  337. {
  338. case TD_NONE:
  339. return false;
  340. case TD_SHALLOW:
  341. if ( !pAttr->IsFlagSet( FATTRIB_MUSTCOPY ) )
  342. return false;
  343. // fall-through intentional
  344. case TD_DEEP:
  345. if ( pAttr->IsFlagSet( FATTRIB_NEVERCOPY ) )
  346. return false;
  347. // fall-through intentional
  348. case TD_ALL:
  349. return true;
  350. }
  351. Assert( 0 );
  352. return false;
  353. }
  354. #endif // DMATTRIBUTE_H