mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Implement CUtlMemory, CUtlBlockMemory and CUtlVector
CUtlMemory has been modified to fit the size of the in-engine structure. The new types seem to be either int64 or unsigned (size_t?).
This commit is contained in:
parent
0fe554b3d1
commit
20d1fabd0c
8
r5dev/tier0/memalloc.h
Normal file
8
r5dev/tier0/memalloc.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef TIER0_MEMALLOC_H
|
||||
#define TIER0_MEMALLOC_H
|
||||
|
||||
#define MEM_ALLOC_CREDIT_CLASS()
|
||||
#define MEM_ALLOC_CLASSNAME(type) NULL
|
||||
#define MEM_ALLOC_CREDIT_FUNCTION()
|
||||
|
||||
#endif /* TIER0_MEMALLOC_H */
|
@ -149,6 +149,30 @@
|
||||
|
||||
#endif // CROSS_PLATFORM_VERSION < 2
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up build configuration defines.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef _CERT
|
||||
#define IsCert() 1
|
||||
#else
|
||||
#define IsCert() 0
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define IsRelease() 0
|
||||
#define IsDebug() 1
|
||||
#else
|
||||
#define IsRelease() 1
|
||||
#define IsDebug() 0
|
||||
#endif
|
||||
|
||||
#ifdef _RETAIL
|
||||
#define IsRetail() 1
|
||||
#else
|
||||
#define IsRetail() 0
|
||||
#endif
|
||||
|
||||
#if defined( GNUC ) && !defined( COMPILER_PS3 ) // use pre-align on PS3
|
||||
// gnuc has the align decoration at the end
|
||||
#define ALIGN4
|
||||
@ -156,6 +180,7 @@
|
||||
#define ALIGN16
|
||||
#define ALIGN32
|
||||
#define ALIGN128
|
||||
#define ALIGN_N( _align_ )
|
||||
|
||||
#undef ALIGN16_POST
|
||||
#define ALIGN4_POST DECL_ALIGN(4)
|
||||
@ -163,6 +188,7 @@
|
||||
#define ALIGN16_POST DECL_ALIGN(16)
|
||||
#define ALIGN32_POST DECL_ALIGN(32)
|
||||
#define ALIGN128_POST DECL_ALIGN(128)
|
||||
#define ALIGN_N_POST( _align_ ) DECL_ALIGN( _align_ )
|
||||
#else
|
||||
// MSVC has the align at the start of the struct
|
||||
// PS3 SNC supports both
|
||||
@ -171,14 +197,110 @@
|
||||
#define ALIGN16 DECL_ALIGN(16)
|
||||
#define ALIGN32 DECL_ALIGN(32)
|
||||
#define ALIGN128 DECL_ALIGN(128)
|
||||
#define ALIGN_N( _align_ ) DECL_ALIGN( _align_ )
|
||||
|
||||
#define ALIGN4_POST
|
||||
#define ALIGN8_POST
|
||||
#define ALIGN16_POST
|
||||
#define ALIGN32_POST
|
||||
#define ALIGN128_POST
|
||||
#define ALIGN_N_POST( _align_ )
|
||||
#endif
|
||||
|
||||
// !!! NOTE: if you get a compile error here, you are using VALIGNOF on an abstract type :NOTE !!!
|
||||
#define VALIGNOF_PORTABLE( type ) ( sizeof( AlignOf_t<type> ) - sizeof( type ) )
|
||||
|
||||
#if defined( COMPILER_GCC ) || defined( COMPILER_MSVC )
|
||||
#define VALIGNOF( type ) __alignof( type )
|
||||
#define VALIGNOF_TEMPLATE_SAFE( type ) VALIGNOF_PORTABLE( type )
|
||||
#else
|
||||
#error "PORT: Code only tested with MSVC! Must validate with new compiler, and use built-in keyword if available."
|
||||
#endif
|
||||
|
||||
// Use ValidateAlignment to sanity-check alignment usage when allocating arrays of an aligned type
|
||||
#define ALIGN_ASSERT( pred ) { COMPILE_TIME_ASSERT( pred ); }
|
||||
template< class T, int ALIGN >
|
||||
inline void ValidateAlignmentExplicit(void)
|
||||
{
|
||||
// Alignment must be a power of two
|
||||
ALIGN_ASSERT((ALIGN & (ALIGN - 1)) == 0);
|
||||
// Alignment must not imply gaps in the array (which the CUtlMemory pattern does not allow for)
|
||||
ALIGN_ASSERT(ALIGN <= sizeof(T));
|
||||
// Alignment must be a multiple of the size of the object type, or elements will *NOT* be aligned!
|
||||
ALIGN_ASSERT((sizeof(T) % ALIGN) == 0);
|
||||
// Alignment should be a multiple of the base alignment of T
|
||||
// ALIGN_ASSERT((ALIGN % VALIGNOF(T)) == 0);
|
||||
}
|
||||
template< class T > inline void ValidateAlignment(void) { ValidateAlignmentExplicit<T, VALIGNOF(T)>(); }
|
||||
|
||||
// Portable alternative to __alignof
|
||||
template<class T> struct AlignOf_t { AlignOf_t() {} AlignOf_t& operator=(const AlignOf_t&) { return *this; } byte b; T t; };
|
||||
|
||||
template < size_t NUM, class T, int ALIGN > struct AlignedByteArrayExplicit_t {};
|
||||
template < size_t NUM, class T > struct AlignedByteArray_t : public AlignedByteArrayExplicit_t< NUM, T, VALIGNOF_TEMPLATE_SAFE(T) > {};
|
||||
|
||||
|
||||
#if defined(MSVC) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
|
||||
|
||||
#pragma warning(disable:4290)
|
||||
#pragma warning(push)
|
||||
#include <typeinfo.h>
|
||||
|
||||
// MEM_DEBUG_CLASSNAME is opt-in.
|
||||
// Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
|
||||
// simultaneously, it'll need a mutex.
|
||||
#if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
|
||||
|
||||
template <typename T> const char* MemAllocClassName(T* p)
|
||||
{
|
||||
static const char* pszName = typeid(*p).name(); // @TODO: support having debug heap ignore certain allocations, and ignore memory allocated here [5/7/2009 tom]
|
||||
return pszName;
|
||||
}
|
||||
|
||||
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( MemAllocClassName( this ) )
|
||||
#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
|
||||
#else
|
||||
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
|
||||
#define MEM_ALLOC_CLASSNAME(type) (__FILE__)
|
||||
#endif
|
||||
|
||||
// MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example )
|
||||
#ifdef _MSC_VER
|
||||
#define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ )
|
||||
#else
|
||||
#define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__)
|
||||
#endif
|
||||
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#define MEM_ALLOC_CREDIT_CLASS()
|
||||
#define MEM_ALLOC_CLASSNAME(type) NULL
|
||||
#define MEM_ALLOC_CREDIT_FUNCTION()
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macro to assist in asserting constant invariants during compilation
|
||||
|
||||
// This implementation of compile time assert has zero cost (so it can safely be
|
||||
// included in release builds) and can be used at file scope or function scope.
|
||||
#ifdef __GNUC__
|
||||
#define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
|
||||
#else
|
||||
#if _MSC_VER >= 1600
|
||||
// If available use static_assert instead of weird language tricks. This
|
||||
// leads to much more readable messages when compile time assert constraints
|
||||
// are violated.
|
||||
#define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
|
||||
#else
|
||||
// Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
|
||||
// errors when used multiple times in one scope. Fix by adding extra scoping.
|
||||
#define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
|
||||
#endif
|
||||
#endif
|
||||
// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
|
||||
// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
|
||||
#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
|
||||
|
||||
// This can be used to declare an abstract (interface only) class.
|
||||
// Classes marked abstract should not be instantiated. If they are, and access violation will occur.
|
||||
//
|
||||
@ -474,6 +596,123 @@ inline int64 CastPtrToInt64(const void* p)
|
||||
|
||||
#endif // BUILD_AS_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C++11 helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
#define VALVE_CPP11 1
|
||||
|
||||
#if VALVE_CPP11
|
||||
template <class T> struct C11RemoveReference { typedef T Type; };
|
||||
template <class T> struct C11RemoveReference<T&> { typedef T Type; };
|
||||
template <class T> struct C11RemoveReference<T&&> { typedef T Type; };
|
||||
|
||||
template <class T>
|
||||
inline typename C11RemoveReference<T>::Type&& Move(T&& obj)
|
||||
{
|
||||
return static_cast<typename C11RemoveReference<T>::Type&&>(obj);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T&& Forward(typename C11RemoveReference<T>::Type& obj)
|
||||
{
|
||||
return static_cast<T&&>(obj);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T&& Forward(typename C11RemoveReference<T>::Type&& obj)
|
||||
{
|
||||
return static_cast<T&&>(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods to invoke the constructor, copy constructor, and destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline T* Construct(T* pMemory)
|
||||
{
|
||||
return ::new(pMemory) T;
|
||||
}
|
||||
|
||||
template <class T, typename ARG1>
|
||||
inline T* Construct(T* pMemory, ARG1 a1)
|
||||
{
|
||||
return ::new(pMemory) T(a1);
|
||||
}
|
||||
|
||||
template <class T, typename ARG1, typename ARG2>
|
||||
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2)
|
||||
{
|
||||
return ::new(pMemory) T(a1, a2);
|
||||
}
|
||||
|
||||
template <class T, typename ARG1, typename ARG2, typename ARG3>
|
||||
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3)
|
||||
{
|
||||
return ::new(pMemory) T(a1, a2, a3);
|
||||
}
|
||||
|
||||
template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4>
|
||||
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4)
|
||||
{
|
||||
return ::new(pMemory) T(a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4, typename ARG5>
|
||||
inline T* Construct(T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5)
|
||||
{
|
||||
return ::new(pMemory) T(a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* CopyConstruct(T* pMemory, T const& src)
|
||||
{
|
||||
return ::new(pMemory) T(src);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T* MoveConstruct(T* pMemory, T&& src)
|
||||
{
|
||||
return ::new(pMemory) T(Move(src));
|
||||
}
|
||||
|
||||
// [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16)))
|
||||
// Fixed by specializing the Destroy function to not call destructor for that type.
|
||||
#if defined( __clang__ ) || defined (LINUX)
|
||||
|
||||
template <class T>
|
||||
inline void Destruct(T* pMemory);
|
||||
|
||||
template <>
|
||||
inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory);
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
template <class T>
|
||||
inline void Destruct(T* pMemory)
|
||||
{
|
||||
pMemory->~T();
|
||||
|
||||
#ifdef _DEBUG
|
||||
memset(pMemory, 0xDD, sizeof(T));
|
||||
#endif
|
||||
}
|
||||
|
||||
// [will] - Fixing a clang compile: unable to create a pseudo-destructor (aka a destructor that does nothing) for float __attribute__((__vector_size__(16)))
|
||||
// Fixed by specializing the Destroy function to not call destructor for that type.
|
||||
#if defined( __clang__ ) || defined (LINUX)
|
||||
|
||||
template <>
|
||||
inline void Destruct(float __attribute__((__vector_size__(16)))* pMemory)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
memset(pMemory, 0xDD, sizeof(float __attribute__((__vector_size__(16)))));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processor Information:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "vstdlib/callback.h"
|
||||
#include "public/include/iconvar.h"
|
||||
#include "public/include/iconcommand.h"
|
||||
#include <tier1/utlvector.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: construct/allocate
|
||||
|
103
r5dev/tier1/splitstring.cpp
Normal file
103
r5dev/tier1/splitstring.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
//================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "strtools.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
CSplitString::CSplitString()
|
||||
{
|
||||
m_szBuffer = nullptr;
|
||||
}
|
||||
|
||||
CSplitString::CSplitString(const char* pString, const char** pSeparators, int nSeparators)
|
||||
{
|
||||
Construct(pString, pSeparators, nSeparators);
|
||||
};
|
||||
|
||||
CSplitString::CSplitString(const char* pString, const char* pSeparator)
|
||||
{
|
||||
Construct(pString, &pSeparator, 1);
|
||||
}
|
||||
|
||||
CSplitString::~CSplitString()
|
||||
{
|
||||
if (m_szBuffer)
|
||||
delete[] m_szBuffer;
|
||||
}
|
||||
|
||||
void CSplitString::Set(const char* pString, const char** pSeparators, int nSeparators)
|
||||
{
|
||||
delete[] m_szBuffer;
|
||||
Construct(pString, pSeparators, nSeparators);
|
||||
}
|
||||
|
||||
void CSplitString::Construct(const char* pString, const char** pSeparators, int nSeparators)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make a duplicate of the original string. We'll use pieces of this duplicate to tokenize the string
|
||||
// and create NULL-terminated tokens of the original string
|
||||
//
|
||||
int nOriginalStringLength = strlen(pString);
|
||||
m_szBuffer = new char[nOriginalStringLength + 1];
|
||||
memcpy(m_szBuffer, pString, nOriginalStringLength + 1);
|
||||
|
||||
this->Purge();
|
||||
const char* pCurPos = pString;
|
||||
while (1)
|
||||
{
|
||||
int iFirstSeparator = -1;
|
||||
const char* pFirstSeparator = 0;
|
||||
for (int i = 0; i < nSeparators; i++)
|
||||
{
|
||||
const char* pTest = strstr(pCurPos, pSeparators[i]);
|
||||
if (pTest && (!pFirstSeparator || pTest < pFirstSeparator))
|
||||
{
|
||||
iFirstSeparator = i;
|
||||
pFirstSeparator = pTest;
|
||||
}
|
||||
}
|
||||
|
||||
if (pFirstSeparator)
|
||||
{
|
||||
// Split on this separator and continue on.
|
||||
int separatorLen = strlen(pSeparators[iFirstSeparator]);
|
||||
if (pFirstSeparator > pCurPos)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// Cut the token out of the duplicate string
|
||||
char* pTokenInDuplicate = m_szBuffer + (pCurPos - pString);
|
||||
int nTokenLength = pFirstSeparator - pCurPos;
|
||||
//Assert(nTokenLength > 0 && !memcmp(pTokenInDuplicate, pCurPos, nTokenLength));
|
||||
pTokenInDuplicate[nTokenLength] = '\0';
|
||||
|
||||
this->AddToTail(pTokenInDuplicate /*AllocString( pCurPos, pFirstSeparator-pCurPos )*/);
|
||||
}
|
||||
|
||||
pCurPos = pFirstSeparator + separatorLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the rest of the string
|
||||
if (int nTokenLength = strlen(pCurPos))
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// There's no need to cut this token, because there's no separator after it.
|
||||
// just add its copy in the buffer to the tail
|
||||
char* pTokenInDuplicate = m_szBuffer + (pCurPos - pString);
|
||||
//Assert(!memcmp(pTokenInDuplicate, pCurPos, nTokenLength));
|
||||
|
||||
this->AddToTail(pTokenInDuplicate/*AllocString( pCurPos, -1 )*/);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSplitString::PurgeAndDeleteElements()
|
||||
{
|
||||
Purge();
|
||||
}
|
349
r5dev/tier1/utlblockmemory.h
Normal file
349
r5dev/tier1/utlblockmemory.h
Normal file
@ -0,0 +1,349 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// A growable memory class.
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef UTLBLOCKMEMORY_H
|
||||
#define UTLBLOCKMEMORY_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
//#include "tier0/memalloc.h"
|
||||
//#include "tier0/memdbgon.h"
|
||||
|
||||
#pragma warning (disable:4100)
|
||||
#pragma warning (disable:4514)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef UTBLOCKLMEMORY_TRACK
|
||||
#define UTLBLOCKMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
|
||||
#define UTLBLOCKMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
|
||||
#else
|
||||
#define UTLBLOCKMEMORY_TRACK_ALLOC() ((void)0)
|
||||
#define UTLBLOCKMEMORY_TRACK_FREE() ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The CUtlBlockMemory class:
|
||||
// A growable memory class that allocates non-sequential blocks, but is indexed sequentially
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
class CUtlBlockMemory
|
||||
{
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlBlockMemory(int nGrowSize = 0, int nInitSize = 0);
|
||||
~CUtlBlockMemory();
|
||||
|
||||
// Set the size by which the memory grows - round up to the next power of 2
|
||||
void Init(int nGrowSize = 0, int nInitSize = 0);
|
||||
|
||||
// here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL
|
||||
T* Base() { return NULL; }
|
||||
const T* Base() const { return NULL; }
|
||||
|
||||
class Iterator_t
|
||||
{
|
||||
public:
|
||||
Iterator_t(I i) : index(i) {}
|
||||
I index;
|
||||
|
||||
bool operator==(const Iterator_t it) const { return index == it.index; }
|
||||
bool operator!=(const Iterator_t it) const { return index != it.index; }
|
||||
};
|
||||
Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); }
|
||||
Iterator_t Next(const Iterator_t& it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); }
|
||||
I GetIndex(const Iterator_t& it) const { return it.index; }
|
||||
bool IsIdxAfter(I i, const Iterator_t& it) const { return i > it.index; }
|
||||
bool IsValidIterator(const Iterator_t& it) const { return IsIdxValid(it.index); }
|
||||
Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); }
|
||||
|
||||
// element access
|
||||
T& operator[](I i);
|
||||
const T& operator[](I i) const;
|
||||
T& Element(I i);
|
||||
const T& Element(I i) const;
|
||||
|
||||
// Can we use this index?
|
||||
bool IsIdxValid(I i) const;
|
||||
static I InvalidIndex() { return (I)-1; }
|
||||
|
||||
void Swap(CUtlBlockMemory< T, I >& mem);
|
||||
|
||||
// Size
|
||||
int NumAllocated() const;
|
||||
int Count() const { return NumAllocated(); }
|
||||
|
||||
// Grows memory by max(num,growsize) rounded up to the next power of 2, and returns the allocation index/ptr
|
||||
void Grow(int num = 1);
|
||||
|
||||
// Makes sure we've got at least this much memory
|
||||
void EnsureCapacity(int num);
|
||||
|
||||
// Memory deallocation
|
||||
void Purge();
|
||||
|
||||
// Purge all but the given number of elements
|
||||
void Purge(int numElements);
|
||||
|
||||
protected:
|
||||
int Index(int major, int minor) const { return (major << m_nIndexShift) | minor; }
|
||||
int MajorIndex(int i) const { return i >> m_nIndexShift; }
|
||||
int MinorIndex(int i) const { return i & m_nIndexMask; }
|
||||
void ChangeSize(int nBlocks);
|
||||
int NumElementsInBlock() const { return m_nIndexMask + 1; }
|
||||
|
||||
T** m_pMemory;
|
||||
int m_nBlocks;
|
||||
int m_nIndexMask : 27;
|
||||
int m_nIndexShift : 5;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class I >
|
||||
CUtlBlockMemory<T, I>::CUtlBlockMemory(int nGrowSize, int nInitAllocationCount)
|
||||
: m_pMemory(0), m_nBlocks(0), m_nIndexMask(0), m_nIndexShift(0)
|
||||
{
|
||||
Init(nGrowSize, nInitAllocationCount);
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlBlockMemory<T, I>::~CUtlBlockMemory()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fast swap
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::Swap(CUtlBlockMemory< T, I >& mem)
|
||||
{
|
||||
V_swap(m_pMemory, mem.m_pMemory);
|
||||
V_swap(m_nBlocks, mem.m_nBlocks);
|
||||
V_swap(m_nIndexMask, mem.m_nIndexMask);
|
||||
V_swap(m_nIndexShift, mem.m_nIndexShift);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the size by which the memory grows - round up to the next power of 2
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::Init(int nGrowSize /* = 0 */, int nInitSize /* = 0 */)
|
||||
{
|
||||
Purge();
|
||||
|
||||
if (nGrowSize == 0)
|
||||
{
|
||||
// default grow size is smallest size s.t. c++ allocation overhead is ~6% of block size
|
||||
nGrowSize = (127 + sizeof(T)) / sizeof(T);
|
||||
}
|
||||
nGrowSize = SmallestPowerOfTwoGreaterOrEqual(nGrowSize);
|
||||
m_nIndexMask = nGrowSize - 1;
|
||||
|
||||
m_nIndexShift = 0;
|
||||
while (nGrowSize > 1)
|
||||
{
|
||||
nGrowSize >>= 1;
|
||||
++m_nIndexShift;
|
||||
}
|
||||
Assert(m_nIndexMask + 1 == (1 << m_nIndexShift));
|
||||
|
||||
Grow(nInitSize);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element access
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline T& CUtlBlockMemory<T, I>::operator[](I i)
|
||||
{
|
||||
Assert(IsIdxValid(i));
|
||||
T* pBlock = m_pMemory[MajorIndex(i)];
|
||||
return pBlock[MinorIndex(i)];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlBlockMemory<T, I>::operator[](I i) const
|
||||
{
|
||||
Assert(IsIdxValid(i));
|
||||
const T* pBlock = m_pMemory[MajorIndex(i)];
|
||||
return pBlock[MinorIndex(i)];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline T& CUtlBlockMemory<T, I>::Element(I i)
|
||||
{
|
||||
Assert(IsIdxValid(i));
|
||||
T* pBlock = m_pMemory[MajorIndex(i)];
|
||||
return pBlock[MinorIndex(i)];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlBlockMemory<T, I>::Element(I i) const
|
||||
{
|
||||
Assert(IsIdxValid(i));
|
||||
const T* pBlock = m_pMemory[MajorIndex(i)];
|
||||
return pBlock[MinorIndex(i)];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Size
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline int CUtlBlockMemory<T, I>::NumAllocated() const
|
||||
{
|
||||
return m_nBlocks * NumElementsInBlock();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is element index valid?
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline bool CUtlBlockMemory<T, I>::IsIdxValid(I i) const
|
||||
{
|
||||
return (i >= 0) && (MajorIndex(i) < m_nBlocks);
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::Grow(int num)
|
||||
{
|
||||
if (num <= 0)
|
||||
return;
|
||||
|
||||
int nBlockSize = NumElementsInBlock();
|
||||
int nBlocks = (num + nBlockSize - 1) / nBlockSize;
|
||||
|
||||
ChangeSize(m_nBlocks + nBlocks);
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::ChangeSize(int nBlocks)
|
||||
{
|
||||
UTLBLOCKMEMORY_TRACK_FREE(); // this must stay before the recalculation of m_nBlocks, since it implicitly uses the old value
|
||||
|
||||
int nBlocksOld = m_nBlocks;
|
||||
m_nBlocks = nBlocks;
|
||||
|
||||
UTLBLOCKMEMORY_TRACK_ALLOC(); // this must stay after the recalculation of m_nBlocks, since it implicitly uses the new value
|
||||
|
||||
// free old blocks if shrinking
|
||||
for (int i = m_nBlocks; i < nBlocksOld; ++i)
|
||||
{
|
||||
UTLBLOCKMEMORY_TRACK_FREE();
|
||||
free((void*)m_pMemory[i]);
|
||||
}
|
||||
|
||||
if (m_pMemory)
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
m_pMemory = (T**)realloc(m_pMemory, m_nBlocks * sizeof(T*));
|
||||
Assert(m_pMemory);
|
||||
}
|
||||
else
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
m_pMemory = (T**)malloc(m_nBlocks * sizeof(T*));
|
||||
Assert(m_pMemory);
|
||||
}
|
||||
|
||||
if (!m_pMemory)
|
||||
{
|
||||
Error(eDLL_T::COMMON, "CUtlBlockMemory overflow!\n");
|
||||
}
|
||||
|
||||
// allocate new blocks if growing
|
||||
int nBlockSize = NumElementsInBlock();
|
||||
for (int i = nBlocksOld; i < m_nBlocks; ++i)
|
||||
{
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
m_pMemory[i] = (T*)malloc(nBlockSize * sizeof(T));
|
||||
Assert(m_pMemory[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we've got at least this much memory
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline void CUtlBlockMemory<T, I>::EnsureCapacity(int num)
|
||||
{
|
||||
Grow(num - NumAllocated());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::Purge()
|
||||
{
|
||||
if (!m_pMemory)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < m_nBlocks; ++i)
|
||||
{
|
||||
UTLBLOCKMEMORY_TRACK_FREE();
|
||||
free((void*)m_pMemory[i]);
|
||||
}
|
||||
m_nBlocks = 0;
|
||||
|
||||
UTLBLOCKMEMORY_TRACK_FREE();
|
||||
free((void*)m_pMemory);
|
||||
m_pMemory = 0;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlBlockMemory<T, I>::Purge(int numElements)
|
||||
{
|
||||
Assert(numElements >= 0);
|
||||
|
||||
int nAllocated = NumAllocated();
|
||||
if (numElements > nAllocated)
|
||||
{
|
||||
// Ensure this isn't a grow request in disguise.
|
||||
Assert(numElements <= nAllocated);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numElements <= 0)
|
||||
{
|
||||
Purge();
|
||||
return;
|
||||
}
|
||||
|
||||
int nBlockSize = NumElementsInBlock();
|
||||
int nBlocksOld = m_nBlocks;
|
||||
int nBlocks = (numElements + nBlockSize - 1) / nBlockSize;
|
||||
|
||||
// If the number of blocks is the same as the allocated number of blocks, we are done.
|
||||
if (nBlocks == m_nBlocks)
|
||||
return;
|
||||
|
||||
ChangeSize(nBlocks);
|
||||
}
|
||||
|
||||
//#include "tier0/memdbgoff.h"
|
||||
|
||||
#endif // UTLBLOCKMEMORY_H
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -113,6 +113,7 @@
|
||||
<ClCompile Include="..\tier1\cvar.cpp" />
|
||||
<ClCompile Include="..\tier1\IConVar.cpp" />
|
||||
<ClCompile Include="..\tier1\NetAdr2.cpp" />
|
||||
<ClCompile Include="..\tier1\splitstring.cpp" />
|
||||
<ClCompile Include="..\tier1\strtools.cpp" />
|
||||
<ClCompile Include="..\tier2\meshutils.cpp" />
|
||||
<ClCompile Include="..\tier2\renderutils.cpp" />
|
||||
@ -462,6 +463,7 @@
|
||||
<ClInclude Include="..\tier0\fasttimer.h" />
|
||||
<ClInclude Include="..\tier0\interface.h" />
|
||||
<ClInclude Include="..\tier0\jobthread.h" />
|
||||
<ClInclude Include="..\tier0\memalloc.h" />
|
||||
<ClInclude Include="..\tier0\memstd.h" />
|
||||
<ClInclude Include="..\tier0\platform.h" />
|
||||
<ClInclude Include="..\tier0\platform_internal.h" />
|
||||
@ -478,6 +480,7 @@
|
||||
<ClInclude Include="..\tier1\mempool.h" />
|
||||
<ClInclude Include="..\tier1\NetAdr2.h" />
|
||||
<ClInclude Include="..\tier1\strtools.h" />
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h" />
|
||||
<ClInclude Include="..\tier1\utldict.h" />
|
||||
<ClInclude Include="..\tier1\utlmemory.h" />
|
||||
<ClInclude Include="..\tier1\utlvector.h" />
|
||||
|
@ -564,6 +564,9 @@
|
||||
<ClCompile Include="..\tier1\characterset.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tier1\splitstring.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\client\cdll_engine_int.h">
|
||||
@ -1664,6 +1667,12 @@
|
||||
<ClInclude Include="..\public\include\icliententitylist.h">
|
||||
<Filter>sdk\public\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier0\memalloc.h">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\shared\resource\lockedserver.png">
|
||||
|
@ -423,6 +423,7 @@
|
||||
<ClInclude Include="..\tier0\fasttimer.h" />
|
||||
<ClInclude Include="..\tier0\interface.h" />
|
||||
<ClInclude Include="..\tier0\jobthread.h" />
|
||||
<ClInclude Include="..\tier0\memalloc.h" />
|
||||
<ClInclude Include="..\tier0\memstd.h" />
|
||||
<ClInclude Include="..\tier0\platform.h" />
|
||||
<ClInclude Include="..\tier0\platform_internal.h" />
|
||||
@ -439,6 +440,7 @@
|
||||
<ClInclude Include="..\tier1\mempool.h" />
|
||||
<ClInclude Include="..\tier1\NetAdr2.h" />
|
||||
<ClInclude Include="..\tier1\strtools.h" />
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h" />
|
||||
<ClInclude Include="..\tier1\utldict.h" />
|
||||
<ClInclude Include="..\tier1\utlmemory.h" />
|
||||
<ClInclude Include="..\tier1\utlvector.h" />
|
||||
@ -552,6 +554,7 @@
|
||||
<ClCompile Include="..\tier1\cvar.cpp" />
|
||||
<ClCompile Include="..\tier1\IConVar.cpp" />
|
||||
<ClCompile Include="..\tier1\NetAdr2.cpp" />
|
||||
<ClCompile Include="..\tier1\splitstring.cpp" />
|
||||
<ClCompile Include="..\tier1\strtools.cpp" />
|
||||
<ClCompile Include="..\tier2\socketcreator.cpp" />
|
||||
<ClCompile Include="..\vpc\IAppSystem.cpp" />
|
||||
|
@ -1191,6 +1191,12 @@
|
||||
<ClInclude Include="..\public\include\worldsize.h">
|
||||
<Filter>sdk\public\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier0\memalloc.h">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\opcodes.cpp">
|
||||
@ -1493,6 +1499,9 @@
|
||||
<ClCompile Include="..\tier1\characterset.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tier1\splitstring.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Dedicated.def" />
|
||||
|
@ -123,6 +123,7 @@
|
||||
<ClCompile Include="..\tier1\cvar.cpp" />
|
||||
<ClCompile Include="..\tier1\IConVar.cpp" />
|
||||
<ClCompile Include="..\tier1\NetAdr2.cpp" />
|
||||
<ClCompile Include="..\tier1\splitstring.cpp" />
|
||||
<ClCompile Include="..\tier1\strtools.cpp" />
|
||||
<ClCompile Include="..\tier2\meshutils.cpp" />
|
||||
<ClCompile Include="..\tier2\renderutils.cpp" />
|
||||
@ -489,6 +490,7 @@
|
||||
<ClInclude Include="..\tier0\dbgflag.h" />
|
||||
<ClInclude Include="..\tier0\fasttimer.h" />
|
||||
<ClInclude Include="..\tier0\jobthread.h" />
|
||||
<ClInclude Include="..\tier0\memalloc.h" />
|
||||
<ClInclude Include="..\tier0\memstd.h" />
|
||||
<ClInclude Include="..\tier0\platform.h" />
|
||||
<ClInclude Include="..\tier0\platform_internal.h" />
|
||||
@ -505,6 +507,7 @@
|
||||
<ClInclude Include="..\tier1\mempool.h" />
|
||||
<ClInclude Include="..\tier1\NetAdr2.h" />
|
||||
<ClInclude Include="..\tier1\strtools.h" />
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h" />
|
||||
<ClInclude Include="..\tier1\utldict.h" />
|
||||
<ClInclude Include="..\tier1\utlmemory.h" />
|
||||
<ClInclude Include="..\tier1\utlvector.h" />
|
||||
|
@ -603,6 +603,9 @@
|
||||
<ClCompile Include="..\tier1\characterset.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tier1\splitstring.cpp">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\client\cdll_engine_int.h">
|
||||
@ -1754,6 +1757,12 @@
|
||||
<ClInclude Include="..\public\include\worldsize.h">
|
||||
<Filter>sdk\public\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier1\utlblockmemory.h">
|
||||
<Filter>sdk\tier1</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tier0\memalloc.h">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\shared\resource\lockedserver.png">
|
||||
|
Loading…
x
Reference in New Issue
Block a user