source-engine/game/shared/entitydatainstantiator.h
2022-06-05 01:12:32 +03:00

127 lines
2.9 KiB
C++

//========= 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