blob: 2882c58569db3456902f3700c4162d878192ee8d (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
//========= 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)src.key;
}
CUtlHash< HashEntry > m_HashTable;
};
#include "tier0/memdbgoff.h"
#endif // ENTITYDATAINSTANTIATOR_H
|