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.

126 lines
2.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef ENTITYDATAINSTANTIATOR_H
  7. #define ENTITYDATAINSTANTIATOR_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "utlhash.h"
  12. #include "tier0/memdbgon.h"
  13. // This is the hash key type, but it could just as easily be and int or void *
  14. class CBaseEntity;
  15. //-----------------------------------------------------------------------------
  16. // Purpose:
  17. //-----------------------------------------------------------------------------
  18. abstract_class IEntityDataInstantiator
  19. {
  20. public:
  21. virtual ~IEntityDataInstantiator() {};
  22. virtual void *GetDataObject( const CBaseEntity *instance ) = 0;
  23. virtual void *CreateDataObject( const CBaseEntity *instance ) = 0;
  24. virtual void DestroyDataObject( const CBaseEntity *instance ) = 0;
  25. };
  26. //-----------------------------------------------------------------------------
  27. // Purpose:
  28. //-----------------------------------------------------------------------------
  29. template <class T>
  30. class CEntityDataInstantiator : public IEntityDataInstantiator
  31. {
  32. public:
  33. CEntityDataInstantiator() :
  34. m_HashTable( 64, 0, 0, CompareFunc, KeyFunc )
  35. {
  36. }
  37. virtual void *GetDataObject( const CBaseEntity *instance )
  38. {
  39. UtlHashHandle_t handle;
  40. HashEntry entry;
  41. entry.key = instance;
  42. handle = m_HashTable.Find( entry );
  43. if ( handle != m_HashTable.InvalidHandle() )
  44. {
  45. return (void *)m_HashTable[ handle ].data;
  46. }
  47. return NULL;
  48. }
  49. virtual void *CreateDataObject( const CBaseEntity *instance )
  50. {
  51. UtlHashHandle_t handle;
  52. HashEntry entry;
  53. entry.key = instance;
  54. handle = m_HashTable.Find( entry );
  55. // Create it if not already present
  56. if ( handle == m_HashTable.InvalidHandle() )
  57. {
  58. handle = m_HashTable.Insert( entry );
  59. Assert( handle != m_HashTable.InvalidHandle() );
  60. m_HashTable[ handle ].data = new T;
  61. // FIXME: We'll have to remove this if any objects we instance have vtables!!!
  62. Q_memset( m_HashTable[ handle ].data, 0, sizeof( T ) );
  63. }
  64. return (void *)m_HashTable[ handle ].data;
  65. }
  66. virtual void DestroyDataObject( const CBaseEntity *instance )
  67. {
  68. UtlHashHandle_t handle;
  69. HashEntry entry;
  70. entry.key = instance;
  71. handle = m_HashTable.Find( entry );
  72. if ( handle != m_HashTable.InvalidHandle() )
  73. {
  74. delete m_HashTable[ handle ].data;
  75. m_HashTable.Remove( handle );
  76. }
  77. }
  78. private:
  79. struct HashEntry
  80. {
  81. HashEntry()
  82. {
  83. key = NULL;
  84. data = NULL;
  85. }
  86. const CBaseEntity *key;
  87. T *data;
  88. };
  89. static bool CompareFunc( const HashEntry &src1, const HashEntry &src2 )
  90. {
  91. return ( src1.key == src2.key );
  92. }
  93. static unsigned int KeyFunc( const HashEntry &src )
  94. {
  95. // Shift right to get rid of alignment bits and border the struct on a 16 byte boundary
  96. return (unsigned int)src.key;
  97. }
  98. CUtlHash< HashEntry > m_HashTable;
  99. };
  100. #include "tier0/memdbgoff.h"
  101. #endif // ENTITYDATAINSTANTIATOR_H