Add CEntityKeyValues, EntityInstanceIter_t, EntityInstanceByNameIter_t, EntityInstanceByClassIter_t & other stuff (#183)

* Replace g_pEntitySystem with GameEntitySystem() function;
* KeyValues3, CGameSystem & CVariant updates;
This commit is contained in:
vanz696 2023-12-23 20:03:58 +03:00 committed by GitHub
parent b02746e648
commit b2301a9ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 2127 additions and 377 deletions

View File

@ -0,0 +1,16 @@
#include "entityidentity.h"
#include "entitysystem.h"
#include "tier1/strtools.h"
bool CEntityIdentity::NameMatches( const char* szName ) const
{
if ( szName && szName[0] == '!' )
return GameEntitySystem()->FindEntityProcedural( szName ) == m_pInstance;
return V_CompareNameWithWildcards( szName, m_name.String() ) == 0;
}
bool CEntityIdentity::ClassMatches( const char* szClassName ) const
{
return V_CompareNameWithWildcards( szClassName, m_designerName.String() ) == 0;
}

335
entity2/entitykeyvalues.cpp Normal file
View File

@ -0,0 +1,335 @@
#include "entity2/entitykeyvalues.h"
#include "tier0/logging.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
CEntityKeyValues::CEntityKeyValues( CKeyValues3Context* allocator, EntityKVAllocatorType_t allocator_type ) :
m_pComplexKeys( NULL ),
m_nRefCount( 0 ),
m_nQueuedForSpawnCount( 0 ),
m_bAllowLogging( false ),
m_eAllocatorType( allocator_type )
{
if ( allocator )
{
m_pAllocator = allocator;
if ( GameEntitySystem() && m_pAllocator == GameEntitySystem()->GetEntityKeyValuesAllocator() )
GameEntitySystem()->AddEntityKeyValuesAllocatorRef();
m_pValues = m_pAllocator->AllocKV();
m_pAttributes = m_pAllocator->AllocKV();
}
else
{
if ( !GameEntitySystem() && ( m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_1 || m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_2 ) )
m_eAllocatorType = EKV_ALLOCATOR_NORMAL;
m_pAllocator = NULL;
}
}
CEntityKeyValues::~CEntityKeyValues()
{
ReleaseAllComplexKeys();
if ( m_pAllocator )
{
if ( m_eAllocatorType != EKV_ALLOCATOR_NORMAL )
{
m_pAllocator->FreeKV( m_pValues );
m_pAllocator->FreeKV( m_pAttributes );
if ( GameEntitySystem() && m_pAllocator == GameEntitySystem()->GetEntityKeyValuesAllocator() )
GameEntitySystem()->ReleaseEntityKeyValuesAllocatorRef();
}
else
{
delete m_pAllocator;
}
}
}
void CEntityKeyValues::ValidateAllocator()
{
if ( !m_pAllocator )
{
if ( m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_1 || m_eAllocatorType == EKV_ALLOCATOR_ENTSYSTEM_2 )
{
Assert( GameEntitySystem() );
m_pAllocator = GameEntitySystem()->GetEntityKeyValuesAllocator();
GameEntitySystem()->AddEntityKeyValuesAllocatorRef();
}
else
{
Assert( m_eAllocatorType != EKV_ALLOCATOR_EXTERNAL );
m_pAllocator = new CKeyValues3Context( true );
}
m_pValues = m_pAllocator->AllocKV();
m_pAttributes = m_pAllocator->AllocKV();
}
}
void CEntityKeyValues::AddRef()
{
++m_nRefCount;
if ( m_bAllowLogging )
Log_Msg( LOG_GENERAL, "kv 0x%p AddRef refcount == %d\n", this, m_nRefCount );
}
void CEntityKeyValues::Release()
{
--m_nRefCount;
if ( m_bAllowLogging )
Log_Msg( LOG_GENERAL, "kv 0x%p Release refcount == %d\n", this, m_nRefCount );
if ( m_nRefCount <= 0 )
delete this;
}
const KeyValues3* CEntityKeyValues::GetKeyValue( const EntityKeyId_t &id, bool* pIsAttribute ) const
{
if ( !m_pAllocator )
return NULL;
const KeyValues3* kv = m_pValues->FindMember( id );
if ( kv )
{
if ( pIsAttribute )
*pIsAttribute = false;
}
else
{
kv = m_pAttributes->FindMember( id );
if ( kv )
{
if ( pIsAttribute )
*pIsAttribute = true;
}
}
return kv;
}
KeyValues3* CEntityKeyValues::SetKeyValue( const EntityKeyId_t &id, const char* pAttributeName )
{
if ( m_nQueuedForSpawnCount > 0 )
return NULL;
ValidateAllocator();
bool bIsAttribute;
KeyValues3* kv = const_cast<KeyValues3*>( GetKeyValue( id, &bIsAttribute ) );
if ( kv )
{
if ( !bIsAttribute && pAttributeName )
{
kv = NULL;
Warning( "Attempted to set non-attribute value %s as if it was an attribute!\n", pAttributeName );
}
else if ( bIsAttribute && !pAttributeName )
{
pAttributeName = "<none>";
for ( int i = 0; i < m_pAttributes->GetMemberCount(); ++i )
{
if ( m_pAttributes->GetMember( i ) != kv )
continue;
pAttributeName = m_pAttributes->GetMemberName( i );
break;
}
kv = NULL;
Warning( "Attempted to set attribute %s as if it was a non-attribute key!\n", pAttributeName );
}
}
else
{
if ( pAttributeName )
kv = m_pAttributes->FindOrCreateMember( id );
else
kv = m_pValues->FindOrCreateMember( id );
}
return kv;
}
void CEntityKeyValues::AddConnectionDesc(
const char* pszOutputName,
EntityIOTargetType_t eTargetType,
const char* pszTargetName,
const char* pszInputName,
const char* pszOverrideParam,
float flDelay,
int32 nTimesToFire )
{
if ( m_nQueuedForSpawnCount > 0 )
return;
ValidateAllocator();
EntityIOConnectionDescFat_t* desc = m_connectionDescs.AddToTailGetPtr();
desc->m_pszOutputName = m_pAllocator->AllocString( pszOutputName ? pszOutputName : "" );
desc->m_eTargetType = eTargetType;
desc->m_pszTargetName = m_pAllocator->AllocString( pszTargetName ? pszTargetName : "" );
desc->m_pszInputName = m_pAllocator->AllocString( pszInputName ? pszInputName : "" );
desc->m_pszOverrideParam = m_pAllocator->AllocString( pszOverrideParam ? pszOverrideParam : "" );
desc->m_flDelay = flDelay;
desc->m_nTimesToFire = nTimesToFire;
}
void CEntityKeyValues::CopyFrom( const CEntityKeyValues* pSrc, bool bRemoveAllKeys, bool bSkipEHandles )
{
if ( bRemoveAllKeys )
RemoveAllKeys();
for ( EntityComplexKeyListElem_t* pListElem = pSrc->m_pComplexKeys; pListElem != NULL; pListElem = pListElem->m_pNext )
{
m_pComplexKeys = new EntityComplexKeyListElem_t( pListElem->m_pKey, m_pComplexKeys );
pListElem->m_pKey->AddRef();
}
FOR_EACH_ENTITYKEY( pSrc, iter )
{
const char* pAttributeName = NULL;
if ( pSrc->IsAttribute( iter ) )
{
pAttributeName = pSrc->GetAttributeName( iter );
}
else
{
if ( bSkipEHandles && pSrc->GetKeyValue( iter )->GetSubType() == KV3_SUBTYPE_EHANDLE )
continue;
}
KeyValues3* kv = SetKeyValue( pSrc->GetEntityKeyId( iter ), pAttributeName );
if ( kv )
*kv = *pSrc->GetKeyValue( iter );
}
m_connectionDescs.RemoveAll();
m_connectionDescs.EnsureCapacity( pSrc->m_connectionDescs.Count() );
FOR_EACH_LEANVEC( pSrc->m_connectionDescs, iter )
{
AddConnectionDesc(
pSrc->m_connectionDescs[ iter ].m_pszOutputName,
pSrc->m_connectionDescs[ iter ].m_eTargetType,
pSrc->m_connectionDescs[ iter ].m_pszTargetName,
pSrc->m_connectionDescs[ iter ].m_pszInputName,
pSrc->m_connectionDescs[ iter ].m_pszOverrideParam,
pSrc->m_connectionDescs[ iter ].m_flDelay,
pSrc->m_connectionDescs[ iter ].m_nTimesToFire );
}
}
void CEntityKeyValues::RemoveKeyValue( const EntityKeyId_t &id )
{
if ( m_nQueuedForSpawnCount > 0 || !m_pAllocator )
return;
if ( !m_pValues->RemoveMember( id ) )
m_pAttributes->RemoveMember( id );
}
void CEntityKeyValues::RemoveAllKeys()
{
if ( m_nQueuedForSpawnCount > 0 )
return;
ReleaseAllComplexKeys();
if ( m_pAllocator )
{
if ( m_eAllocatorType != EKV_ALLOCATOR_NORMAL )
{
m_pValues->SetToEmptyTable();
m_pAttributes->SetToEmptyTable();
}
else
{
m_pAllocator->Clear();
m_pValues = m_pAllocator->AllocKV();
m_pAttributes = m_pAllocator->AllocKV();
}
}
}
bool CEntityKeyValues::IsEmpty() const
{
if ( !m_pAllocator )
return true;
if ( !m_pValues->GetMemberCount() && !m_pAttributes->GetMemberCount() )
return true;
return false;
}
bool CEntityKeyValues::ValuesHasBadNames() const
{
if ( !m_pAllocator )
return false;
return m_pValues->TableHasBadNames();
}
bool CEntityKeyValues::AttributesHasBadNames() const
{
if ( !m_pAllocator )
return false;
return m_pAttributes->TableHasBadNames();
}
void CEntityKeyValues::ReleaseAllComplexKeys()
{
EntityComplexKeyListElem_t* pListElem = m_pComplexKeys;
while ( pListElem != NULL )
{
EntityComplexKeyListElem_t* pListElemForRelease = pListElem;
pListElem = pListElem->m_pNext;
pListElemForRelease->m_pKey->Release();
delete pListElemForRelease;
}
m_pComplexKeys = NULL;
}
CEntityHandle CEntityKeyValues::GetEHandle( const EntityKeyId_t &id, WorldGroupId_t worldGroupId, CEntityHandle defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
if ( !kv )
return defaultValue;
switch ( kv->GetType() )
{
case KV3_TYPE_UINT:
return kv->GetEHandle( defaultValue );
case KV3_TYPE_STRING:
Assert( GameEntitySystem() );
return GameEntitySystem()->FindFirstEntityHandleByName( kv->GetString(), worldGroupId );
default:
return defaultValue;
}
}
void CEntityKeyValues::SetString( KeyValues3* kv, const char* string )
{
ValidateAllocator();
kv->SetStringExternal( m_pAllocator->AllocString( string ) );
}

View File

@ -1,7 +1,8 @@
#include "const.h"
#include "entity2/entitysystem.h"
#include "entity2/entityclass.h"
CBaseEntity* CEntitySystem::GetBaseEntity(CEntityIndex entnum)
CEntityIdentity* CEntitySystem::GetEntityIdentity(CEntityIndex entnum)
{
if (entnum.Get() <= -1 || entnum.Get() >= (MAX_TOTAL_ENTITIES - 1))
return nullptr;
@ -17,10 +18,10 @@ CBaseEntity* CEntitySystem::GetBaseEntity(CEntityIndex entnum)
if (pIdentity->GetEntityIndex() != entnum)
return nullptr;
return static_cast<CBaseEntity*>(pIdentity->m_pInstance);
return pIdentity;
}
CBaseEntity* CEntitySystem::GetBaseEntity(const CEntityHandle& hEnt)
CEntityIdentity* CEntitySystem::GetEntityIdentity(const CEntityHandle& hEnt)
{
if (!hEnt.IsValid())
return nullptr;
@ -36,7 +37,68 @@ CBaseEntity* CEntitySystem::GetBaseEntity(const CEntityHandle& hEnt)
if (pIdentity->GetRefEHandle() != hEnt)
return nullptr;
return static_cast<CBaseEntity*>(pIdentity->m_pInstance);
return pIdentity;
}
CEntityClass* CEntitySystem::FindClassByName(const char* szClassName)
{
if (!szClassName || !*szClassName)
return nullptr;
unsigned short idx = m_entClassesByCPPClassname.Find(szClassName);
if (idx == m_entClassesByCPPClassname.InvalidIndex())
{
// vscript stuff is skipped here
return nullptr;
}
return m_entClassesByCPPClassname[ idx ];
}
CEntityClass* CEntitySystem::FindClassByDesignName(const char* szClassName)
{
if (!szClassName || !*szClassName)
return nullptr;
unsigned short idx = m_entClassesByClassname.Find(szClassName);
if (idx == m_entClassesByClassname.InvalidIndex())
{
// vscript stuff is skipped here
return nullptr;
}
return m_entClassesByClassname[ idx ];
}
CEntityHandle CEntitySystem::FindFirstEntityHandleByName(const char* szName, WorldGroupId_t hWorldGroupId)
{
if (!szName || !*szName)
return CEntityHandle();
EntityInstanceByNameIter_t iter(szName);
iter.SetWorldGroupId(hWorldGroupId);
CEntityInstance* pEntity = iter.First();
if (!pEntity)
return CEntityHandle();
return pEntity->GetRefEHandle();
}
CUtlSymbolLarge CEntitySystem::AllocPooledString(const char* pString)
{
if (!pString || !*pString)
return CUtlSymbolLarge();
return m_Symbols.AddString(pString);
}
CUtlSymbolLarge CEntitySystem::FindPooledString(const char* pString)
{
if (!pString || !*pString)
return CUtlSymbolLarge();
return m_Symbols.Find(pString);
}
void CGameEntitySystem::AddListenerEntity(IEntityListener* pListener)
@ -51,3 +113,265 @@ void CGameEntitySystem::RemoveListenerEntity(IEntityListener* pListener)
{
m_entityListeners.FindAndRemove(pListener);
}
EntityInstanceIter_t::EntityInstanceIter_t(IEntityFindFilter* pFilter, EntityIterType_t eIterType)
{
m_pCurrentEnt = nullptr;
m_pFilter = pFilter;
m_eIterType = eIterType;
m_hWorldGroupId = WorldGroupId_t();
}
CEntityInstance* EntityInstanceIter_t::First()
{
m_pCurrentEnt = nullptr;
return Next();
}
CEntityInstance* EntityInstanceIter_t::Next()
{
if (m_pCurrentEnt)
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
else
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
{
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
continue;
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
continue;
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
continue;
break;
}
if (m_pCurrentEnt)
return m_pCurrentEnt->m_pInstance;
return nullptr;
}
EntityInstanceByNameIter_t::EntityInstanceByNameIter_t(const char* szName, CEntityInstance* pSearchingEntity, CEntityInstance* pActivator, CEntityInstance* pCaller, IEntityFindFilter* pFilter, EntityIterType_t eIterType)
{
m_pCurrentEnt = nullptr;
m_pFilter = pFilter;
m_eIterType = eIterType;
m_hWorldGroupId = WorldGroupId_t();
if (szName[0] == '!')
{
m_pszEntityName = nullptr;
m_pEntityHandles = nullptr;
m_nCurEntHandle = 0;
m_nNumEntHandles = 0;
m_pProceduralEnt = GameEntitySystem()->FindEntityProcedural(szName, pSearchingEntity, pActivator, pCaller);
}
else if (strchr(szName, '*') || eIterType == ENTITY_ITER_OVER_DORMANT)
{
m_pszEntityName = szName;
m_pEntityHandles = nullptr;
m_nCurEntHandle = 0;
m_nNumEntHandles = 0;
m_pProceduralEnt = nullptr;
}
else
{
m_pszEntityName = nullptr;
m_pProceduralEnt = nullptr;
CUtlSymbolLarge nameSymbol = GameEntitySystem()->FindPooledString(szName);
unsigned short idx = GameEntitySystem()->m_entityNames.Find(nameSymbol);
if (idx == GameEntitySystem()->m_entityNames.InvalidIndex())
{
m_pEntityHandles = nullptr;
m_nCurEntHandle = 0;
m_nNumEntHandles = 0;
}
else
{
m_pEntityHandles = GameEntitySystem()->m_entityNames[ idx ];
m_nCurEntHandle = 0;
if (m_pEntityHandles)
{
m_nNumEntHandles = m_pEntityHandles->Count();
if (!m_nNumEntHandles)
m_pEntityHandles = nullptr;
}
else
{
m_nNumEntHandles = 0;
}
}
}
}
CEntityInstance* EntityInstanceByNameIter_t::First()
{
m_pCurrentEnt = nullptr;
return Next();
}
CEntityInstance* EntityInstanceByNameIter_t::Next()
{
if (m_pProceduralEnt)
{
if (m_pCurrentEnt)
{
m_pCurrentEnt = nullptr;
}
else
{
if (!m_pFilter || m_pFilter->ShouldFindEntity(m_pProceduralEnt))
m_pCurrentEnt = m_pProceduralEnt->m_pEntity;
}
}
else if (m_pEntityHandles)
{
if ( !m_pCurrentEnt )
m_nCurEntHandle = m_nNumEntHandles;
for (--m_nCurEntHandle; m_nCurEntHandle >= 0; --m_nCurEntHandle)
{
m_pCurrentEnt = GameEntitySystem()->GetEntityIdentity(m_pEntityHandles->Element(m_nCurEntHandle));
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
continue;
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
continue;
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
continue;
break;
}
if (m_nCurEntHandle < 0)
m_pCurrentEnt = nullptr;
}
else if (m_pszEntityName)
{
if (m_pCurrentEnt)
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
else
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
{
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
continue;
if (!m_pCurrentEnt->m_name.IsValid())
continue;
if (!m_pCurrentEnt->NameMatches(m_pszEntityName))
continue;
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
continue;
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
continue;
break;
}
}
if (m_pCurrentEnt)
return m_pCurrentEnt->m_pInstance;
return nullptr;
}
EntityInstanceByClassIter_t::EntityInstanceByClassIter_t(const char* szClassName, IEntityFindFilter* pFilter, EntityIterType_t eIterType)
{
m_pCurrentEnt = nullptr;
m_pFilter = pFilter;
m_eIterType = eIterType;
m_hWorldGroupId = WorldGroupId_t();
if (strchr(szClassName, '*') || eIterType == ENTITY_ITER_OVER_DORMANT)
{
m_pszClassName = szClassName;
m_pEntityClass = nullptr;
}
else
{
m_pEntityClass = GameEntitySystem()->FindClassByDesignName(szClassName);
if (!m_pEntityClass)
m_pszClassName = szClassName;
else
m_pszClassName = nullptr;
}
}
CEntityInstance* EntityInstanceByClassIter_t::First()
{
m_pCurrentEnt = nullptr;
return Next();
}
CEntityInstance* EntityInstanceByClassIter_t::Next()
{
if (m_pEntityClass)
{
if (m_pCurrentEnt)
m_pCurrentEnt = m_pCurrentEnt->m_pNextByClass;
else
m_pCurrentEnt = m_pEntityClass->m_pFirstEntity;
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNextByClass)
{
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
continue;
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
continue;
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
continue;
break;
}
}
else if (m_pszClassName)
{
if (m_pCurrentEnt)
m_pCurrentEnt = m_pCurrentEnt->m_pNext;
else
m_pCurrentEnt = (m_eIterType == ENTITY_ITER_OVER_ACTIVE) ? GameEntitySystem()->m_EntityList.m_pFirstActiveEntity : GameEntitySystem()->m_EntityList.m_dormantList.m_pHead;
for (; m_pCurrentEnt != nullptr; m_pCurrentEnt = m_pCurrentEnt->m_pNext)
{
if ((m_pCurrentEnt->m_flags & EF_MARKED_FOR_DELETE) != 0)
continue;
if (!m_pCurrentEnt->m_designerName.IsValid())
continue;
if (!m_pCurrentEnt->ClassMatches(m_pszClassName))
continue;
if (m_pFilter && !m_pFilter->ShouldFindEntity(m_pCurrentEnt->m_pInstance))
continue;
if (m_hWorldGroupId != WorldGroupId_t() && m_hWorldGroupId != m_pCurrentEnt->m_worldGroupId)
continue;
break;
}
}
if (m_pCurrentEnt)
return m_pCurrentEnt->m_pInstance;
return nullptr;
}

