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
126 lines
2.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef ENTITYDATAINSTANTIATOR_H |
|
#define ENTITYDATAINSTANTIATOR_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "utlhash.h" |
|
|
|
#include "tier0/memdbgon.h" |
|
|
|
// This is the hash key type, but it could just as easily be and int or void * |
|
class CBaseEntity; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
abstract_class IEntityDataInstantiator |
|
{ |
|
public: |
|
virtual ~IEntityDataInstantiator() {}; |
|
|
|
virtual void *GetDataObject( const CBaseEntity *instance ) = 0; |
|
virtual void *CreateDataObject( const CBaseEntity *instance ) = 0; |
|
virtual void DestroyDataObject( const CBaseEntity *instance ) = 0; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
template <class T> |
|
class CEntityDataInstantiator : public IEntityDataInstantiator |
|
{ |
|
public: |
|
CEntityDataInstantiator() : |
|
m_HashTable( 64, 0, 0, CompareFunc, KeyFunc ) |
|
{ |
|
} |
|
|
|
virtual void *GetDataObject( const CBaseEntity *instance ) |
|
{ |
|
UtlHashHandle_t handle; |
|
HashEntry entry; |
|
entry.key = instance; |
|
handle = m_HashTable.Find( entry ); |
|
|
|
if ( handle != m_HashTable.InvalidHandle() ) |
|
{ |
|
return (void *)m_HashTable[ handle ].data; |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
virtual void *CreateDataObject( const CBaseEntity *instance ) |
|
{ |
|
UtlHashHandle_t handle; |
|
HashEntry entry; |
|
entry.key = instance; |
|
handle = m_HashTable.Find( entry ); |
|
|
|
// Create it if not already present |
|
if ( handle == m_HashTable.InvalidHandle() ) |
|
{ |
|
handle = m_HashTable.Insert( entry ); |
|
Assert( handle != m_HashTable.InvalidHandle() ); |
|
m_HashTable[ handle ].data = new T; |
|
|
|
// FIXME: We'll have to remove this if any objects we instance have vtables!!! |
|
Q_memset( m_HashTable[ handle ].data, 0, sizeof( T ) ); |
|
} |
|
|
|
return (void *)m_HashTable[ handle ].data; |
|
} |
|
|
|
virtual void DestroyDataObject( const CBaseEntity *instance ) |
|
{ |
|
UtlHashHandle_t handle; |
|
HashEntry entry; |
|
entry.key = instance; |
|
handle = m_HashTable.Find( entry ); |
|
|
|
if ( handle != m_HashTable.InvalidHandle() ) |
|
{ |
|
delete m_HashTable[ handle ].data; |
|
m_HashTable.Remove( handle ); |
|
} |
|
} |
|
|
|
private: |
|
|
|
struct HashEntry |
|
{ |
|
HashEntry() |
|
{ |
|
key = NULL; |
|
data = NULL; |
|
} |
|
|
|
const CBaseEntity *key; |
|
T *data; |
|
}; |
|
|
|
static bool CompareFunc( const HashEntry &src1, const HashEntry &src2 ) |
|
{ |
|
return ( src1.key == src2.key ); |
|
} |
|
|
|
|
|
static unsigned int KeyFunc( const HashEntry &src ) |
|
{ |
|
// Shift right to get rid of alignment bits and border the struct on a 16 byte boundary |
|
return (unsigned int)(uintp)src.key; |
|
} |
|
|
|
CUtlHash< HashEntry > m_HashTable; |
|
}; |
|
|
|
#include "tier0/memdbgoff.h" |
|
|
|
#endif // ENTITYDATAINSTANTIATOR_H
|
|
|