View File

@ -14,6 +14,9 @@
#pragma once
#endif
#include "entity2/entitysystem.h"
#if 0
#include "mempool.h"
struct EventQueuePrioritizedEvent_t
@ -78,6 +81,7 @@ private:
extern CEventQueue g_EventQueue;
#endif
#endif // EVENTQUEUE_H

View File

@ -20,8 +20,7 @@
inline CEntityInstance* CEntityHandle::Get() const
{
extern CEntitySystem *g_pEntitySystem;
return g_pEntitySystem->GetBaseEntity( *this );
return GameEntitySystem()->GetBaseEntity( *this );
}
// -------------------------------------------------------------------------------------------------- //

View File

@ -25,7 +25,7 @@ struct inputdata_t;
#define INVALID_TIME (FLT_MAX * -1.0) // Special value not rebased on save/load
typedef enum _fieldtypes
typedef enum _fieldtypes : uint8
{
FIELD_VOID = 0, // No type or value
FIELD_FLOAT, // Any floating point value

View File

@ -0,0 +1,39 @@
#ifndef ENTITYCLASS_H
#define ENTITYCLASS_H
#if _WIN32
#pragma once
#endif
#include "tier1/utlsymbollarge.h"
class CEntityClassInfo;
class CEntityIdentity;
class ServerClass;
struct EntInput_t;
struct EntOutput_t;
struct EntClassComponentOverride_t;
// Size: 0x110
class CEntityClass
{
public:
void* m_pScriptDesc; // 0x0
EntInput_t* m_pInputs; // 0x8
EntOutput_t* m_pOutputs; // 0x10
int m_nInputCount; // 0x18
int m_nOutputCount; // 0x1C
EntClassComponentOverride_t* m_pComponentOverrides; // 0x20
CEntityClassInfo* m_pClassInfo; // 0x28
CEntityClassInfo* m_pBaseClassInfo; // 0x30
CUtlSymbolLarge m_designerName; // 0x38
uint m_flags; // 0x40
private:
uint8 pad68[0xB4]; // 0x44
public:
CEntityClass* m_pNext; // 0xF8
CEntityIdentity* m_pFirstEntity; // 0x100
ServerClass* m_pServerClass; // 0x108
};
#endif // ENTITYCLASS_H

View File

@ -9,10 +9,12 @@
#define MAX_ENTITY_LISTS 64 // 0x3F
#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST * MAX_ENTITY_LISTS // 0x8000
#include "eiface.h"
#include "tier1/utlstring.h"
#include "tier1/utlsymbollarge.h"
#include "entitycomponent.h"
#include "entityhandle.h"
class CEntityClass;
class CEntityInstance;
struct ChangeAccessorFieldPathIndex_t
@ -84,10 +86,13 @@ public:
return m_EHandle.GetEntryIndex();
}
bool NameMatches( const char* szName ) const;
bool ClassMatches( const char* szClassName ) const;
public:
CEntityInstance* m_pInstance; // 0x0
private:
void* m_pClass; // 0x8 - CEntityClass
CEntityClass* m_pClass; // 0x8
public:
CEntityHandle m_EHandle; // 0x10
int32 m_nameStringableIndex; // 0x14

View File

@ -0,0 +1,480 @@
#ifndef ENTITYKEYVALUES_H
#define ENTITYKEYVALUES_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier1/keyvalues3.h"
#include "tier1/utlleanvector.h"
#include "entity2/entitysystem.h"
#include "tier0/memdbgon.h"
#define FOR_EACH_ENTITYKEY( ekv, iter ) \
for ( auto iter = ekv->First(); ekv->IsValidIterator( iter ); iter = ekv->Next( iter ) )
typedef CKV3MemberName EntityKeyId_t;
enum EntityKVAllocatorType_t : uint8
{
EKV_ALLOCATOR_NORMAL = 0,
EKV_ALLOCATOR_ENTSYSTEM_1 = 1,
EKV_ALLOCATOR_ENTSYSTEM_2 = 2,
EKV_ALLOCATOR_EXTERNAL = 3,
};
struct EntityIOConnectionDescFat_t
{
const char* m_pszOutputName;
EntityIOTargetType_t m_eTargetType;
const char* m_pszTargetName;
const char* m_pszInputName;
const char* m_pszOverrideParam;
float m_flDelay;
int32 m_nTimesToFire;
};
abstract_class IEntityKeyComplex
{
public:
IEntityKeyComplex() : m_nRefCount( 0 ) {}
void AddRef() { ++m_nRefCount; }
void Release() { if ( --m_nRefCount == 0 ) DeleteThis(); }
private:
virtual void DeleteThis() = 0;
private:
int32 m_nRefCount;
};
template < class T >
class CEntityKeyComplex : public IEntityKeyComplex
{
public:
CEntityKeyComplex( const T& obj ) : m_Object( obj ) {}
private:
virtual void DeleteThis() { delete this; }
public:
T m_Object;
};
class CEntityKeyValues
{
public:
CEntityKeyValues( CKeyValues3Context* allocator = NULL, EntityKVAllocatorType_t allocator_type = EKV_ALLOCATOR_NORMAL );
~CEntityKeyValues();
class Iterator_t
{
Iterator_t( const KeyValues3* _keys, int _index ) : keys( _keys ), index( _index ) {}
const KeyValues3* keys;
int index;
friend class CEntityKeyValues;
public:
bool operator==( const Iterator_t it ) const { return keys == it.keys && index == it.index; }
bool operator!=( const Iterator_t it ) const { return keys != it.keys || index != it.index; }
};
Iterator_t First() const;
Iterator_t Next( const Iterator_t &it ) const;
bool IsValidIterator( const Iterator_t &it ) const;
const KeyValues3* GetKeyValue( const Iterator_t &it ) const;
EntityKeyId_t GetEntityKeyId( const Iterator_t &it ) const;
const char* GetAttributeName( const Iterator_t &it ) const;
bool IsAttribute( const Iterator_t &it ) const;
// Indicates that kv's is in the spawn queue and we should not modify it
bool IsQueuedForSpawn() const { return m_nQueuedForSpawnCount > 0; }
bool IsLoggingEnabled() const { return m_bAllowLogging; }
void EnableLogging( bool bEnable ) { m_bAllowLogging = bEnable; }
void AddRef();
void Release();
void AddConnectionDesc(
const char* pszOutputName,
EntityIOTargetType_t eTargetType,
const char* pszTargetName,
const char* pszInputName,
const char* pszOverrideParam,
float flDelay,
int32 nTimesToFire );
void CopyFrom( const CEntityKeyValues* pSrc, bool bRemoveAllKeys = false, bool bSkipEHandles = false );
void RemoveKeyValue( const EntityKeyId_t &id );
void RemoveAllKeys();
bool IsEmpty() const;
bool ValuesHasBadNames() const;
bool AttributesHasBadNames() const;
bool HasValue( const EntityKeyId_t &id ) const { bool bIsAttribute; return ( GetKeyValue( id, &bIsAttribute ) && !bIsAttribute ); }
bool HasAttribute( const EntityKeyId_t &id ) const { bool bIsAttribute; return ( GetKeyValue( id, &bIsAttribute ) && bIsAttribute ); }
const KeyValues3* GetKeyValue( const EntityKeyId_t &id, bool* pIsAttribute = NULL ) const;
//
// GetKeyValue helpers
//
bool GetBool( const EntityKeyId_t &id, bool defaultValue = false ) const;
int GetInt( const EntityKeyId_t &id, int defaultValue = 0 ) const;
uint GetUint( const EntityKeyId_t &id, uint defaultValue = 0 ) const;
int64 GetInt64( const EntityKeyId_t &id, int64 defaultValue = 0 ) const;
uint64 GetUint64( const EntityKeyId_t &id, uint64 defaultValue = 0 ) const;
float GetFloat( const EntityKeyId_t &id, float defaultValue = 0.0f ) const;
double GetDouble( const EntityKeyId_t &id, double defaultValue = 0.0 ) const;
const char* GetString( const EntityKeyId_t &id, const char *defaultValue = "" ) const;
void* GetPtr( const EntityKeyId_t &id, void *defaultValue = ( void* )0 ) const;
CUtlStringToken GetStringToken( const EntityKeyId_t &id, CUtlStringToken defaultValue = CUtlStringToken() ) const;
CEntityHandle GetEHandle( const EntityKeyId_t &id, WorldGroupId_t worldGroupId = WorldGroupId_t(), CEntityHandle defaultValue = CEntityHandle() ) const;
Color GetColor( const EntityKeyId_t &id, const Color &defaultValue = Color( 0, 0, 0, 255 ) ) const;
Vector GetVector( const EntityKeyId_t &id, const Vector &defaultValue = Vector( 0.0f, 0.0f, 0.0f ) ) const;
Vector2D GetVector2D( const EntityKeyId_t &id, const Vector2D &defaultValue = Vector2D( 0.0f, 0.0f ) ) const;
Vector4D GetVector4D( const EntityKeyId_t &id, const Vector4D &defaultValue = Vector4D( 0.0f, 0.0f, 0.0f, 0.0f ) ) const;
Quaternion GetQuaternion( const EntityKeyId_t &id, const Quaternion &defaultValue = Quaternion( 0.0f, 0.0f, 0.0f, 0.0f ) ) const;
QAngle GetQAngle( const EntityKeyId_t &id, const QAngle &defaultValue = QAngle( 0.0f, 0.0f, 0.0f ) ) const;
matrix3x4_t GetMatrix3x4( const EntityKeyId_t &id, const matrix3x4_t &defaultValue = matrix3x4_t( Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ) ) ) const;
void SetBool( const EntityKeyId_t &id, bool value, bool bAsAttribute = false );
void SetInt( const EntityKeyId_t &id, int value, bool bAsAttribute = false );
void SetUint( const EntityKeyId_t &id, uint value, bool bAsAttribute = false );
void SetInt64( const EntityKeyId_t &id, int64 value, bool bAsAttribute = false );
void SetUint64( const EntityKeyId_t &id, uint64 value, bool bAsAttribute = false );
void SetFloat( const EntityKeyId_t &id, float value, bool bAsAttribute = false );
void SetDouble( const EntityKeyId_t &id, double value, bool bAsAttribute = false );
void SetString( const EntityKeyId_t &id, const char* string, bool bAsAttribute = false );
void SetPtr( const EntityKeyId_t &id, void* ptr, bool bAsAttribute = false );
void SetStringToken( const EntityKeyId_t &id, CUtlStringToken token, bool bAsAttribute = false );
void SetEHandle( const EntityKeyId_t &id, CEntityHandle ehandle, bool bAsAttribute = false );
void SetColor( const EntityKeyId_t &id, const Color &color, bool bAsAttribute = false );
void SetVector( const EntityKeyId_t &id, const Vector &vec, bool bAsAttribute = false );
void SetVector2D( const EntityKeyId_t &id, const Vector2D &vec2d, bool bAsAttribute = false );
void SetVector4D( const EntityKeyId_t &id, const Vector4D &vec4d, bool bAsAttribute = false );
void SetQuaternion( const EntityKeyId_t &id, const Quaternion &quat, bool bAsAttribute = false );
void SetQAngle( const EntityKeyId_t &id, const QAngle &ang, bool bAsAttribute = false );
void SetMatrix3x4( const EntityKeyId_t &id, const matrix3x4_t &matrix, bool bAsAttribute = false );
CEntityKeyValues& operator=( const CEntityKeyValues& src ) { CopyFrom( &src ); return *this; }
private:
CEntityKeyValues( const CEntityKeyValues& other );
// Use public setters for all available types instead
KeyValues3* SetKeyValue( const EntityKeyId_t &id, const char* pAttributeName = NULL );
void SetString( KeyValues3* kv, const char* string );
void ReleaseAllComplexKeys();
void ValidateAllocator();
private:
struct EntityComplexKeyListElem_t
{
EntityComplexKeyListElem_t( IEntityKeyComplex* pKey, EntityComplexKeyListElem_t* pNext ) : m_pKey( pKey ), m_pNext( pNext ) {}
IEntityKeyComplex* m_pKey;
EntityComplexKeyListElem_t* m_pNext;
};
CKeyValues3Context* m_pAllocator;
EntityComplexKeyListElem_t* m_pComplexKeys;
KeyValues3* m_pValues;
KeyValues3* m_pAttributes;
int16 m_nRefCount;
int16 m_nQueuedForSpawnCount;
bool m_bAllowLogging;
EntityKVAllocatorType_t m_eAllocatorType;
CUtlLeanVector<EntityIOConnectionDescFat_t> m_connectionDescs;
};
inline CEntityKeyValues::Iterator_t CEntityKeyValues::First() const
{
const KeyValues3* keys = NULL;
if ( m_pAllocator )
{
if ( m_pValues->GetMemberCount() > 0 )
keys = m_pValues;
else
keys = m_pAttributes;
}
return CEntityKeyValues::Iterator_t( keys, 0 );
}
inline CEntityKeyValues::Iterator_t CEntityKeyValues::Next( const CEntityKeyValues::Iterator_t &it ) const
{
const KeyValues3* keys = it.keys;
int index = it.index + 1;
if ( index >= keys->GetMemberCount() )
{
if ( keys == m_pValues )
{
keys = m_pAttributes;
index = 0;
}
else
{
index = keys->GetMemberCount();
}
}
return CEntityKeyValues::Iterator_t( keys, index );
}
inline bool CEntityKeyValues::IsValidIterator( const CEntityKeyValues::Iterator_t &it ) const
{
return ( it.keys != NULL ) && ( it.index < it.keys->GetMemberCount() );
}
inline const KeyValues3* CEntityKeyValues::GetKeyValue( const CEntityKeyValues::Iterator_t &it ) const
{
if ( it.index >= it.keys->GetMemberCount() )
return NULL;
return it.keys->GetMember( it.index );
}
inline EntityKeyId_t CEntityKeyValues::GetEntityKeyId( const CEntityKeyValues::Iterator_t &it ) const
{
if ( it.index >= it.keys->GetMemberCount() )
return EntityKeyId_t();
return it.keys->GetMemberNameEx( it.index );
}
inline const char* CEntityKeyValues::GetAttributeName( const CEntityKeyValues::Iterator_t &it ) const
{
if ( it.keys == m_pValues )
return NULL;
if ( it.index >= it.keys->GetMemberCount() )
return "<none>";
return it.keys->GetMemberName( it.index );
}
inline bool CEntityKeyValues::IsAttribute( const CEntityKeyValues::Iterator_t &it ) const
{
return ( it.index < it.keys->GetMemberCount() ) && ( it.keys == m_pAttributes );
}
inline bool CEntityKeyValues::GetBool( const EntityKeyId_t &id, bool defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetBool( defaultValue ) : defaultValue;
}
inline int CEntityKeyValues::GetInt( const EntityKeyId_t &id, int defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetInt( defaultValue ) : defaultValue;
}
inline uint CEntityKeyValues::GetUint( const EntityKeyId_t &id, uint defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetUInt() : defaultValue;
}
inline int64 CEntityKeyValues::GetInt64( const EntityKeyId_t &id, int64 defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetInt64( defaultValue ) : defaultValue;
}
inline uint64 CEntityKeyValues::GetUint64( const EntityKeyId_t &id, uint64 defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetUInt64( defaultValue ) : defaultValue;
}
inline float CEntityKeyValues::GetFloat( const EntityKeyId_t &id, float defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetFloat( defaultValue ) : defaultValue;
}
inline double CEntityKeyValues::GetDouble( const EntityKeyId_t &id, double defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetDouble( defaultValue ) : defaultValue;
}
inline const char* CEntityKeyValues::GetString( const EntityKeyId_t &id, const char *defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetString( defaultValue ) : defaultValue;
}
inline void* CEntityKeyValues::GetPtr( const EntityKeyId_t &id, void *defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetPointer( defaultValue ) : defaultValue;
}
inline CUtlStringToken CEntityKeyValues::GetStringToken( const EntityKeyId_t &id, CUtlStringToken defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetStringToken( defaultValue ) : defaultValue;
}
inline Color CEntityKeyValues::GetColor( const EntityKeyId_t &id, const Color &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetColor( defaultValue ) : defaultValue;
}
inline Vector CEntityKeyValues::GetVector( const EntityKeyId_t &id, const Vector &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetVector( defaultValue ) : defaultValue;
}
inline Vector2D CEntityKeyValues::GetVector2D( const EntityKeyId_t &id, const Vector2D &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetVector2D( defaultValue ) : defaultValue;
}
inline Vector4D CEntityKeyValues::GetVector4D( const EntityKeyId_t &id, const Vector4D &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetVector4D( defaultValue ) : defaultValue;
}
inline Quaternion CEntityKeyValues::GetQuaternion( const EntityKeyId_t &id, const Quaternion &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetQuaternion( defaultValue ) : defaultValue;
}
inline QAngle CEntityKeyValues::GetQAngle( const EntityKeyId_t &id, const QAngle &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetQAngle( defaultValue ) : defaultValue;
}
inline matrix3x4_t CEntityKeyValues::GetMatrix3x4( const EntityKeyId_t &id, const matrix3x4_t &defaultValue ) const
{
const KeyValues3* kv = GetKeyValue( id );
return kv ? kv->GetMatrix3x4( defaultValue ) : defaultValue;
}
inline void CEntityKeyValues::SetBool( const EntityKeyId_t &id, bool value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetBool( value );
}
inline void CEntityKeyValues::SetInt( const EntityKeyId_t &id, int value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetInt( value );
}
inline void CEntityKeyValues::SetUint( const EntityKeyId_t &id, uint value, bool bAsAttribute )
{
KeyValues3* val = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( val ) val->SetUInt( value );
}
inline void CEntityKeyValues::SetInt64( const EntityKeyId_t &id, int64 value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetInt64( value );
}
inline void CEntityKeyValues::SetUint64( const EntityKeyId_t &id, uint64 value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetUInt64( value );
}
inline void CEntityKeyValues::SetFloat( const EntityKeyId_t &id, float value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetFloat( value );
}
inline void CEntityKeyValues::SetDouble( const EntityKeyId_t &id, double value, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetDouble( value );
}
inline void CEntityKeyValues::SetString( const EntityKeyId_t &id, const char* string, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) SetString( kv, string );
}
inline void CEntityKeyValues::SetPtr( const EntityKeyId_t &id, void* ptr, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetPointer( ptr );
}
inline void CEntityKeyValues::SetStringToken( const EntityKeyId_t &id, CUtlStringToken token, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetStringToken( token );
}
inline void CEntityKeyValues::SetEHandle( const EntityKeyId_t &id, CEntityHandle ehandle, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetEHandle( ehandle );
}
inline void CEntityKeyValues::SetColor( const EntityKeyId_t &id, const Color &color, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetColor( color );
}
inline void CEntityKeyValues::SetVector( const EntityKeyId_t &id, const Vector &vec, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetVector( vec );
}
inline void CEntityKeyValues::SetVector2D( const EntityKeyId_t &id, const Vector2D &vec2d, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetVector2D( vec2d );
}
inline void CEntityKeyValues::SetVector4D( const EntityKeyId_t &id, const Vector4D &vec4d, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetVector4D( vec4d );
}
inline void CEntityKeyValues::SetQuaternion( const EntityKeyId_t &id, const Quaternion &quat, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetQuaternion( quat );
}
inline void CEntityKeyValues::SetQAngle( const EntityKeyId_t &id, const QAngle &ang, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetQAngle( ang );
}
inline void CEntityKeyValues::SetMatrix3x4( const EntityKeyId_t &id, const matrix3x4_t &matrix, bool bAsAttribute )
{
KeyValues3* kv = SetKeyValue( id, bAsAttribute ? id.GetString() : NULL );
if ( kv ) kv->SetMatrix3x4( matrix );
}
#include "tier0/memdbgoff.h"
#endif // ENTITYKEYVALUES_H

View File

@ -2,27 +2,66 @@
#define ENTITYSYSTEM_H
#include "tier0/platform.h"
#include "tier0/threadtools.h"
#include "tier1/generichash.h"
#include "tier1/keyvalues3.h"
#include "tier1/utlmemory.h"
#include "tier1/utlsymbollarge.h"
#include "tier1/utlvector.h"
#include "tier1/utldict.h"
#include "tier1/utlmap.h"
#include "tier1/utlhashtable.h"
#include <tier1/utldelegate.h>
#include "tier1/utlscratchmemory.h"
#include "tier1/utlstring.h"
#include "networksystem/inetworkserializer.h"
#include "vscript/ivscript.h"
#include "eiface.h"
#include "baseentity.h"
#include "entityhandle.h"
#include "concreteentitylist.h"
#include "entitydatainstantiator.h"
class CUtlScratchMemoryPool;
class CEntityClass;
class CEntityComponentHelper;
class CEntityKeyValues;
class CGameEntitySystem;
class IEntityIONotify;
class INetworkFieldChangedEventQueue;
class INetworkFieldScratchData;
class IFieldChangeLimitSpew;
class IEntity2SaveRestore;
class IEntity2Networkables;
class IEntityResourceManifest;
class IEntityPrecacheConfiguration;
class IEntityResourceManifestBuilder;
class ISpawnGroupEntityFilter;
class IHandleEntity;
struct ComponentUnserializerFieldInfo_t;
extern CGameEntitySystem* GameEntitySystem();
typedef void (*EntityResourceManifestCreationCallback_t)(IEntityResourceManifest *, void *);
enum EntityIOTargetType_t
{
ENTITY_IO_TARGET_INVALID = -1,
ENTITY_IO_TARGET_CLASSNAME = 0,
ENTITY_IO_TARGET_CLASSNAME_DERIVES_FROM = 1,
ENTITY_IO_TARGET_ENTITYNAME = 2,
ENTITY_IO_TARGET_CONTAINS_COMPONENT = 3,
ENTITY_IO_TARGET_SPECIAL_ACTIVATOR = 4,
ENTITY_IO_TARGET_SPECIAL_CALLER = 5,
ENTITY_IO_TARGET_EHANDLE = 6,
ENTITY_IO_TARGET_ENTITYNAME_OR_CLASSNAME = 7,
};
enum EntityIterType_t
{
ENTITY_ITER_OVER_ACTIVE = 0x0,
ENTITY_ITER_OVER_DORMANT = 0x1,
};
enum SpawnGroupEntityFilterType_t
{
SPAWN_GROUP_ENTITY_FILTER_FALLBACK = 0x0,
@ -55,6 +94,33 @@ enum EntityDormancyType_t
ENTITY_SUSPENDED = 0x2,
};
// Event queue //
struct EventQueuePrioritizedEvent_t
{
float m_flFireTime;
EntityIOTargetType_t m_eTargetType;
CUtlSymbolLarge m_iTarget;
CUtlSymbolLarge m_iTargetInput;
CEntityHandle m_pActivator;
CEntityHandle m_pCaller;
int m_iOutputID;
CEntityHandle m_pEntTarget; // a pointer to the entity to target; overrides m_iTarget
variant_t m_VariantValue; // variable-type parameter
EventQueuePrioritizedEvent_t *m_pNext;
EventQueuePrioritizedEvent_t *m_pPrev;
};
class CEventQueue
{
public:
CThreadMutex m_Mutex;
EventQueuePrioritizedEvent_t m_Events;
int m_iListCount;
};
// Entity notifications //
struct EntityNotification_t
@ -169,24 +235,78 @@ public:
// Size: 0x1510 | 0x1540 (from constructor)
class CEntitySystem : public IEntityResourceManifestBuilder
{
public:
virtual ~CEntitySystem() = 0;
virtual void ClearEntityDatabase(ClearEntityDatabaseMode_t eMode) = 0;
virtual void FindEntityProcedural(const char* szName, CEntityInstance* pSearchingEntity, CEntityInstance* pActivator, CEntityInstance* pCaller) = 0;
virtual void OnEntityParentChanged(CEntityInstance* pEntity, CEntityInstance* pNewParent) = 0; // empty function
virtual void OnAddEntity(CEntityInstance* pEnt, CEntityHandle handle) = 0; // empty function
virtual void OnRemoveEntity(CEntityInstance* pEnt, CEntityHandle handle) = 0; // empty function
virtual int GetSpawnGroupWorldId(SpawnGroupHandle_t hSpawnGroup) = 0; // returns 0
virtual void Spawn(int nCount, const EntitySpawnInfo_t* pInfo) = 0;
virtual void Activate(int nCount, const EntityActivation_t* pActivates, ActivateType_t activateType) = 0;
virtual void PostDataUpdate(int nCount, const PostDataUpdateInfo_t *pInfo) = 0;
virtual void OnSetDormant(int nCount, const EntityDormancyChange_t* pInfo, bool bNotifyAddedToPVS) = 0;
virtual void UpdateOnRemove(int nCount, const EntityDeletion_t *pDeletion) = 0;
enum
{
MAX_ACCESSORS = 32,
};
struct CreationInfo_t
{
CEntityHandle m_hEnt;
CEntityInstance* m_pEnt;
const CEntityKeyValues* m_pKeyValues;
bool m_Unk1;
};
struct DestructionInfo_t
{
CEntityIdentity* m_pEnt;
};
struct DormancyChangeInfo_t
{
CEntityInstance* m_pEnt;
bool m_bDormant;
};
struct MurmurHash2HashFunctor
{
unsigned int operator()( uint32 n ) const { return MurmurHash2( &n, sizeof( uint32 ), 0x3501A674 ); }
};
public:
CBaseEntity* GetBaseEntity(CEntityIndex entnum);
virtual ~CEntitySystem() = 0;
virtual void ClearEntityDatabase(ClearEntityDatabaseMode_t eMode) = 0;
virtual CEntityInstance* FindEntityProcedural(const char* szName, CEntityInstance* pSearchingEntity = nullptr, CEntityInstance* pActivator = nullptr, CEntityInstance* pCaller = nullptr) = 0;
virtual void OnEntityParentChanged(CEntityInstance* pEntity, CEntityInstance* pNewParent) = 0; // empty function
virtual void OnAddEntity(CEntityInstance* pEnt, CEntityHandle handle) = 0; // empty function
virtual void OnRemoveEntity(CEntityInstance* pEnt, CEntityHandle handle) = 0; // empty function
virtual int GetSpawnGroupWorldId(SpawnGroupHandle_t hSpawnGroup) = 0; // returns 0
virtual void Spawn(int nCount, const EntitySpawnInfo_t* pInfo) = 0;
virtual void Activate(int nCount, const EntityActivation_t* pActivates, ActivateType_t activateType) = 0;
virtual void PostDataUpdate(int nCount, const PostDataUpdateInfo_t *pInfo) = 0;
virtual void OnSetDormant(int nCount, const EntityDormancyChange_t* pInfo, bool bNotifyAddedToPVS) = 0;
virtual void UpdateOnRemove(int nCount, const EntityDeletion_t *pDeletion) = 0;
CBaseEntity* GetBaseEntity(const CEntityHandle& hEnt);
public:
CEntityIdentity* GetEntityIdentity(CEntityIndex entnum);
CEntityIdentity* GetEntityIdentity(const CEntityHandle& hEnt);
inline CEntityInstance* GetEntityInstance(CEntityIndex entnum) { return GetEntityIdentity(entnum)->m_pInstance; }
inline CEntityInstance* GetEntityInstance(const CEntityHandle& hEnt) { return GetEntityIdentity(hEnt)->m_pInstance; }
inline CBaseEntity* GetBaseEntity(CEntityIndex entnum) { return static_cast<CBaseEntity*>(GetEntityIdentity(entnum)->m_pInstance); }
inline CBaseEntity* GetBaseEntity(const CEntityHandle& hEnt) { return static_cast<CBaseEntity*>(GetEntityIdentity(hEnt)->m_pInstance); }
inline void AddEntityKeyValuesAllocatorRef() { ++m_nEntityKeyValuesAllocatorRefCount; }
inline void ReleaseEntityKeyValuesAllocatorRef()
{
if (--m_nEntityKeyValuesAllocatorRefCount == 0)
m_EntityKeyValuesAllocator.Clear();
}
inline CKeyValues3Context* GetEntityKeyValuesAllocator() { return &m_EntityKeyValuesAllocator; }
// Search for an entity class by its C++ name, case-insensitive
CEntityClass* FindClassByName(const char* szClassName);
// Search for an entity class by its designer name, case-insensitive
CEntityClass* FindClassByDesignName(const char* szClassName);
CEntityHandle FindFirstEntityHandleByName(const char* szName, WorldGroupId_t hWorldGroupId = WorldGroupId_t());
CUtlSymbolLarge AllocPooledString(const char* pString);
CUtlSymbolLarge FindPooledString(const char* pString);
private:
IEntityResourceManifest* m_pCurrentManifest;
@ -195,11 +315,47 @@ public:
// CConcreteEntityList seems to be correct but m_CallQueue supposedly starts at offset 2664, which is... impossible?
// Based on CEntitySystem::CEntitySystem found via string "MaxNonNetworkableEntities"
private:
uint8 pad2696[0xa88];
#ifdef PLATFORM_POSIX
uint8 pad5392[0x30];
#endif
public:
CUtlString m_sEntSystemName; // 2696
CUtlMap<const char*, CEntityClass*> m_entClassesByCPPClassname; // 2704
CUtlMap<const char*, CEntityClass*> m_entClassesByClassname; // 2736
CUtlMap<const char*, CEntityComponentHelper*> m_entityComponentHelpers; // 2768
CUtlMap<CUtlSymbolLarge, CUtlVector<CEntityHandle>*> m_entityNames; // 2800
CEventQueue m_EventQueue; // 2832
CUtlVectorFixedGrowable<IEntityIONotify*, 2> m_entityIONotifiers; // 2968 | 2984
int m_Unk1; // 3008 | 3024
NetworkSerializationMode_t m_eNetworkSerializationMode; // 3012 | 3028
int m_Unk2; // 3016 | 3032
int m_Unk3; // 3020 | 3036
int m_Unk4; // 3024 | 3040
int m_Unk5; // 3028 | 3044
int m_nEntityKeyValuesAllocatorRefCount; // 3032 | 3048
float m_flChangeCallbackSpewThreshold; // 3036 | 3052
bool m_Unk6; // 3040 | 3056
bool m_Unk7; // 3041 | 3057
bool m_Unk8; // 3042 | 3058
bool m_Unk9; // 3043 | 3059
bool m_Unk10; // 3044 | 3060
bool m_Unk11; // 3045 | 3061
bool m_Unk12; // 3046 | 3062
CUtlVector<CreationInfo_t> m_queuedCreations; // 3048 | 3064
CUtlVector<PostDataUpdateInfo_t> m_queuedPostDataUpdates; // 3072 | 3088
CUtlVector<DestructionInfo_t> m_queuedDeletions; // 3096 | 3112
CUtlVector<DestructionInfo_t> m_queuedDeferredDeletions; // 3120 | 3136
CUtlVector<DestructionInfo_t> m_queuedDeallocations; // 3144 | 3160
CUtlVector<DormancyChangeInfo_t> m_queuedDormancyChanges; // 3168 | 3184
CUtlDelegate<void ( int, const EntitySpawnInfo_t* )> m_EntityPostSpawnCallback; // 3192 | 3208
INetworkFieldChangedEventQueue* m_pNetworkFieldChangedEventQueue; // 3208 | 3232
INetworkFieldScratchData* m_pNetworkFieldScratchData; // 3216 | 3240
IFieldChangeLimitSpew* m_pFieldChangeLimitSpew; // 3224 | 3248
CUtlHashtable<fieldtype_t, CUtlDelegate<bool ( IParsingErrorListener*, CEntityInstance*, void*, const ComponentUnserializerFieldInfo_t*, const KeyValues3* )>, MurmurHash2HashFunctor> m_DataDescKeyUnserializers; // 3232 | 3256
CUtlScratchMemoryPool m_ComponentUnserializerInfoAllocator; // 3264 | 3288
CKeyValues3Context m_EntityKeyValuesAllocator; // 3280 | 3304
CUtlSymbolTableLargeMT_CI m_Symbols; // 4864 | 4888
SpawnGroupHandle_t m_hActiveSpawnGroup; // 5048 | 5088
matrix3x4a_t m_vSpawnOriginOffset; // 5056 | 5104
IEntityDataInstantiator* m_Accessors[ MAX_ACCESSORS ]; // 5104 | 5152
CUtlHashtable<CUtlString, void*> m_EntityMaterialAttributes; // 5360 | 5408
};
// Size: 0x1580 | 0x15B0 (from constructor)
@ -213,7 +369,7 @@ class CGameEntitySystem : public CEntitySystem
//typedef SpawnGroupEntityFilterInfo_t CUtlMap<char const*, SpawnGroupEntityFilterInfo_t, int, bool (*)(char const* const&, char const* const&)>::ElemType_t;
public:
virtual ~CGameEntitySystem() = 0;
virtual ~CGameEntitySystem() = 0;
void AddListenerEntity(IEntityListener* pListener);
void RemoveListenerEntity(IEntityListener* pListener);
@ -225,9 +381,73 @@ public:
// int m_iNumEdicts; // This is no longer referenced in the server binary
CUtlDict<SpawnGroupEntityFilterInfo_t> m_spawnGroupEntityFilters; // 5408 | 5456
CUtlVector<IEntityListener*> m_entityListeners; // 5448 | 5496
IEntity2SaveRestore* m_pEntity2SaveRestore; // 5472 | 5520
IEntity2Networkables* m_pEntity2Networkables; // 5480 | 5528
bool m_Unk13; // 5488 | 5536
};
abstract_class IEntityFindFilter
{
public:
virtual bool ShouldFindEntity(CEntityInstance* pEnt) = 0;
};
class EntityInstanceIter_t
{
public:
EntityInstanceIter_t(IEntityFindFilter* pFilter = nullptr, EntityIterType_t eIterType = ENTITY_ITER_OVER_ACTIVE);
CEntityInstance* First();
CEntityInstance* Next();
inline void SetWorldGroupId(WorldGroupId_t hWorldGroupId) { m_hWorldGroupId = hWorldGroupId; }
private:
uint8 pad5480[0x20];
CEntityIdentity* m_pCurrentEnt;
IEntityFindFilter* m_pFilter;
EntityIterType_t m_eIterType;
WorldGroupId_t m_hWorldGroupId;
};
class EntityInstanceByNameIter_t
{
public:
EntityInstanceByNameIter_t(const char* szName, CEntityInstance* pSearchingEntity = nullptr, CEntityInstance* pActivator = nullptr, CEntityInstance* pCaller = nullptr, IEntityFindFilter* pFilter = nullptr, EntityIterType_t eIterType = ENTITY_ITER_OVER_ACTIVE);
CEntityInstance* First();
CEntityInstance* Next();
inline void SetWorldGroupId(WorldGroupId_t hWorldGroupId) { m_hWorldGroupId = hWorldGroupId; }
private:
CEntityIdentity* m_pCurrentEnt;
IEntityFindFilter* m_pFilter;
EntityIterType_t m_eIterType;
WorldGroupId_t m_hWorldGroupId;
const char* m_pszEntityName;
CUtlVector<CEntityHandle>* m_pEntityHandles;
int m_nCurEntHandle;
int m_nNumEntHandles;
CEntityInstance* m_pProceduralEnt;
};
class EntityInstanceByClassIter_t
{
public:
EntityInstanceByClassIter_t(const char* szClassName, IEntityFindFilter* pFilter = nullptr, EntityIterType_t eIterType = ENTITY_ITER_OVER_ACTIVE);
CEntityInstance* First();
CEntityInstance* Next();
inline void SetWorldGroupId(WorldGroupId_t hWorldGroupId) { m_hWorldGroupId = hWorldGroupId; }
private:
CEntityIdentity* m_pCurrentEnt;
IEntityFindFilter* m_pFilter;
EntityIterType_t m_eIterType;
WorldGroupId_t m_hWorldGroupId;
const char* m_pszClassName;
CEntityClass* m_pEntityClass;
};
#endif // ENTITYSYSTEM_H

View File

@ -160,7 +160,7 @@ public:
matrix3x4a_t() { if (((size_t)Base()) % 16 != 0) { Error( "matrix3x4a_t missaligned" ); } }
*/
matrix3x4a_t& operator=( const matrix3x4_t& src ) { memcpy( Base(), src.Base(), sizeof( float ) * 3 * 4 ); return *this; };
};
} ALIGN16_POST;
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h

View File

@ -303,6 +303,18 @@ public:
return StringFuncs<char>::EmptyString();
}
inline void Clear()
{
if (GetAllocatedNumber() != 0)
{
if (IsStackAllocated())
m_Memory.m_szString[0] = '\0';
else
m_Memory.m_pString[0] = '\0';
}
m_nTotalCount &= ~LENGTH_MASK;
}
private:
int m_nTotalCount;
int m_nAllocated;

View File

@ -26,12 +26,14 @@ class KeyValues3;
class CKeyValues3Array;
class CKeyValues3Table;
class CKeyValues3Cluster;
class CKeyValues3ArrayCluster;
class CKeyValues3TableCluster;
class CKeyValues3Context;
struct KV1ToKV3Translation_t;
struct KV3ToKV1Translation_t;
template < class T > class CKeyValues3ClusterT;
typedef CKeyValues3ClusterT< CKeyValues3Array > CKeyValues3ArrayCluster;
typedef CKeyValues3ClusterT< CKeyValues3Table > CKeyValues3TableCluster;
/*
KeyValues3 is a data storage format. See https://developer.valvesoftware.com/wiki/KeyValues3
Supports various specific data types targeted at the Source2.
@ -60,6 +62,41 @@ const KV3ID_t g_KV3Encoding_Text =
0xDAA323A6DA77799ull
};
const KV3ID_t g_KV3Encoding_Binary =
{
"binary",
0x40C1F7D81B860500ull,
0x14E76782A47582ADull
};
const KV3ID_t g_KV3Encoding_BinaryLZ4 =
{
"binary_lz4",
0x4F5C63A16847348Aull,
0x19B1D96F805397A1ull
};
const KV3ID_t g_KV3Encoding_BinaryZSTD =
{
"binary_zstd",
0x4305FEF06F620A00ull,
0x29DBB14623045FA3ull
};
const KV3ID_t g_KV3Encoding_BinaryBC =
{
"binary_bc",
0x4F6C95BC95791A46ull,
0xD2DFB7A1BC050BA7ull
};
const KV3ID_t g_KV3Encoding_BinaryAuto =
{
"binary_auto",
0x45836B856EB109E6ull,
0x8C06046E3A7012A3ull
};
const KV3ID_t g_KV3Format_Generic =
{
"generic",
@ -134,6 +171,8 @@ enum KV3Type_t : uint8
KV3_TYPE_BINARY_BLOB,
KV3_TYPE_ARRAY,
KV3_TYPE_TABLE,
KV3_TYPE_COUNT,
};
enum KV3TypeOpt_t : uint8
@ -226,6 +265,8 @@ enum KV3SubType_t : uint8
KV3_SUBTYPE_STRING_TOKEN,
KV3_SUBTYPE_EHANDLE,
KV3_SUBTYPE_COUNT,
};
enum KV3ArrayAllocType_t
@ -235,16 +276,58 @@ enum KV3ArrayAllocType_t
KV3_ARRAY_ALLOC_EXTERN_FREE = 2,
};
enum KV3ToStringFlags_t
{
KV3_TO_STRING_NONE = 0,
KV3_TO_STRING_DONT_CLEAR_BUFF = (1 << 0),
KV3_TO_STRING_DONT_APPEND_STRINGS = (1 << 1),
KV3_TO_STRING_APPEND_ONLY_NUMERICS = (1 << 2),
KV3_TO_STRING_RETURN_NON_NUMERICS = (1 << 3),
};
enum KV3MetaDataFlags_t
{
KV3_METADATA_MULTILINE_STRING = (1 << 0),
KV3_METADATA_SINGLE_QUOTED_STRING = (1 << 1),
};
namespace KV3Helpers
{
// https://www.chessprogramming.org/BitScan
inline int BitScanFwd( uint64 bb )
{
static const int index64[64] = {
0, 47, 1, 56, 48, 27, 2, 60,
57, 49, 41, 37, 28, 16, 3, 61,
54, 58, 35, 52, 50, 42, 21, 44,
38, 32, 29, 23, 17, 11, 4, 62,
46, 55, 26, 59, 40, 36, 15, 53,
34, 51, 20, 43, 31, 22, 10, 45,
25, 39, 14, 33, 19, 30, 9, 24,
13, 18, 8, 12, 7, 6, 5, 63
};
const uint64 debruijn64 = 0x03f79d71b4cb0a89ull;
Assert( bb != 0 );
return index64[ ( ( bb ^ ( bb - 1 ) ) * debruijn64 ) >> 58 ];
}
// https://www.chessprogramming.org/Population_Count
inline int PopCount( uint64 x )
{
x = x - ( ( x >> 1 ) & 0x5555555555555555ull );
x = ( x & 0x3333333333333333ull ) + ( ( x >> 2 ) & 0x3333333333333333ull );
x = ( x + ( x >> 4 ) ) & 0x0f0f0f0f0f0f0f0full;
x = ( x * 0x0101010101010101ull ) >> 56;
return ( int )x;
}
}
struct KV3MetaData_t
{
KV3MetaData_t() : m_nLine( 0 ), m_nColumn( 0 ), m_nFlags( 0 ) {}
~KV3MetaData_t() {}
void Clear()
{
@ -292,10 +375,7 @@ public:
if (!pszString || !pszString[0])
return;
CUtlString buf( pszString );
buf.ToLowerFast();
m_nHashCode = MurmurHash2(buf.Get(), strlen(pszString), 0x31415926);
m_nHashCode = MurmurHash2LowerCase(pszString, strlen(pszString), 0x31415926);
m_pszString = pszString;
#if 0
@ -307,14 +387,7 @@ public:
}
inline CKV3MemberName(): m_nHashCode(0), m_pszString("") {}
inline CKV3MemberName(unsigned int nHashCode, const char* pszString): m_nHashCode(nHashCode), m_pszString(pszString) {}
inline CKV3MemberName(const CKV3MemberName& other): m_nHashCode(other.m_nHashCode), m_pszString(other.m_pszString) {}
inline CKV3MemberName& operator=(const CKV3MemberName& src)
{
m_nHashCode = src.m_nHashCode;
m_pszString = src.m_pszString;
return *this;
}
inline CKV3MemberName(unsigned int nHashCode, const char* pszString = ""): m_nHashCode(nHashCode), m_pszString(pszString) {}
inline unsigned int GetHashCode() const { return m_nHashCode; }
inline const char* GetString() const { return m_pszString; }
@ -337,6 +410,11 @@ public:
KV3TypeEx_t GetTypeEx() const { return ( KV3TypeEx_t )m_TypeEx; }
KV3SubType_t GetSubType() const { return ( KV3SubType_t )m_SubType; }
const char* GetTypeAsString() const;
const char* GetSubTypeAsString() const;
const char* ToString( CBufferString& buff, uint flags = KV3_TO_STRING_NONE ) const;
void SetToNull() { PrepareForType( KV3_TYPEEX_NULL, KV3_SUBTYPE_NULL ); }
bool GetBool( bool defaultValue = false ) const { return GetValue<bool>( defaultValue ); }
@ -371,10 +449,10 @@ public:
void SetPointer( void* ptr ) { SetValue<uint64>( ( uint64 )ptr, KV3_TYPEEX_UINT, KV3_SUBTYPE_POINTER ); }
CUtlStringToken GetStringToken( CUtlStringToken defaultValue = CUtlStringToken() ) const { return ( GetSubType() == KV3_SUBTYPE_STRING_TOKEN ) ? CUtlStringToken( ( uint32 )m_UInt ) : defaultValue; }
void SetStringToken( const CUtlStringToken& token ) { SetValue<uint32>( token.m_nHashCode, KV3_TYPEEX_UINT, KV3_SUBTYPE_STRING_TOKEN ); }
void SetStringToken( CUtlStringToken token ) { SetValue<uint32>( token.m_nHashCode, KV3_TYPEEX_UINT, KV3_SUBTYPE_STRING_TOKEN ); }
CEntityHandle GetEHandle( CEntityHandle defaultValue = CEntityHandle() ) const { return ( GetSubType() == KV3_SUBTYPE_EHANDLE ) ? CEntityHandle( ( uint32 )m_UInt ) : defaultValue; }
void SetEHandle( const CEntityHandle& ehandle ) { SetValue<uint32>( ehandle.ToInt(), KV3_TYPEEX_UINT, KV3_SUBTYPE_EHANDLE ); }
void SetEHandle( CEntityHandle ehandle ) { SetValue<uint32>( ehandle.ToInt(), KV3_TYPEEX_UINT, KV3_SUBTYPE_EHANDLE ); }
const char* GetString( const char *defaultValue = "" ) const;
void SetString( const char* pString, KV3SubType_t subtype = KV3_SUBTYPE_STRING );
@ -385,20 +463,22 @@ public:
void SetToBinaryBlob( const byte* blob, int size );
void SetToBinaryBlobExternal( const byte* blob, int size, bool free_mem );
Color GetColor( Color defaultValue = Color( 0, 0, 0, 255 ) ) const;
Color GetColor( const Color &defaultValue = Color( 0, 0, 0, 255 ) ) const;
void SetColor( const Color &color );
Vector GetVector( Vector defaultValue = Vector( 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector>( 3, defaultValue ); }
Vector2D GetVector2D( Vector2D defaultValue = Vector2D( 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector2D>( 2, defaultValue ); }
Vector4D GetVector4D( Vector4D defaultValue = Vector4D( 0.0f, 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector4D>( 4, defaultValue ); }
Quaternion GetQuaternion( Quaternion defaultValue = Quaternion( 0.0f, 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Quaternion>( 4, defaultValue ); }
QAngle GetQAngle( QAngle defaultValue = QAngle( 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<QAngle>( 3, defaultValue ); }
Vector GetVector( const Vector &defaultValue = Vector( 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector>( 3, defaultValue ); }
Vector2D GetVector2D( const Vector2D &defaultValue = Vector2D( 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector2D>( 2, defaultValue ); }
Vector4D GetVector4D( const Vector4D &defaultValue = Vector4D( 0.0f, 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Vector4D>( 4, defaultValue ); }
Quaternion GetQuaternion( const Quaternion &defaultValue = Quaternion( 0.0f, 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<Quaternion>( 4, defaultValue ); }
QAngle GetQAngle( const QAngle &defaultValue = QAngle( 0.0f, 0.0f, 0.0f ) ) const { return GetVecBasedObj<QAngle>( 3, defaultValue ); }
matrix3x4_t GetMatrix3x4( const matrix3x4_t &defaultValue = matrix3x4_t( Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ) ) ) const { return GetVecBasedObj<matrix3x4_t>( 3*4, defaultValue ); }
void SetVector( const Vector &vec ) { SetVecBasedObj<Vector>( vec, 3, KV3_SUBTYPE_VECTOR ); }
void SetVector2D( const Vector2D &vec2d ) { SetVecBasedObj<Vector2D>( vec2d, 2, KV3_SUBTYPE_VECTOR2D ); }
void SetVector4D( const Vector4D &vec4d ) { SetVecBasedObj<Vector4D>( vec4d, 4, KV3_SUBTYPE_VECTOR4D ); }
void SetQuaternion( const Quaternion &quat ) { SetVecBasedObj<Quaternion>( quat, 4, KV3_SUBTYPE_QUATERNION ); }
void SetQAngle( const QAngle &ang ) { SetVecBasedObj<QAngle>( ang, 3, KV3_SUBTYPE_QANGLE ); }
void SetMatrix3x4( const matrix3x4_t &matrix ) { SetVecBasedObj<matrix3x4_t>( matrix, 3*4, KV3_SUBTYPE_MATRIX3X4 ); }
int GetArrayElementCount() const;
KeyValues3** GetArrayBase();
@ -412,12 +492,15 @@ public:
void RemoveArrayElement( int elem ) { RemoveArrayElements( elem, 1 ); }
int GetMemberCount() const;
KeyValues3* GetMember( KV3MemberId_t id ) const;
KeyValues3* GetMember( KV3MemberId_t id );
const KeyValues3* GetMember( KV3MemberId_t id ) const { return const_cast<KeyValues3*>(this)->GetMember( id ); }
const char* GetMemberName( KV3MemberId_t id ) const;
CKV3MemberName GetMemberNameEx( KV3MemberId_t id ) const;
unsigned int GetMemberHash( KV3MemberId_t id ) const;
KeyValues3* FindMember( const CKV3MemberName &name, KeyValues3* defaultValue = NULL ) const;
KeyValues3* FindMember( const CKV3MemberName &name, KeyValues3* defaultValue = NULL );
KeyValues3* FindOrCreateMember( const CKV3MemberName &name, bool *pCreated = NULL );
bool TableHasBadNames() const;
void SetTableHasBadNames( bool bHasBadNames );
void SetToEmptyTable();
bool RemoveMember( KV3MemberId_t id );
bool RemoveMember( const KeyValues3* kv );
@ -445,10 +528,10 @@ private:
template < typename T > T GetValue( T defaultValue ) const;
template < typename T > void SetValue( T value, KV3TypeEx_t type, KV3SubType_t subtype );
template < typename T > T GetVecBasedObj( int size, T defaultValue ) const;
template < typename T > T GetVecBasedObj( int size, const T &defaultValue ) const;
template < typename T > void SetVecBasedObj( const T &obj, int size, KV3SubType_t subtype );
template< typename T >
template < typename T >
void NormalizeArray( KV3TypeEx_t type, KV3SubType_t subtype, int size, const T* data, bool bFree );
void NormalizeArray();
@ -490,7 +573,7 @@ private:
CKeyValues3Table* m_pTable;
uint64 m_Value;
uint64 m_nData;
void* m_pData;
char m_Data[1];
};
@ -503,8 +586,7 @@ COMPILE_TIME_ASSERT(sizeof(KeyValues3) == 16);
class CKeyValues3Array
{
public:
CKeyValues3Array( int cluster_elem = -1 ) : m_nClusterElement( cluster_elem ) {}
~CKeyValues3Array() {}
CKeyValues3Array( int cluster_elem = -1 );
int GetClusterElement() const { return m_nClusterElement; }
CKeyValues3ArrayCluster* GetCluster() const;
@ -533,25 +615,23 @@ private:
class CKeyValues3Table
{
public:
CKeyValues3Table( int cluster_elem = -1 ) :
m_nClusterElement( cluster_elem ),
m_pFastSearch( NULL ),
m_bHasBadNames( false ) {}
~CKeyValues3Table() {}
CKeyValues3Table( int cluster_elem = -1 );
int GetClusterElement() const { return m_nClusterElement; }
CKeyValues3TableCluster* GetCluster() const;
CKeyValues3Context* GetContext() const;
int GetMemberCount() const { return m_Hashes.Count(); }
KeyValues3* GetMember( KV3MemberId_t id ) const { return m_Members[ id ]; }
KeyValues3* GetMember( KV3MemberId_t id ) { return m_Members[ id ]; }
const KeyValues3* GetMember( KV3MemberId_t id ) const { return m_Members[ id ]; }
const char* GetMemberName( KV3MemberId_t id ) const { return m_Names[ id ]; }
unsigned int GetMemberHash( KV3MemberId_t id ) const { return m_Hashes[ id ]; }
void EnableFastSearch();
KV3MemberId_t FindMember( const KeyValues3* kv ) const;
KV3MemberId_t FindMember( const CKV3MemberName &name );
KV3MemberId_t CreateMember( const CKV3MemberName &name );
bool HasBadNames() const { return m_bHasBadNames; }
void SetHasBadNames( bool bHasBadNames ) { m_bHasBadNames = bHasBadNames; }
void CopyFrom( const CKeyValues3Table* pSrc );
void RemoveMember( KV3MemberId_t id );
void RemoveAll( int nAllocSize = 0 );
@ -567,7 +647,6 @@ private:
struct kv3tablefastsearch_t {
kv3tablefastsearch_t() : m_ignore( false ), m_ignores_counter( 0 ) {}
~kv3tablefastsearch_t() {}
void Clear()
{
@ -594,19 +673,8 @@ private:
class CKeyValues3Cluster
{
public:
CKeyValues3Cluster( CKeyValues3Context* context ) :
m_pContext( context ),
m_nAllocatedElements( 0 ),
m_pMetaData( NULL ),
m_pNextFree( NULL )
{
memset( &m_KeyValues, 0, sizeof( m_KeyValues ) );
}
~CKeyValues3Cluster()
{
FreeMetaData();
}
CKeyValues3Cluster( CKeyValues3Context* context );
~CKeyValues3Cluster();
KeyValues3* Alloc( KV3TypeEx_t type = KV3_TYPEEX_NULL, KV3SubType_t subtype = KV3_SUBTYPE_UNSPECIFIED );
void Free( int element );
@ -619,8 +687,8 @@ public:
KV3MetaData_t* GetMetaData( int element ) const;
CKeyValues3Context* GetContext() const { return m_pContext; }
int NumAllocated() const;
bool IsFree() const { return (m_nAllocatedElements != 0x7fffffffffffffffull); }
int NumAllocated() const { return KV3Helpers::PopCount( m_nAllocatedElements ); }
bool IsFree() const { return ( m_nAllocatedElements != 0x7fffffffffffffffull ); }
CKeyValues3Cluster* GetNextFree() const { return m_pNextFree; }
void SetNextFree( CKeyValues3Cluster* free ) { m_pNextFree = free; }
@ -641,69 +709,30 @@ private:
friend CKeyValues3Cluster* KeyValues3::GetCluster() const;
};
class CKeyValues3ArrayCluster
template < class T >
class CKeyValues3ClusterT
{
public:
CKeyValues3ArrayCluster( CKeyValues3Context* context ) :
m_pContext( context ),
m_nAllocatedElements( 0 ),
m_pNextFree( NULL )
{
memset( &m_Arrays, 0, sizeof( m_Arrays ) );
}
CKeyValues3ClusterT( CKeyValues3Context* context );
~CKeyValues3ArrayCluster() {}
CKeyValues3Array* Alloc();
T* Alloc();
void Free( int element );
void Clear() { Purge(); };
void Clear() { Purge(); }
void Purge();
CKeyValues3Context* GetContext() const { return m_pContext; }
int NumAllocated() const;
bool IsFree() const { return (m_nAllocatedElements != 0x7fffffffffffffffull); }
CKeyValues3ArrayCluster* GetNextFree() const { return m_pNextFree; }
void SetNextFree( CKeyValues3ArrayCluster* free ) { m_pNextFree = free; }
int NumAllocated() const { return KV3Helpers::PopCount( m_nAllocatedElements ); }
bool IsFree() const { return ( m_nAllocatedElements != 0x7fffffffffffffffull ); }
CKeyValues3ClusterT* GetNextFree() const { return m_pNextFree; }
void SetNextFree( CKeyValues3ClusterT* free ) { m_pNextFree = free; }
private:
CKeyValues3Context* m_pContext;
uint64 m_nAllocatedElements;
CKeyValues3Array m_Arrays[KV3_CLUSTER_MAX_ELEMENTS];
CKeyValues3ArrayCluster* m_pNextFree;
CKeyValues3Context* m_pContext;
uint64 m_nAllocatedElements;
T m_Elements[KV3_CLUSTER_MAX_ELEMENTS];
CKeyValues3ClusterT* m_pNextFree;
friend CKeyValues3ArrayCluster* CKeyValues3Array::GetCluster() const;
};
class CKeyValues3TableCluster
{
public:
CKeyValues3TableCluster( CKeyValues3Context* context ) :
m_pContext( context ),
m_nAllocatedElements( 0 ),
m_pNextFree( NULL )
{
memset( &m_Tables, 0, sizeof( m_Tables ) );
}
~CKeyValues3TableCluster() {}
CKeyValues3Table* Alloc();
void Free( int element );
void Clear() { Purge(); };
void Purge();
CKeyValues3Context* GetContext() const { return m_pContext; }
int NumAllocated() const;
bool IsFree() const { return (m_nAllocatedElements != 0x7fffffffffffffffull); }
CKeyValues3TableCluster* GetNextFree() const { return m_pNextFree; }
void SetNextFree( CKeyValues3TableCluster* free ) { m_pNextFree = free; }
private:
CKeyValues3Context* m_pContext;
uint64 m_nAllocatedElements;
CKeyValues3Table m_Tables[KV3_CLUSTER_MAX_ELEMENTS];
CKeyValues3TableCluster* m_pNextFree;
friend CKeyValues3TableCluster* CKeyValues3Table::GetCluster() const;
};
@ -757,16 +786,17 @@ public:
// gets the pre-allocated kv if we indicated its existence when creating the context
KeyValues3* Root();
const KeyValues3* Root() const { return const_cast<CKeyValues3Context*>(this)->Root(); }
bool IsMetaDataEnabled() const { return m_bMetaDataEnabled; };
bool IsMetaDataEnabled() const { return m_bMetaDataEnabled; }
// returns true if the desired format was converted to another after loading via LoadKV3*
bool IsFormatConverted() const { return m_bFormatConverted; };
bool IsRootAvailabe() const { return m_bRootAvailabe; };
bool IsFormatConverted() const { return m_bFormatConverted; }
bool IsRootAvailabe() const { return m_bRootAvailabe; }
// filled in after loading via LoadKV3* in binary encoding
const CUtlBuffer& GetBinaryData() const { return m_BinaryData; }
CUtlBuffer& GetBinaryData() { return m_BinaryData; }
IParsingErrorListener* GetParsingErrorListener() const { return m_pParsingErrorListener; };
IParsingErrorListener* GetParsingErrorListener() const { return m_pParsingErrorListener; }
void SetParsingErrorListener( IParsingErrorListener* listener ) { m_pParsingErrorListener = listener; }
const char* AllocString( const char* pString );
@ -826,7 +856,7 @@ template <> inline void KeyValues3::SetDirect( float32 value ) { m_Double = ( fl
template <> inline void KeyValues3::SetDirect( float64 value ) { m_Double = value; }
template < typename T >
T KeyValues3::GetVecBasedObj( int size, T defaultValue ) const
T KeyValues3::GetVecBasedObj( int size, const T &defaultValue ) const
{
T obj;
if ( !ReadArrayFloat32( size, obj.Base() ) )
@ -867,11 +897,11 @@ void KeyValues3::SetValue( T value, KV3TypeEx_t type, KV3SubType_t subtype )
SetDirect<T>( value );
}
template< typename T >
template < typename T >
void KeyValues3::NormalizeArray( KV3TypeEx_t type, KV3SubType_t subtype, int size, const T* data, bool bFree )
{
m_TypeEx = KV3_TYPEEX_ARRAY;
m_Value = 0;
m_nData = 0;
Alloc();
m_pArray->SetCount( size, type, subtype );
@ -905,7 +935,7 @@ void KeyValues3::AllocArray( int size, const T* data, KV3ArrayAllocType_t alloc_
m_bFreeArrayMemory = false;
m_nNumArrayElements = size;
m_Value = 0;
m_nData = 0;
memcpy( m_Data, data, size * sizeof( T ) );
if ( alloc_type == KV3_ARRAY_ALLOC_EXTERN_FREE )
@ -920,19 +950,19 @@ void KeyValues3::AllocArray( int size, const T* data, KV3ArrayAllocType_t alloc_
if ( alloc_type == KV3_ARRAY_ALLOC_EXTERN )
{
m_pData = (void*)data;
m_bFreeArrayMemory = false;
m_pData = (void*)data;
}
else if ( alloc_type == KV3_ARRAY_ALLOC_EXTERN_FREE )
{
m_pData = (void*)data;
m_bFreeArrayMemory = true;
m_pData = (void*)data;
}
else
{
m_bFreeArrayMemory = true;
m_pData = malloc( size * sizeof( T ) );
memcpy( m_pData, data, size * sizeof( T ) );
m_bFreeArrayMemory = true;
}
}
else
@ -950,6 +980,50 @@ void KeyValues3::AllocArray( int size, const T* data, KV3ArrayAllocType_t alloc_
}
}
template < class T >
CKeyValues3ClusterT< T >::CKeyValues3ClusterT( CKeyValues3Context* context ) :
m_pContext( context ),
m_nAllocatedElements( 0 ),
m_pNextFree( NULL )
{
memset( &m_Elements, 0, sizeof( m_Elements ) );
}
template < class T >
T* CKeyValues3ClusterT< T >::Alloc()
{
Assert( IsFree() );
int element = KV3Helpers::BitScanFwd( ~m_nAllocatedElements );
m_nAllocatedElements |= ( 1ull << element );
T* pElement = &m_Elements[ element ];
Construct( pElement, element );
return pElement;
}
template < class T >
void CKeyValues3ClusterT< T >::Free( int element )
{
Assert( element >= 0 && element < KV3_CLUSTER_MAX_ELEMENTS );
T* pElement = &m_Elements[ element ];
Destruct( pElement );
memset( (void *)pElement, 0, sizeof( T ) );
m_nAllocatedElements &= ~( 1ull << element );
}
template < class T >
void CKeyValues3ClusterT< T >::Purge()
{
uint64 mask = 1;
for ( int i = 0; i < KV3_CLUSTER_MAX_ELEMENTS; ++i )
{
if ( ( m_nAllocatedElements & mask ) != 0 )
m_Elements[ i ].Purge( true );
mask <<= 1;
}
m_nAllocatedElements = 0;
}
template< class ELEMENT_TYPE, class CLUSTER_TYPE, class VECTOR_TYPE >
ELEMENT_TYPE* CKeyValues3Context::Alloc( CLUSTER_TYPE *&head, VECTOR_TYPE &vec )
{
@ -982,6 +1056,8 @@ void CKeyValues3Context::Free( ELEMENT_TYPE *element, CLUSTER_TYPE *base, CLUSTE
{
CLUSTER_TYPE* cluster = element->GetCluster();
Assert( cluster != NULL && cluster->GetContext() == m_pContext );
cluster->Free( element->GetClusterElement() );
int num_allocated = cluster->NumAllocated();

View File

@ -74,7 +74,7 @@ public:
};
storage_t flags_and_hash;
storage_t data[ ( sizeof(KVPair) + sizeof(storage_t) - 1 ) / sizeof(storage_t) ];
alignas( alignof(KVPair) ) storage_t data[ ( sizeof(KVPair) + sizeof(storage_t) - 1 ) / sizeof(storage_t) ];
bool IsValid() const { return flags_and_hash >= 0; }
void MarkInvalid() { int32 flag = FLAG_FREE; flags_and_hash = (storage_t)flag; }

View File

@ -45,7 +45,7 @@ public:
void Purge();
protected:
I m_Size;
I m_nSize;
I m_nAllocationCount;
T* m_pMemory;
};
@ -54,7 +54,7 @@ protected:
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, class I >
inline CUtlLeanVectorBase<T, I>::CUtlLeanVectorBase() : m_Size(0),
inline CUtlLeanVectorBase<T, I>::CUtlLeanVectorBase() : m_nSize(0),
m_nAllocationCount(0), m_pMemory(0)
{
}
@ -103,7 +103,7 @@ void CUtlLeanVectorBase<T, I>::EnsureCapacity( int num, bool force )
if ( num > nMaxAllocationCount )
{
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, num, nMaxAllocationCount );
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, ( uint64 )num, ( uint64 )nMaxAllocationCount );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
@ -134,11 +134,11 @@ template< class T, class I >
void CUtlLeanVectorBase<T, I>::RemoveAll()
{
T* pElement = Base();
const T* pEnd = &pElement[ m_Size ];
const T* pEnd = &pElement[ m_nSize ];
while ( pElement != pEnd )
Destruct( pElement++ );
m_Size = 0;
m_nSize = 0;
}
//-----------------------------------------------------------------------------
@ -180,7 +180,7 @@ public:
void Purge();
protected:
I m_Size;
I m_nSize;
I m_nAllocationCount;
union
@ -194,7 +194,7 @@ protected:
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, size_t N, class I >
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::CUtlLeanVectorFixedGrowableBase() : m_Size(0),
inline CUtlLeanVectorFixedGrowableBase<T, N, I>::CUtlLeanVectorFixedGrowableBase() : m_nSize(0),
m_nAllocationCount(N)
{
}
@ -213,7 +213,7 @@ inline T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base()
{
if ( m_nAllocationCount )
{
if ( m_nAllocationCount > N )
if ( ( size_t )m_nAllocationCount > N )
return m_pMemory;
else
return &m_Memory[ 0 ];
@ -227,7 +227,7 @@ inline const T* CUtlLeanVectorFixedGrowableBase<T, N, I>::Base() const
{
if ( m_nAllocationCount )
{
if ( m_nAllocationCount > N )
if ( ( size_t )m_nAllocationCount > N )
return m_pMemory;
else
return &m_Memory[ 0 ];
@ -249,11 +249,11 @@ void CUtlLeanVectorFixedGrowableBase<T, N, I>::EnsureCapacity( int num, bool for
if ( num <= m_nAllocationCount )
return;
if ( num > N )
if ( ( size_t )num > N )
{
if ( num > nMaxAllocationCount )
{
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, num, nMaxAllocationCount );
Msg( "%s allocation count overflow( %llu > %llu )\n", __FUNCTION__, ( uint64 )num, ( uint64 )nMaxAllocationCount );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
@ -278,14 +278,14 @@ void CUtlLeanVectorFixedGrowableBase<T, N, I>::EnsureCapacity( int num, bool for
nNewAllocationCount = num;
}
if ( m_nAllocationCount > N )
if ( ( size_t )m_nAllocationCount > N )
{
m_pMemory = (T*)realloc( m_pMemory, nNewAllocationCount * sizeof(T) );
}
else if ( nNewAllocationCount > N )
else if ( ( size_t )nNewAllocationCount > N )
{
T* pNew = (T*)malloc( nNewAllocationCount * sizeof(T) );
memcpy( pNew, Base(), m_Size * sizeof(T) );
memcpy( pNew, Base(), m_nSize * sizeof(T) );
m_pMemory = pNew;
}
@ -299,11 +299,11 @@ template< class T, size_t N, class I >
void CUtlLeanVectorFixedGrowableBase<T, N, I>::RemoveAll()
{
T* pElement = Base();
const T* pEnd = &pElement[ m_Size ];
const T* pEnd = &pElement[ m_nSize ];
while ( pElement != pEnd )
Destruct( pElement++ );
m_Size = 0;
m_nSize = 0;
}
//-----------------------------------------------------------------------------
@ -314,7 +314,7 @@ inline void CUtlLeanVectorFixedGrowableBase<T, N, I>::Purge()
{
RemoveAll();
if ( m_nAllocationCount > N )
if ( ( size_t )m_nAllocationCount > N )
free( (void*)m_pMemory );
m_nAllocationCount = N;
@ -331,16 +331,19 @@ public:
// Copy the array.
CUtlLeanVectorImpl<B, T, I>& operator=( const CUtlLeanVectorImpl<B, T, I> &other );
struct Iterator_t
class Iterator_t
{
Iterator_t( T* _elem, const T* _end ) : elem( _elem ), end( _end ) {}
T* elem;
const T* end;
public:
Iterator_t( const T* _elem, const T* _end ) : elem( _elem ), end( _end ) {}
const T* elem;
const T* end;
bool operator==( const Iterator_t it ) const { return elem == it.elem && end == it.end; }
bool operator!=( const Iterator_t it ) const { return elem != it.elem || end != it.end; }
};
Iterator_t First() const { T* base = const_cast<T*>( this->Base() ); return Iterator_t( base, &base[ this->m_Size ] ); }
Iterator_t First() const { const T* base = this->Base(); return Iterator_t( base, &base[ this->m_nSize ] ); }
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.elem + 1, it.end ); }
bool IsValidIterator( const Iterator_t &it ) const { return it.elem != it.end; }
T& operator[]( const Iterator_t &it ) { return *it.elem; }
T& operator[]( const Iterator_t &it ) { return *const_cast<T*>(it.elem); }
const T& operator[]( const Iterator_t &it ) const { return *it.elem; }
// element access
@ -402,10 +405,14 @@ inline CUtlLeanVectorImpl<B, T, I>& CUtlLeanVectorImpl<B, T, I>::operator=( cons
{
int nCount = other.Count();
SetSize( nCount );
for ( int i = 0; i < nCount; i++ )
{
(*this)[ i ] = other[ i ];
}
T* pDest = this->Base();
const T* pSrc = other.Base();
const T* pEnd = &pSrc[ nCount ];
while ( pSrc != pEnd )
*(pDest++) = *(pSrc++);
return *this;
}
@ -415,57 +422,57 @@ inline CUtlLeanVectorImpl<B, T, I>& CUtlLeanVectorImpl<B, T, I>::operator=( cons
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::operator[]( int i )
{
Assert( i < this->m_Size );
Assert( i < this->m_nSize );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::operator[]( int i ) const
{
Assert( i < this->m_Size );
Assert( i < this->m_nSize );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Element( int i )
{
Assert( i < this->m_Size );
Assert( i < this->m_nSize );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Element( int i ) const
{
Assert( i < this->m_Size );
Assert( i < this->m_nSize );
return this->Base()[ i ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Head()
{
Assert( this->m_Size > 0 );
Assert( this->m_nSize > 0 );
return this->Base()[ 0 ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Head() const
{
Assert( this->m_Size > 0 );
Assert( this->m_nSize > 0 );
return this->Base()[ 0 ];
}
template< class B, class T, class I >
inline T& CUtlLeanVectorImpl<B, T, I>::Tail()
{
Assert( this->m_Size > 0 );
return this->Base()[ this->m_Size - 1 ];
Assert( this->m_nSize > 0 );
return this->Base()[ this->m_nSize - 1 ];
}
template< class B, class T, class I >
inline const T& CUtlLeanVectorImpl<B, T, I>::Tail() const
{
Assert( this->m_Size > 0 );
return this->Base()[ this->m_Size - 1 ];
Assert( this->m_nSize > 0 );
return this->Base()[ this->m_nSize - 1 ];
}
//-----------------------------------------------------------------------------
@ -474,7 +481,7 @@ inline const T& CUtlLeanVectorImpl<B, T, I>::Tail() const
template< class B, class T, class I >
inline int CUtlLeanVectorImpl<B, T, I>::Count() const
{
return this->m_Size;
return this->m_nSize;
}
//-----------------------------------------------------------------------------
@ -483,7 +490,7 @@ inline int CUtlLeanVectorImpl<B, T, I>::Count() const
template< class B, class T, class I >
inline bool CUtlLeanVectorImpl<B, T, I>::IsValidIndex( int i ) const
{
return (i >= 0) && (i < this->m_Size);
return (i >= 0) && (i < this->m_nSize);
}
//-----------------------------------------------------------------------------
@ -501,10 +508,10 @@ inline int CUtlLeanVectorImpl<B, T, I>::InvalidIndex()
template< class B, class T, class I >
T* CUtlLeanVectorImpl<B, T, I>::AddToTailGetPtr()
{
this->EnsureCapacity( this->m_Size + 1 );
this->EnsureCapacity( this->m_nSize + 1 );
T* pBase = this->Base();
Construct( &pBase[ this->m_Size ] );
return &pBase[ this->m_Size++ ];
Construct( &pBase[ this->m_nSize ] );
return &pBase[ this->m_nSize++ ];
}
//-----------------------------------------------------------------------------
@ -513,10 +520,10 @@ T* CUtlLeanVectorImpl<B, T, I>::AddToTailGetPtr()
template< class B, class T, class I >
int CUtlLeanVectorImpl<B, T, I>::AddToTail( const T& src )
{
this->EnsureCapacity( this->m_Size + 1 );
this->EnsureCapacity( this->m_nSize + 1 );
T* pBase = this->Base();
CopyConstruct( &pBase[ this->m_Size ], src );
return this->m_Size++;
CopyConstruct( &pBase[ this->m_nSize ], src );
return this->m_nSize++;
}
//-----------------------------------------------------------------------------
@ -525,7 +532,7 @@ int CUtlLeanVectorImpl<B, T, I>::AddToTail( const T& src )
template< class B, class T, class I >
int CUtlLeanVectorImpl<B, T, I>::AddMultipleToTail( int nSize )
{
int nOldSize = this->m_Size;
int nOldSize = this->m_nSize;
if ( nSize > 0 )
{
@ -533,7 +540,7 @@ int CUtlLeanVectorImpl<B, T, I>::AddMultipleToTail( int nSize )
if ( ( nMaxSize - nOldSize ) < nSize )
{
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, nSize, nOldSize, nMaxSize );
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, ( uint64 )nSize, ( uint64 )nOldSize, ( uint64 )nMaxSize );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
@ -546,7 +553,7 @@ int CUtlLeanVectorImpl<B, T, I>::AddMultipleToTail( int nSize )
ConstructElements( &pBase[ nOldSize ], &pBase[ nNewSize ] );
this->m_Size = nNewSize;
this->m_nSize = nNewSize;
}
return nOldSize;
@ -558,7 +565,7 @@ int CUtlLeanVectorImpl<B, T, I>::AddMultipleToTail( int nSize )
template< class B, class T, class I >
T* CUtlLeanVectorImpl<B, T, I>::InsertBeforeGetPtr( int nBeforeIndex, int nSize )
{
int nOldSize = this->m_Size;
int nOldSize = this->m_nSize;
if ( nBeforeIndex < 0 || nBeforeIndex > nOldSize )
{
@ -576,7 +583,7 @@ T* CUtlLeanVectorImpl<B, T, I>::InsertBeforeGetPtr( int nBeforeIndex, int nSize
if ( ( nMaxSize - nOldSize ) < nSize )
{
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, nSize, nOldSize, nMaxSize );
Msg( "%s allocation count overflow( add %llu + current %llu > max %llu )\n", __FUNCTION__, ( uint64 )nSize, ( uint64 )nOldSize, ( uint64 )nMaxSize );
Plat_FatalErrorFunc( "%s allocation count overflow", __FUNCTION__ );
DebuggerBreak();
}
@ -590,7 +597,7 @@ T* CUtlLeanVectorImpl<B, T, I>::InsertBeforeGetPtr( int nBeforeIndex, int nSize
ShiftElements( &pBase[ nBeforeIndex + nSize ], &pBase[ nBeforeIndex ], &pBase[ nOldSize ] );
ConstructElements( &pBase[ nBeforeIndex ], &pBase[ nBeforeIndex + nSize ] );
this->m_Size = nNewSize;
this->m_nSize = nNewSize;
return &pBase[ nBeforeIndex ];
}
@ -602,12 +609,12 @@ void CUtlLeanVectorImpl<B, T, I>::SetCount( int count )
T* pBase = this->Base();
if ( this->m_Size < count )
ConstructElements( &pBase[ this->m_Size ], &pBase[ count ] );
else if ( this->m_Size > count )
DestructElements( &pBase[ count ], &pBase[ this->m_Size ] );
if ( this->m_nSize < count )
ConstructElements( &pBase[ this->m_nSize ], &pBase[ count ] );
else if ( this->m_nSize > count )
DestructElements( &pBase[ count ], &pBase[ this->m_nSize ] );
this->m_Size = count;
this->m_nSize = count;
}
template< class B, class T, class I >
@ -641,11 +648,11 @@ void CUtlLeanVectorImpl<B, T, I>::FastRemove( int elem )
T* pBase = this->Base();
Destruct( &pBase[ elem ] );
if ( this->m_Size > 0 )
if ( this->m_nSize > 0 )
{
if ( elem != this->m_Size - 1 )
memcpy( &pBase[ elem ], &pBase[ this->m_Size - 1 ], sizeof( T ) );
--this->m_Size;
if ( elem != this->m_nSize - 1 )
memcpy( &pBase[ elem ], &pBase[ this->m_nSize - 1 ], sizeof( T ) );
--this->m_nSize;
}
}
@ -654,8 +661,8 @@ void CUtlLeanVectorImpl<B, T, I>::Remove( int elem )
{
T* pBase = this->Base();
Destruct( &pBase[ elem ] );
ShiftElements( &pBase[ elem ], &pBase[ elem + 1 ], &pBase[ this->m_Size ] );
--this->m_Size;
ShiftElements( &pBase[ elem ], &pBase[ elem + 1 ], &pBase[ this->m_nSize ] );
--this->m_nSize;
}
template< class B, class T, class I >
@ -690,8 +697,8 @@ void CUtlLeanVectorImpl<B, T, I>::RemoveMultiple( int elem, int num )
T* pBase = this->Base();
DestructElements( &pBase[ elem ], &pBase[ elem + num ] );
ShiftElements( &pBase[ elem ], &pBase[ elem + num ], &pBase[ this->m_Size ] );
this->m_Size -= num;
ShiftElements( &pBase[ elem ], &pBase[ elem + num ], &pBase[ this->m_nSize ] );
this->m_nSize -= num;
}
//-----------------------------------------------------------------------------

View File

@ -1203,7 +1203,7 @@ inline void CUtlMemory_RawAllocator<T>::EnsureCapacity( int num )
if (m_nAllocationCount >= num)
return;
if ( num > ( SIZE_MAX / sizeof(T) ) )
if ( ( size_t )num > ( SIZE_MAX / sizeof(T) ) )
{
Plat_FatalErrorFunc( "%s: Invalid capacity %u\n", __FUNCTION__, num );
DebuggerBreak();

View File

@ -45,8 +45,8 @@ class CUtlStringToken
public:
inline CUtlStringToken(): m_nHashCode(0) {}
inline CUtlStringToken(unsigned int nHashCode): m_nHashCode(nHashCode) {}
inline CUtlStringToken(const CUtlStringToken& other): m_nHashCode(other.m_nHashCode) {}
inline CUtlStringToken& operator=(const CUtlStringToken& src) { m_nHashCode = src.m_nHashCode; return *this; }
inline bool operator==(CUtlStringToken const &other) const { return (other.m_nHashCode == m_nHashCode); }
inline bool operator!=(CUtlStringToken const &other) const { return (other.m_nHashCode != m_nHashCode); }
public:
unsigned int m_nHashCode;

View File

@ -47,18 +47,6 @@ public:
m_pString = pString;
}
CUtlSymbolLarge( CUtlSymbolLarge const& sym )
{
m_pString = sym.m_pString;
}
// operator=
CUtlSymbolLarge& operator=( CUtlSymbolLarge const& src )
{
m_pString = src.m_pString;
return *this;
}
// operator==
bool operator==( CUtlSymbolLarge const& src ) const
{
@ -85,7 +73,7 @@ public:
private:
// Disallowed
bool operator==( const char* pStr ) const; // disallow since we don't know if the table this is from was case sensitive or not... maybe we don't care
bool operator==( const char* pString ) const; // disallow since we don't know if the table this is from was case sensitive or not... maybe we don't care
const char* m_pString;
};
@ -154,7 +142,7 @@ public:
void Purge();
private:
CUtlSymbolLarge AddString( unsigned int hash, const char* pString, int nLength );
CUtlSymbolLarge AddString( unsigned int hash, const char* pString, int nLength, bool* created );
CUtlSymbolLarge Find( unsigned int hash, const char* pString, int nLength ) const;
const char* String( UtlSymLargeId_t id ) const;
@ -162,18 +150,20 @@ private:
struct UtlSymTableLargeAltKey
{
CUtlSymbolTableLargeBase* m_pTable;
const char* m_pString;
int m_nLength;
const CUtlSymbolTableLargeBase* m_pTable;
const char* m_pString;
int m_nLength;
};
struct UtlSymTableLargeHashFunctor
{
ptrdiff_t m_tableOffset;
ptrdiff_t m_ownerOffset;
UtlSymTableLargeHashFunctor()
{
m_tableOffset = 1024 - (uintp)(&((Hashtable_t*)1024)->GetHashRef());
const ptrdiff_t tableoffset = (uintp)(&((Hashtable_t*)1024)->GetHashRef()) - 1024;
const ptrdiff_t owneroffset = offsetof(CUtlSymbolTableLargeBase, m_HashTable) + tableoffset;
m_ownerOffset = -owneroffset;
}
unsigned int operator()( UtlSymTableLargeAltKey k ) const
@ -183,7 +173,7 @@ private:
unsigned int operator()( UtlSymLargeId_t k ) const
{
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintp)this + m_tableOffset);
const CUtlSymbolTableLargeBase* pTable = (const CUtlSymbolTableLargeBase*)((uintp)this + m_ownerOffset);
return pTable->HashValue( k );
}
@ -191,16 +181,18 @@ private:
struct UtlSymTableLargeEqualFunctor
{
ptrdiff_t m_tableOffset;
ptrdiff_t m_ownerOffset;
UtlSymTableLargeEqualFunctor()
{
m_tableOffset = 1024 - (uintp)(&((Hashtable_t*)1024)->GetEqualRef());
const ptrdiff_t tableoffset = (uintp)(&((Hashtable_t*)1024)->GetEqualRef()) - 1024;
const ptrdiff_t owneroffset = offsetof(CUtlSymbolTableLargeBase, m_HashTable) + tableoffset;
m_ownerOffset = -owneroffset;
}
bool operator()( UtlSymLargeId_t a, UtlSymLargeId_t b ) const
{
CUtlSymbolTableLargeBase* pTable = (CUtlSymbolTableLargeBase*)((uintp)this + m_tableOffset);
const CUtlSymbolTableLargeBase* pTable = (const CUtlSymbolTableLargeBase*)((uintp)this + m_ownerOffset);
if ( !CASEINSENSITIVE )
return strcmp( pTable->String( a ), pTable->String( b ) ) == 0;
@ -210,9 +202,10 @@ private:
bool operator()( UtlSymTableLargeAltKey a, UtlSymLargeId_t b ) const
{
const char* pString = a.m_pTable->String( b );
const char* pString = a.m_pTable->String( b );
int nLength = strlen( pString );
if ( a.m_nLength != strlen( pString ) )
if ( a.m_nLength != nLength )
return false;
if ( !CASEINSENSITIVE )
@ -243,7 +236,7 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUT
{
UtlSymTableLargeAltKey key;
key.m_pTable = ( CUtlSymbolTableLargeBase* )this;
key.m_pTable = this;
key.m_pString = pString;
key.m_nLength = nLength;
@ -256,7 +249,7 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUT
}
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( unsigned int hash, const char* pString, int nLength )
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( unsigned int hash, const char* pString, int nLength, bool* created )
{
if ( m_MemBlocks.Count() >= m_nElementLimit )
{
@ -267,8 +260,13 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUT
}
Warning( "ERROR: CUtlSymbolTableLarge element limit of %u exceeded\n", m_nElementLimit );
return CUtlSymbolLarge();
}
if ( created )
*created = true;
MemBlockHandle_t block = m_MemBlockAllocator.Alloc( nLength + sizeof( LargeSymbolTableHashDecoration_t ) + 1 );
CUtlSymbolTableLargeBaseTreeEntry_t *entry = (CUtlSymbolTableLargeBaseTreeEntry_t *)m_MemBlockAllocator.GetBlock( block );
@ -328,6 +326,9 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUT
template < bool CASEINSENSITIVE, size_t PAGE_SIZE, class MUTEX_TYPE >
inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::AddString( const char* pString, int nLength, bool* created )
{
if ( created )
*created = false;
CUtlSymbolLarge sym;
if ( pString && nLength > 0 && *pString )
@ -339,7 +340,7 @@ inline CUtlSymbolLarge CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUT
sym = Find( hash, pString, nLength );
if ( !sym.IsValid() )
sym = AddString( hash, pString, nLength );
sym = AddString( hash, pString, nLength, created );
m_Mutex.Unlock( __FILE__, __LINE__ );
}
@ -358,8 +359,8 @@ inline void CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::
{
m_Mutex.Lock( __FILE__, __LINE__ );
m_MemBlocks.RemoveAll();
m_HashTable.RemoveAll();
m_MemBlocks.RemoveAll();
m_MemBlockAllocator.RemoveAll();
m_Mutex.Unlock( __FILE__, __LINE__ );
@ -370,8 +371,8 @@ inline void CUtlSymbolTableLargeBase< CASEINSENSITIVE, PAGE_SIZE, MUTEX_TYPE >::
{
m_Mutex.Lock( __FILE__, __LINE__ );
m_MemBlocks.Purge();
m_HashTable.Purge();
m_MemBlocks.Purge();
m_MemBlockAllocator.Purge();
m_Mutex.Unlock( __FILE__, __LINE__ );

View File

@ -59,7 +59,7 @@ private:
static CUtlScratchMemoryPool *sm_pMemoryPool;
};
inline const char *VariantFieldTypeName(int16 eType)
inline const char *VariantFieldTypeName(fieldtype_t eType)
{
switch(eType)
{
@ -132,7 +132,7 @@ DECLARE_DEDUCE_VARIANT_FIELDTYPE(FIELD_EHANDLE, CEntityHandle);
DECLARE_DEDUCE_VARIANT_FIELDTYPE(FIELD_RESOURCE, ResourceHandle_t);
DECLARE_DEDUCE_VARIANT_FIELDTYPE(FIELD_UTLSTRINGTOKEN, CUtlStringToken);
#define VariantDeduceType( T ) VariantTypeDeducer<T>::FIELD_TYPE
#define VariantDeduceType( T ) (fieldtype_t)VariantTypeDeducer<T>::FIELD_TYPE
#undef DECLARE_DEDUCE_VARIANT_FIELDTYPE
template <typename T>
@ -796,7 +796,7 @@ public:
template <typename T>
bool AssignTo(T *pDest)
{
int16 destType = VariantDeduceType(T);
fieldtype_t destType = VariantDeduceType(T);
if(destType == FIELD_VOID)
{
return false;
@ -969,8 +969,7 @@ public:
ResourceHandle_t m_hResource;
};
// fieldtype_t
int16 m_type;
fieldtype_t m_type;
// CVFlags_t flags
uint16 m_flags;

View File

@ -3,47 +3,19 @@
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if defined( POSIX )
// Nasty hack to redefine gcc's offsetof which doesn't like GET_OUTER macro
#ifdef COMPILER_GCC
#undef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
// https://www.chessprogramming.org/BitScan
static int BitScanFwd( uint64 bb )
{
static const int index64[64] = {
0, 47, 1, 56, 48, 27, 2, 60,
57, 49, 41, 37, 28, 16, 3, 61,
54, 58, 35, 52, 50, 42, 21, 44,
38, 32, 29, 23, 17, 11, 4, 62,
46, 55, 26, 59, 40, 36, 15, 53,
34, 51, 20, 43, 31, 22, 10, 45,
25, 39, 14, 33, 19, 30, 9, 24,
13, 18, 8, 12, 7, 6, 5, 63
};
const uint64 debruijn64 = 0x03f79d71b4cb0a89ull;
Assert( bb != 0 );
return index64[ ( ( bb ^ ( bb - 1 ) ) * debruijn64 ) >> 58 ];
}
// https://www.chessprogramming.org/Population_Count
static int PopCount( uint64 x )
{
x = x - ( ( x >> 1 ) & 0x5555555555555555ull );
x = ( x & 0x3333333333333333ull ) + ( ( x >> 2 ) & 0x3333333333333333ull );
x = ( x + ( x >> 4 ) ) & 0x0f0f0f0f0f0f0f0full;
x = ( x * 0x0101010101010101ull ) >> 56;
return ( int )x;
}
KeyValues3::KeyValues3( KV3TypeEx_t type, KV3SubType_t subtype ) :
m_bExternalStorage( true ),
m_TypeEx( type ),
m_SubType( subtype ),
m_nFlags( 0 ),
m_nReserved( 0 ),
m_Value( 0 )
m_nData( 0 )
{
ResolveUnspecified();
Alloc();
@ -56,7 +28,7 @@ KeyValues3::KeyValues3( int cluster_elem, KV3TypeEx_t type, KV3SubType_t subtype
m_nFlags( 0 ),
m_nClusterElement( cluster_elem ),
m_nReserved( 0 ),
m_Value( 0 )
m_nData( 0 )
{
ResolveUnspecified();
Alloc();
@ -98,7 +70,7 @@ void KeyValues3::Alloc()
{
m_bFreeArrayMemory = false;
m_nNumArrayElements = 0;
m_Value = 0;
m_nData = 0;
break;
}
default:
@ -183,7 +155,7 @@ void KeyValues3::Free( bool bClearingContext )
free( m_pData );
m_bFreeArrayMemory = false;
m_nNumArrayElements = 0;
m_Value = 0;
m_nData = 0;
break;
}
default:
@ -258,7 +230,7 @@ void KeyValues3::PrepareForType( KV3TypeEx_t type, KV3SubType_t subtype )
{
Free();
m_TypeEx = type;
m_Value = 0;
m_nData = 0;
Alloc();
}
@ -269,7 +241,7 @@ void KeyValues3::OnClearContext()
{
Free( true );
m_TypeEx = KV3_TYPEEX_NULL;
m_Value = 0;
m_nData = 0;
}
CKeyValues3Cluster* KeyValues3::GetCluster() const
@ -409,7 +381,7 @@ void KeyValues3::SetToBinaryBlobExternal( const byte* blob, int size, bool free_
}
}
Color KeyValues3::GetColor( Color defaultValue ) const
Color KeyValues3::GetColor( const Color &defaultValue ) const
{
int32 color[4];
if ( ReadArrayInt32( 4, color ) )
@ -428,7 +400,10 @@ Color KeyValues3::GetColor( Color defaultValue ) const
void KeyValues3::SetColor( const Color &color )
{
AllocArray<uint8>( 4, &color[0], KV3_ARRAY_ALLOC_NORMAL, KV3_TYPEEX_ARRAY_UINT8_SHORT, KV3_TYPEEX_INVALID, KV3_SUBTYPE_COLOR32, KV3_TYPEEX_UINT, KV3_SUBTYPE_UINT8 );
if ( color.a() == 255 )
AllocArray<uint8>( 3, &color[0], KV3_ARRAY_ALLOC_NORMAL, KV3_TYPEEX_ARRAY_UINT8_SHORT, KV3_TYPEEX_INVALID, KV3_SUBTYPE_COLOR32, KV3_TYPEEX_UINT, KV3_SUBTYPE_UINT8 );
else
AllocArray<uint8>( 4, &color[0], KV3_ARRAY_ALLOC_NORMAL, KV3_TYPEEX_ARRAY_UINT8_SHORT, KV3_TYPEEX_INVALID, KV3_SUBTYPE_COLOR32, KV3_TYPEEX_UINT, KV3_SUBTYPE_UINT8 );
}
int KeyValues3::GetArrayElementCount() const
@ -585,8 +560,7 @@ bool KeyValues3::ReadArrayInt32( int dest_size, int32* data ) const
{
src_size = m_nNumArrayElements;
int count = MIN( src_size, dest_size );
for ( int i = 0; i < count; ++i )
data[ i ] = m_i32Array[ i ];
memcpy( data, m_i32Array, count * sizeof( int32 ) );
break;
}
case KV3_TYPEEX_ARRAY_UINT8_SHORT:
@ -645,8 +619,7 @@ bool KeyValues3::ReadArrayFloat32( int dest_size, float32* data ) const
{
src_size = m_nNumArrayElements;
int count = MIN( src_size, dest_size );
for ( int i = 0; i < count; ++i )
data[ i ] = m_f32Array[ i ];
memcpy( data, m_f32Array, count * sizeof( float32 ) );
break;
}
case KV3_TYPEEX_ARRAY_FLOAT64:
@ -676,7 +649,7 @@ int KeyValues3::GetMemberCount() const
return m_pTable->GetMemberCount();
}
KeyValues3* KeyValues3::GetMember( KV3MemberId_t id ) const
KeyValues3* KeyValues3::GetMember( KV3MemberId_t id )
{
if ( GetType() != KV3_TYPE_TABLE || id < 0 || id >= m_pTable->GetMemberCount() )
return NULL;
@ -708,7 +681,7 @@ unsigned int KeyValues3::GetMemberHash( KV3MemberId_t id ) const
return m_pTable->GetMemberHash( id );
}
KeyValues3* KeyValues3::FindMember( const CKV3MemberName &name, KeyValues3* defaultValue ) const
KeyValues3* KeyValues3::FindMember( const CKV3MemberName &name, KeyValues3* defaultValue )
{
if ( GetType() != KV3_TYPE_TABLE )
return defaultValue;
@ -744,6 +717,22 @@ KeyValues3* KeyValues3::FindOrCreateMember( const CKV3MemberName &name, bool *pC
return m_pTable->GetMember( id );
}
bool KeyValues3::TableHasBadNames() const
{
if ( GetType() != KV3_TYPE_TABLE )
return false;
return m_pTable->HasBadNames();
}
void KeyValues3::SetTableHasBadNames( bool bHasBadNames )
{
if ( GetType() != KV3_TYPE_TABLE )
return;
m_pTable->SetHasBadNames( bHasBadNames );
}
void KeyValues3::SetToEmptyTable()
{
PrepareForType( KV3_TYPEEX_TABLE, KV3_SUBTYPE_TABLE );
@ -790,6 +779,292 @@ bool KeyValues3::RemoveMember( const CKV3MemberName &name )
return true;
}
const char* KeyValues3::GetTypeAsString() const
{
static const char* s_Types[] =
{
"invalid",
"null",
"bool",
"int",
"uint",
"double",
"string",
"binary_blob",
"array",
"table",
NULL
};
KV3Type_t type = GetType();
if ( type < KV3_TYPE_COUNT )
return s_Types[type];
return "<unknown>";
}
const char* KeyValues3::GetSubTypeAsString() const
{
static const char* s_SubTypes[] =
{
"invalid",
"resource",
"resource_name",
"panorama",
"soundevent",
"subclass",
"entity_name",
"unspecified",
"null",
"binary_blob",
"array",
"table",
"bool8",
"char8",
"uchar32",
"int8",
"uint8",
"int16",
"uint16",
"int32",
"uint32",
"int64",
"uint64",
"float32",
"float64",
"string",
"pointer",
"color32",
"vector",
"vector2d",
"vector4d",
"rotation_vector",
"quaternion",
"qangle",
"matrix3x4",
"transform",
"string_token",
"ehandle",
NULL
};
KV3SubType_t subtype = GetSubType();
if ( subtype < KV3_SUBTYPE_COUNT )
return s_SubTypes[subtype];
return "<unknown>";
}
const char* KeyValues3::ToString( CBufferString& buff, uint flags ) const
{
if ( ( flags & KV3_TO_STRING_DONT_CLEAR_BUFF ) != 0 )
flags &= ~KV3_TO_STRING_DONT_APPEND_STRINGS;
else
buff.ToGrowable()->Clear();
KV3Type_t type = GetType();
switch ( type )
{
case KV3_TYPE_NULL:
{
return buff.ToGrowable()->Get();
}
case KV3_TYPE_BOOL:
{
const char* str = m_Bool ? "true" : "false";
if ( ( flags & KV3_TO_STRING_DONT_APPEND_STRINGS ) != 0 )
return str;
buff.Insert( buff.ToGrowable()->GetTotalNumber(), str );
return buff.ToGrowable()->Get();
}
case KV3_TYPE_INT:
{
buff.AppendFormat( "%lld", m_Int );
return buff.ToGrowable()->Get();
}
case KV3_TYPE_UINT:
{
if ( GetSubType() == KV3_SUBTYPE_POINTER )
{
if ( ( flags & KV3_TO_STRING_APPEND_ONLY_NUMERICS ) == 0 )
buff.Insert( buff.ToGrowable()->GetTotalNumber(), "<pointer>" );
if ( ( flags & KV3_TO_STRING_RETURN_NON_NUMERICS ) == 0 )
return NULL;
return buff.ToGrowable()->Get();
}
buff.AppendFormat( "%llu", m_UInt );
return buff.ToGrowable()->Get();
}
case KV3_TYPE_DOUBLE:
{
buff.AppendFormat( "%g", m_Double );
return buff.ToGrowable()->Get();
}
case KV3_TYPE_STRING:
{
const char* str = GetString();
if ( ( flags & KV3_TO_STRING_DONT_APPEND_STRINGS ) != 0 )
return str;
buff.Insert( buff.ToGrowable()->GetTotalNumber(), str );
return buff.ToGrowable()->Get();
}
case KV3_TYPE_BINARY_BLOB:
{
if ( ( flags & KV3_TO_STRING_APPEND_ONLY_NUMERICS ) == 0 )
buff.AppendFormat( "<binary blob: %u bytes>", GetBinaryBlobSize() );
if ( ( flags & KV3_TO_STRING_RETURN_NON_NUMERICS ) == 0 )
return NULL;
return buff.ToGrowable()->Get();
}
case KV3_TYPE_ARRAY:
{
int elements = GetArrayElementCount();
if ( elements > 0 && elements <= 4 )
{
switch ( GetTypeEx() )
{
case KV3_TYPEEX_ARRAY:
{
bool unprintable = false;
CBufferStringGrowable<128> temp;
KeyValues3** arr = m_pArray->Base();
for ( int i = 0; i < elements; ++i )
{
switch ( arr[i]->GetType() )
{
case KV3_TYPE_INT:
temp.AppendFormat( "%lld", arr[i]->m_Int );
break;
case KV3_TYPE_UINT:
if ( arr[i]->GetSubType() == KV3_SUBTYPE_POINTER )
unprintable = true;
else
temp.AppendFormat( "%llu", arr[i]->m_UInt );
break;
case KV3_TYPE_DOUBLE:
temp.AppendFormat( "%g", arr[i]->m_Double );
break;
default:
unprintable = true;
break;
}
if ( unprintable )
break;
if ( i != elements - 1 ) temp.Insert( temp.ToGrowable()->GetTotalNumber(), " " );
}
if ( unprintable )
break;
buff.Insert( buff.ToGrowable()->GetTotalNumber(), temp.Get() );
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_FLOAT32:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%g", m_f32Array[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_FLOAT64:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%g", m_f64Array[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_INT16:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%d", m_i16Array[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_INT32:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%d", m_i32Array[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_UINT8_SHORT:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%u", m_u8ArrayShort[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
case KV3_TYPEEX_ARRAY_INT16_SHORT:
{
for ( int i = 0; i < elements; ++i )
{
buff.AppendFormat( "%d", m_i16ArrayShort[i] );
if ( i != elements - 1 ) buff.Insert( buff.ToGrowable()->GetTotalNumber(), " " );
}
return buff.ToGrowable()->Get();
}
default:
break;
}
}
if ( ( flags & KV3_TO_STRING_APPEND_ONLY_NUMERICS ) == 0 )
buff.AppendFormat( "<array: %u elements>", elements );
if ( ( flags & KV3_TO_STRING_RETURN_NON_NUMERICS ) == 0 )
return NULL;
return buff.ToGrowable()->Get();
}
case KV3_TYPE_TABLE:
{
if ( ( flags & KV3_TO_STRING_APPEND_ONLY_NUMERICS ) == 0 )
buff.AppendFormat( "<table: %u members>", GetMemberCount() );
if ( ( flags & KV3_TO_STRING_RETURN_NON_NUMERICS ) == 0 )
return NULL;
return buff.ToGrowable()->Get();
}
default:
{
if ( ( flags & KV3_TO_STRING_APPEND_ONLY_NUMERICS ) == 0 )
buff.AppendFormat( "<unknown KV3 basic type '%s' (%d)>", GetTypeAsString(), type );
if ( ( flags & KV3_TO_STRING_RETURN_NON_NUMERICS ) == 0 )
return NULL;
return buff.ToGrowable()->Get();
}
}
}
void KeyValues3::CopyFrom( const KeyValues3* pSrc )
{
SetToNull();
@ -886,12 +1161,17 @@ KeyValues3& KeyValues3::operator=( const KeyValues3& src )
return *this;
}
CKeyValues3Array::CKeyValues3Array( int cluster_elem ) :
m_nClusterElement( cluster_elem )
{
}
CKeyValues3ArrayCluster* CKeyValues3Array::GetCluster() const
{
if ( m_nClusterElement == -1 )
return NULL;
return GET_OUTER( CKeyValues3ArrayCluster, m_Arrays[ m_nClusterElement ] );
return GET_OUTER( CKeyValues3ArrayCluster, m_Elements[ m_nClusterElement ] );
}
CKeyValues3Context* CKeyValues3Array::GetContext() const
@ -991,12 +1271,19 @@ void CKeyValues3Array::Purge( bool bClearingContext )
m_Elements.Purge();
}
CKeyValues3Table::CKeyValues3Table( int cluster_elem ) :
m_nClusterElement( cluster_elem ),
m_pFastSearch( NULL ),
m_bHasBadNames( false )
{
}
CKeyValues3TableCluster* CKeyValues3Table::GetCluster() const
{
if ( m_nClusterElement == -1 )
return NULL;
return GET_OUTER( CKeyValues3TableCluster, m_Tables[ m_nClusterElement ] );
return GET_OUTER( CKeyValues3TableCluster, m_Elements[ m_nClusterElement ] );
}
CKeyValues3Context* CKeyValues3Table::GetContext() const
@ -1238,11 +1525,26 @@ void CKeyValues3Table::Purge( bool bClearingContext )
m_IsExternalName.Purge();
}
CKeyValues3Cluster::CKeyValues3Cluster( CKeyValues3Context* context ) :
m_pContext( context ),
m_nAllocatedElements( 0 ),
m_pMetaData( NULL ),
m_pNextFree( NULL )
{
memset( &m_KeyValues, 0, sizeof( m_KeyValues ) );
}
CKeyValues3Cluster::~CKeyValues3Cluster()
{
FreeMetaData();
}
#include "tier0/memdbgoff.h"
KeyValues3* CKeyValues3Cluster::Alloc( KV3TypeEx_t type, KV3SubType_t subtype )
{
int element = BitScanFwd( ~m_nAllocatedElements );
Assert( IsFree() );
int element = KV3Helpers::BitScanFwd( ~m_nAllocatedElements );
m_nAllocatedElements |= ( 1ull << element );
KeyValues3* kv = &m_KeyValues[ element ];
new( kv ) KeyValues3( element, type, subtype );
@ -1253,6 +1555,7 @@ KeyValues3* CKeyValues3Cluster::Alloc( KV3TypeEx_t type, KV3SubType_t subtype )
void CKeyValues3Cluster::Free( int element )
{
Assert( element >= 0 && element < KV3_CLUSTER_MAX_ELEMENTS );
KeyValues3* kv = &m_KeyValues[ element ];
Destruct( kv );
memset( (void *)kv, 0, sizeof( KeyValues3 ) );
@ -1316,87 +1619,14 @@ void CKeyValues3Cluster::FreeMetaData()
KV3MetaData_t* CKeyValues3Cluster::GetMetaData( int element ) const
{
Assert( element >= 0 && element < KV3_CLUSTER_MAX_ELEMENTS );
if ( !m_pMetaData )
return NULL;
return &m_pMetaData->m_elements[ element ];
}
int CKeyValues3Cluster::NumAllocated() const
{
return PopCount( m_nAllocatedElements );
}
CKeyValues3Array* CKeyValues3ArrayCluster::Alloc()
{
int element = BitScanFwd( ~m_nAllocatedElements );
m_nAllocatedElements |= ( 1ull << element );
CKeyValues3Array* arr = &m_Arrays[ element ];
Construct( arr, element );
return arr;
}
void CKeyValues3ArrayCluster::Free( int element )
{
CKeyValues3Array* arr = &m_Arrays[ element ];
Destruct( arr );
memset( (void *)arr, 0, sizeof( CKeyValues3Array ) );
m_nAllocatedElements &= ~( 1ull << element );
}
void CKeyValues3ArrayCluster::Purge()
{
uint64 mask = 1;
for ( int i = 0; i < KV3_CLUSTER_MAX_ELEMENTS; ++i )
{
if ( ( m_nAllocatedElements & mask ) != 0 )
m_Arrays[ i ].Purge( true );
mask <<= 1;
}
m_nAllocatedElements = 0;
}
int CKeyValues3ArrayCluster::NumAllocated() const
{
return PopCount( m_nAllocatedElements );
}
CKeyValues3Table* CKeyValues3TableCluster::Alloc()
{
int element = BitScanFwd( ~m_nAllocatedElements );
m_nAllocatedElements |= ( 1ull << element );
CKeyValues3Table* table = &m_Tables[ element ];
Construct( table, element );
return table;
}
void CKeyValues3TableCluster::Free( int element )
{
CKeyValues3Table* table = &m_Tables[ element ];
Destruct( table );
memset( (void *)table, 0, sizeof( CKeyValues3Table ) );
m_nAllocatedElements &= ~( 1ull << element );
}
void CKeyValues3TableCluster::Purge()
{
uint64 mask = 1;
for ( int i = 0; i < KV3_CLUSTER_MAX_ELEMENTS; ++i )
{
if ( ( m_nAllocatedElements & mask ) != 0 )
m_Tables[ i ].Purge( true );
mask <<= 1;
}
m_nAllocatedElements = 0;
}
int CKeyValues3TableCluster::NumAllocated() const
{
return PopCount( m_nAllocatedElements );
}
CKeyValues3ContextBase::CKeyValues3ContextBase( CKeyValues3Context* context ) :
m_pContext( context ),
m_KV3BaseCluster( context ),
@ -1602,7 +1832,10 @@ KeyValues3* CKeyValues3Context::AllocKV( KV3TypeEx_t type, KV3SubType_t subtype
void CKeyValues3Context::FreeKV( KeyValues3* kv )
{
KV3MetaData_t* metadata = kv->GetMetaData();
CKeyValues3Context* context;
KV3MetaData_t* metadata = kv->GetMetaData( &context );
Assert( context == m_pContext );
if ( metadata )
metadata->Clear();