完全搞定除了皮肤
This commit is contained in:
@@ -1,18 +1,116 @@
|
||||
#include "convar.hpp"
|
||||
|
||||
inline const char** CCommand::ArgV() const
|
||||
{
|
||||
return ArgC() ? (const char**)m_Args.Base() : NULL;
|
||||
inline const char** CCommand::ArgV() const {
|
||||
return ArgC() ? (const char**)m_Args.Base() : NULL;
|
||||
}
|
||||
|
||||
inline const char* CCommand::ArgS() const
|
||||
{
|
||||
return m_nArgv0Size ? (m_ArgSBuffer.Base() + m_nArgv0Size) : "";
|
||||
inline const char* CCommand::ArgS() const {
|
||||
return m_nArgv0Size ? (m_ArgSBuffer.Base() + m_nArgv0Size) : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline const char* CCommand::operator[](int nIndex) const
|
||||
{
|
||||
return Arg(nIndex);
|
||||
inline const char* CCommand::operator[](int nIndex) const {
|
||||
return Arg(nIndex);
|
||||
}
|
||||
static characterset_t s_BreakSet;
|
||||
static bool s_bBuiltBreakSet = false;
|
||||
void CharacterSetBuild(characterset_t* pSetBuffer, const char* pszSetString) {
|
||||
int i = 0;
|
||||
|
||||
// Test our pointers
|
||||
if (!pSetBuffer || !pszSetString) return;
|
||||
|
||||
memset(pSetBuffer->set, 0, sizeof(pSetBuffer->set));
|
||||
|
||||
while (pszSetString[i]) {
|
||||
pSetBuffer->set[static_cast<size_t>(pszSetString[i])] = 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tokenizer class
|
||||
//-----------------------------------------------------------------------------
|
||||
CCommand::CCommand() {
|
||||
if (!s_bBuiltBreakSet) {
|
||||
s_bBuiltBreakSet = true;
|
||||
CharacterSetBuild(&s_BreakSet, "{}()':");
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
CCommand::CCommand(int nArgC, const char** ppArgV) {
|
||||
Assert(nArgC > 0);
|
||||
|
||||
if (!s_bBuiltBreakSet) {
|
||||
s_bBuiltBreakSet = true;
|
||||
CharacterSetBuild(&s_BreakSet, "{}()':");
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
char* pBuf = m_ArgvBuffer.Base();
|
||||
char* pSBuf = m_ArgSBuffer.Base();
|
||||
for (int i = 0; i < nArgC; ++i) {
|
||||
m_Args.AddToTail(pBuf);
|
||||
int nLen = strlen(ppArgV[i]);
|
||||
memcpy(pBuf, ppArgV[i], nLen + 1);
|
||||
if (i == 0) {
|
||||
m_nArgv0Size = nLen;
|
||||
}
|
||||
pBuf += nLen + 1;
|
||||
|
||||
bool bContainsSpace = strchr(ppArgV[i], ' ') != NULL;
|
||||
if (bContainsSpace) {
|
||||
*pSBuf++ = '\"';
|
||||
}
|
||||
memcpy(pSBuf, ppArgV[i], nLen);
|
||||
pSBuf += nLen;
|
||||
if (bContainsSpace) {
|
||||
*pSBuf++ = '\"';
|
||||
}
|
||||
|
||||
if (i != nArgC - 1) {
|
||||
*pSBuf++ = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
bool CCommand::Tokenize(const char* pCommand, characterset_t* pBreakSet) {
|
||||
__debugbreak();
|
||||
return false;
|
||||
}
|
||||
void CCommand::Reset() {
|
||||
m_nArgv0Size = 0;
|
||||
m_ArgSBuffer.RemoveAll();
|
||||
m_ArgvBuffer.RemoveAll();
|
||||
m_Args.RemoveAll();
|
||||
}
|
||||
|
||||
characterset_t* CCommand::DefaultBreakSet() { return &s_BreakSet; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper function to parse arguments to commands.
|
||||
//-----------------------------------------------------------------------------
|
||||
int CCommand::FindArg(const char* pName) const {
|
||||
int nArgC = ArgC();
|
||||
for (int i = 1; i < nArgC; i++) {
|
||||
if (!_stricmp(Arg(i), pName)) return (i + 1) < nArgC ? i + 1 : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CCommand::FindArgInt(const char* pName, int nDefaultVal) const {
|
||||
int idx = FindArg(pName);
|
||||
if (idx != -1)
|
||||
return atoi(m_Args[idx]);
|
||||
else
|
||||
return nDefaultVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default console command autocompletion function
|
||||
//-----------------------------------------------------------------------------
|
||||
int DefaultCompletionFunc(const char* partial,
|
||||
CUtlVector<CUtlString>& commands) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,129 +1,83 @@
|
||||
#pragma once
|
||||
#include "../sdk.h"
|
||||
#include "../tier1/UtlVector.hpp"
|
||||
struct characterset_t
|
||||
{
|
||||
char set[256];
|
||||
struct characterset_t {
|
||||
char set[256];
|
||||
};
|
||||
class ConCommandBase
|
||||
{
|
||||
friend class CCvar;
|
||||
friend class ConCommand;
|
||||
class ConCommandBase {
|
||||
friend class CCvar;
|
||||
friend class ConCommand;
|
||||
|
||||
protected:
|
||||
ConCommandBase(void);
|
||||
public:
|
||||
protected:
|
||||
ConCommandBase(void);
|
||||
|
||||
~ConCommandBase(void);
|
||||
// Check flag
|
||||
bool IsFlagSet(int64_t flag) const;
|
||||
// Set flag
|
||||
void AddFlags(int64_t flags);
|
||||
// Clear flag
|
||||
void RemoveFlags(int64_t flags);
|
||||
public:
|
||||
~ConCommandBase(void);
|
||||
// Check flag
|
||||
bool IsFlagSet(int64_t flag) const;
|
||||
// Set flag
|
||||
void AddFlags(int64_t flags);
|
||||
// Clear flag
|
||||
void RemoveFlags(int64_t flags);
|
||||
|
||||
int64_t GetFlags() const;
|
||||
int64_t GetFlags() const;
|
||||
|
||||
// Return name of cvar
|
||||
const char* GetName(void) const;
|
||||
// Return name of cvar
|
||||
const char* GetName(void) const;
|
||||
|
||||
// Return help text for cvar
|
||||
const char* GetHelpText(void) const;
|
||||
// Return help text for cvar
|
||||
const char* GetHelpText(void) const;
|
||||
|
||||
private:
|
||||
// Static data
|
||||
const char* m_pszName;
|
||||
const char* m_pszHelpString;
|
||||
private:
|
||||
// Static data
|
||||
const char* m_pszName;
|
||||
const char* m_pszHelpString;
|
||||
|
||||
// ConVar flags
|
||||
int64_t m_nFlags;
|
||||
// ConVar flags
|
||||
int64_t m_nFlags;
|
||||
};
|
||||
|
||||
template< class T, size_t SIZE, class I = int >
|
||||
class CUtlMemoryFixedGrowable : public CUtlMemory< T, I >
|
||||
{
|
||||
typedef CUtlMemory< T, I > BaseClass;
|
||||
class CCommand {
|
||||
public:
|
||||
CCommand();
|
||||
CCommand(int nArgC, const char** ppArgV);
|
||||
virtual bool Tokenize(const char* pCommand,
|
||||
characterset_t* pBreakSet = NULL);
|
||||
virtual void Reset();
|
||||
|
||||
public:
|
||||
CUtlMemoryFixedGrowable(int nGrowSize = 0, int nInitSize = SIZE) : BaseClass(m_pFixedMemory, SIZE)
|
||||
{
|
||||
Assert(nInitSize == 0 || nInitSize == SIZE);
|
||||
}
|
||||
int ArgC() const { return m_Args.Count(); }
|
||||
const char** ArgV() const;
|
||||
const char* ArgS()
|
||||
const; // All args that occur after the 0th arg, in string form
|
||||
const char* GetCommandString() const {
|
||||
return ArgC() ? m_ArgSBuffer.Base() : "";
|
||||
}
|
||||
const char* operator[](int nIndex) const; // Gets at arguments
|
||||
const char* Arg(int nIndex) const {
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if (nIndex < 0 || nIndex >= ArgC()) return "";
|
||||
return m_Args[nIndex];
|
||||
}
|
||||
|
||||
void EnsureCapacity(int num)
|
||||
{
|
||||
if (CUtlMemory<T>::m_nAllocationCount >= num)
|
||||
return;
|
||||
// Helper functions to parse arguments to commands.
|
||||
//
|
||||
// Returns index of argument, or -1 if no such argument.
|
||||
int FindArg(const char* pName) const;
|
||||
|
||||
BaseClass::EnsureCapacity(num);
|
||||
}
|
||||
int FindArgInt(const char* pName, int nDefaultVal) const;
|
||||
|
||||
private:
|
||||
T m_pFixedMemory[SIZE];
|
||||
static int MaxCommandLength() { return COMMAND_MAX_LENGTH - 1; }
|
||||
static characterset_t* DefaultBreakSet();
|
||||
|
||||
private:
|
||||
enum {
|
||||
COMMAND_MAX_ARGC = 64,
|
||||
COMMAND_MAX_LENGTH = 512,
|
||||
};
|
||||
|
||||
int m_nArgv0Size;
|
||||
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgSBuffer;
|
||||
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgvBuffer;
|
||||
CUtlVectorFixedGrowable<char*, COMMAND_MAX_ARGC> m_Args;
|
||||
};
|
||||
|
||||
template< class T, size_t MAX_SIZE >
|
||||
class CUtlVectorFixedGrowable : public CUtlVector< T, CUtlMemoryFixedGrowable<T, MAX_SIZE > >
|
||||
{
|
||||
typedef CUtlVector< T, CUtlMemoryFixedGrowable<T, MAX_SIZE > > BaseClass;
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlVectorFixedGrowable(int growSize = 0) : BaseClass(growSize, MAX_SIZE) {}
|
||||
};
|
||||
|
||||
|
||||
class CCommand
|
||||
{
|
||||
public:
|
||||
CCommand();
|
||||
CCommand(int nArgC, const char** ppArgV);
|
||||
virtual bool Tokenize(const char* pCommand, characterset_t* pBreakSet = NULL);
|
||||
virtual void Reset();
|
||||
|
||||
int ArgC() const {
|
||||
return m_Args.Count();
|
||||
}
|
||||
const char** ArgV() const;
|
||||
const char* ArgS() const; // All args that occur after the 0th arg, in string form
|
||||
const char* GetCommandString() const
|
||||
{
|
||||
return ArgC() ? m_ArgSBuffer.Base() : "";
|
||||
}
|
||||
const char* operator[](int nIndex) const; // Gets at arguments
|
||||
const char* Arg(int nIndex) const {
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if (nIndex < 0 || nIndex >= ArgC())
|
||||
return "";
|
||||
return m_Args[nIndex];
|
||||
|
||||
}
|
||||
|
||||
// Helper functions to parse arguments to commands.
|
||||
//
|
||||
// Returns index of argument, or -1 if no such argument.
|
||||
int FindArg(const char* pName) const;
|
||||
|
||||
int FindArgInt(const char* pName, int nDefaultVal) const;
|
||||
|
||||
static int MaxCommandLength()
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
static characterset_t* DefaultBreakSet();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
COMMAND_MAX_ARGC = 64,
|
||||
COMMAND_MAX_LENGTH = 512,
|
||||
};
|
||||
|
||||
int m_nArgv0Size;
|
||||
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgSBuffer;
|
||||
CUtlVectorFixedGrowable<char, COMMAND_MAX_LENGTH> m_ArgvBuffer;
|
||||
CUtlVectorFixedGrowable<char*, COMMAND_MAX_ARGC> m_Args;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef BITVEC_H
|
||||
#define BITVEC_H
|
||||
#ifdef _WIN32
|
||||
|
||||
17
csgo2/sdk/public/irecipientfilter.h
Normal file
17
csgo2/sdk/public/irecipientfilter.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "eiface.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic interface for routing messages to users
|
||||
//-----------------------------------------------------------------------------
|
||||
class IRecipientFilter
|
||||
{
|
||||
public:
|
||||
virtual ~IRecipientFilter() {}
|
||||
|
||||
virtual bool IsReliable(void) const = 0;
|
||||
virtual bool IsInitMessage(void) const = 0;
|
||||
|
||||
virtual int GetRecipientCount(void) const = 0;
|
||||
virtual CEntityIndex GetRecipientIndex(int slot) const = 0;
|
||||
};
|
||||
62
csgo2/sdk/public/recipientfilters.h
Normal file
62
csgo2/sdk/public/recipientfilters.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "../sdk.h"
|
||||
|
||||
class CSingleRecipientFilter : public IRecipientFilter
|
||||
{
|
||||
public:
|
||||
CSingleRecipientFilter(int iRecipient, bool bReliable = true, bool bInitMessage = false) :
|
||||
m_iRecipient(iRecipient), m_bReliable(bReliable), m_bInitMessage(bInitMessage) {}
|
||||
|
||||
~CSingleRecipientFilter() override {}
|
||||
|
||||
bool IsReliable(void) const override { return m_bReliable; }
|
||||
|
||||
bool IsInitMessage(void) const override { return m_bInitMessage; }
|
||||
|
||||
int GetRecipientCount(void) const override { return 1; }
|
||||
|
||||
CEntityIndex GetRecipientIndex(int slot) const override { return CEntityIndex(m_iRecipient); }
|
||||
|
||||
private:
|
||||
bool m_bReliable;
|
||||
bool m_bInitMessage;
|
||||
int m_iRecipient;
|
||||
};
|
||||
|
||||
class CCopyRecipientFilter : public IRecipientFilter
|
||||
{
|
||||
public:
|
||||
CCopyRecipientFilter(IRecipientFilter *source, int iExcept)
|
||||
{
|
||||
m_bReliable = source->IsReliable();
|
||||
m_bInitMessage = source->IsInitMessage();
|
||||
m_Recipients.RemoveAll();
|
||||
|
||||
for (int i = 0; i < source->GetRecipientCount(); i++)
|
||||
{
|
||||
if (source->GetRecipientIndex(i).Get() != iExcept)
|
||||
m_Recipients.AddToTail(source->GetRecipientIndex(i));
|
||||
}
|
||||
}
|
||||
|
||||
~CCopyRecipientFilter() override {}
|
||||
|
||||
bool IsReliable(void) const override { return m_bReliable; }
|
||||
|
||||
bool IsInitMessage(void) const override { return m_bInitMessage; }
|
||||
|
||||
int GetRecipientCount(void) const override { return m_Recipients.Count(); }
|
||||
|
||||
CEntityIndex GetRecipientIndex(int slot) const override
|
||||
{
|
||||
if (slot < 0 || slot >= GetRecipientCount())
|
||||
return CEntityIndex(-1);
|
||||
|
||||
return m_Recipients[slot];
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bReliable;
|
||||
bool m_bInitMessage;
|
||||
CUtlVectorFixed<CEntityIndex, 64> m_Recipients;
|
||||
};
|
||||
@@ -1,11 +1,3 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef UTLRBTREE_H
|
||||
#define UTLRBTREE_H
|
||||
|
||||
|
||||
118
csgo2/sdk/sdk.h
118
csgo2/sdk/sdk.h
@@ -1,61 +1,109 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <shared_mutex>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <limits.h>
|
||||
#include <cstdint>
|
||||
#define CORRECT_PATH_SEPARATOR '\\'
|
||||
#define CORRECT_PATH_SEPARATOR_S "\\"
|
||||
#define INCORRECT_PATH_SEPARATOR '/'
|
||||
#define INCORRECT_PATH_SEPARATOR_S "/"
|
||||
#define FMTFUNCTION( a, b )
|
||||
enum EStringConvertErrorPolicy
|
||||
{
|
||||
_STRINGCONVERTFLAG_SKIP = 1,
|
||||
_STRINGCONVERTFLAG_FAIL = 2,
|
||||
_STRINGCONVERTFLAG_ASSERT = 4,
|
||||
#define FMTFUNCTION(a, b)
|
||||
enum EStringConvertErrorPolicy {
|
||||
_STRINGCONVERTFLAG_SKIP = 1,
|
||||
_STRINGCONVERTFLAG_FAIL = 2,
|
||||
_STRINGCONVERTFLAG_ASSERT = 4,
|
||||
|
||||
STRINGCONVERT_REPLACE = 0,
|
||||
STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP,
|
||||
STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL,
|
||||
STRINGCONVERT_REPLACE = 0,
|
||||
STRINGCONVERT_SKIP = _STRINGCONVERTFLAG_SKIP,
|
||||
STRINGCONVERT_FAIL = _STRINGCONVERTFLAG_FAIL,
|
||||
|
||||
STRINGCONVERT_ASSERT_REPLACE = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE,
|
||||
STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP,
|
||||
STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL,
|
||||
STRINGCONVERT_ASSERT_REPLACE =
|
||||
_STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_REPLACE,
|
||||
STRINGCONVERT_ASSERT_SKIP = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_SKIP,
|
||||
STRINGCONVERT_ASSERT_FAIL = _STRINGCONVERTFLAG_ASSERT + STRINGCONVERT_FAIL,
|
||||
};
|
||||
|
||||
enum EUniverse
|
||||
{
|
||||
k_EUniverseInvalid = 0,
|
||||
k_EUniversePublic = 1,
|
||||
k_EUniverseBeta = 2,
|
||||
k_EUniverseInternal = 3,
|
||||
k_EUniverseDev = 4,
|
||||
// k_EUniverseRC = 5, // no such universe anymore
|
||||
k_EUniverseMax
|
||||
enum EUniverse {
|
||||
k_EUniverseInvalid = 0,
|
||||
k_EUniversePublic = 1,
|
||||
k_EUniverseBeta = 2,
|
||||
k_EUniverseInternal = 3,
|
||||
k_EUniverseDev = 4,
|
||||
// k_EUniverseRC = 5, // no such universe anymore
|
||||
k_EUniverseMax
|
||||
};
|
||||
|
||||
#define Plat_FastMemset memset
|
||||
#define Plat_FastMemcpy memcpy
|
||||
#define RESTRICT __restrict
|
||||
#define RESTRICT_FUNC __declspec(restrict)
|
||||
#define FORCEINLINE_TEMPLATE __forceinline
|
||||
#define RESTRICT __restrict
|
||||
#define RESTRICT_FUNC __declspec(restrict)
|
||||
#define FORCEINLINE_TEMPLATE __forceinline
|
||||
#define PAD_NUMBER(number, boundary) \
|
||||
( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
|
||||
(((number) + ((boundary)-1)) / (boundary)) * (boundary)
|
||||
typedef __int64 intp;
|
||||
#ifndef Assert
|
||||
typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) &&
|
||||
// sizeof(intp) >= sizeof(void *)
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
typedef __int16 int16;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef __int32 int32;
|
||||
typedef unsigned __int32 uint32;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned int uint;
|
||||
#define Assert
|
||||
#endif // !Assert
|
||||
template <class T>
|
||||
inline T* Construct(T* pMemory)
|
||||
{
|
||||
return ::new(pMemory) T;
|
||||
inline T* Construct(T* pMemory) {
|
||||
return ::new (pMemory) T;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void Destruct(T* pMemory)
|
||||
{
|
||||
pMemory->~T();
|
||||
inline void Destruct(T* pMemory) {
|
||||
pMemory->~T();
|
||||
|
||||
#ifdef _DEBUG
|
||||
memset((void*)pMemory, 0xDD, sizeof(T));
|
||||
memset((void*)pMemory, 0xDD, sizeof(T));
|
||||
#endif
|
||||
}
|
||||
#include "../head.h"
|
||||
template <typename T>
|
||||
inline T AlignValue(T val, uintptr_t alignment) {
|
||||
return (T)(((uintptr_t)val + alignment - 1) & ~(alignment - 1));
|
||||
}
|
||||
|
||||
#include "player/playerslot.h"
|
||||
|
||||
#include "public/mathlib.h"
|
||||
#include "public/string_t.h"
|
||||
#include "tier1/UtlMemory.hpp"
|
||||
#include "tier1/utlfixedmemory.h"
|
||||
#include "tier1/utlblockmemory.h"
|
||||
#include "tier1/UtlString.hpp"
|
||||
#include "tier1/UtlVector.hpp"
|
||||
#include "tier1/bufferstring.h"
|
||||
#include "tier1/cbyteswap.h"
|
||||
|
||||
#include "tier1/utlbuffer.h"
|
||||
|
||||
#include "public/eiface.h"
|
||||
#include "public/bitvec.h"
|
||||
#include "public/iserver.h"
|
||||
#include "public/utlrbtree.h"
|
||||
#include "public/utlmap.h"
|
||||
#include "public/IRecipientFilter.h"
|
||||
#include "public/recipientfilters.h"
|
||||
#include "interfaces/interfaces.h"
|
||||
#include "gameevent/IGameEvent.h"
|
||||
#include "convar/convar.hpp"
|
||||
|
||||
#include "gameevent/IGameEvent.h"
|
||||
#include "tier1/bufferstring.h"
|
||||
#include "public/eiface.h"
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
#define UTLMEMORY_TRACK_ALLOC()
|
||||
#define MEM_ALLOC_CREDIT_CLASS()
|
||||
#define UTLMEMORY_TRACK_FREE()
|
||||
template< class T, class I = int >
|
||||
class CUtlMemory
|
||||
{
|
||||
public:
|
||||
#define Assert
|
||||
|
||||
template <class T, class I = int>
|
||||
class CUtlMemory {
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlMemory(int nGrowSize = 0, int nInitSize = 0);
|
||||
CUtlMemory(T* pMemory, int numElements);
|
||||
@@ -17,20 +18,26 @@ public:
|
||||
// Set the size by which the memory grows
|
||||
void Init(int nGrowSize = 0, int nInitSize = 0);
|
||||
|
||||
class Iterator_t
|
||||
{
|
||||
public:
|
||||
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 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
|
||||
@@ -41,7 +48,7 @@ public:
|
||||
|
||||
bool IsIdxValid(I i) const;
|
||||
|
||||
static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT
|
||||
static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT
|
||||
static I InvalidIndex() { return INVALID_INDEX; }
|
||||
|
||||
T* Base();
|
||||
@@ -49,11 +56,11 @@ public:
|
||||
|
||||
void SetExternalBuffer(T* pMemory, int numElements);
|
||||
void SetExternalBuffer(const T* pMemory, int numElements);
|
||||
void AssumeMemory(T *pMemory, int nSize);
|
||||
void AssumeMemory(T* pMemory, int nSize);
|
||||
T* Detach();
|
||||
void *DetachMemory();
|
||||
void* DetachMemory();
|
||||
|
||||
void Swap(CUtlMemory< T, I > &mem);
|
||||
void Swap(CUtlMemory<T, I>& mem);
|
||||
void ConvertToGrowableMemory(int nGrowSize);
|
||||
int NumAllocated() const;
|
||||
int Count() const;
|
||||
@@ -65,14 +72,10 @@ public:
|
||||
bool IsReadOnly() const;
|
||||
void SetGrowSize(int size);
|
||||
|
||||
protected:
|
||||
void ValidateGrowSize()
|
||||
{
|
||||
protected:
|
||||
void ValidateGrowSize() {}
|
||||
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
EXTERNAL_BUFFER_MARKER = -1,
|
||||
EXTERNAL_CONST_BUFFER_MARKER = -2,
|
||||
};
|
||||
@@ -86,48 +89,45 @@ protected:
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T, I>::CUtlMemory(int nGrowSize, int nInitAllocationCount) : m_pMemory(0),
|
||||
m_nAllocationCount(nInitAllocationCount), m_nGrowSize(nGrowSize)
|
||||
{
|
||||
template <class T, class I>
|
||||
CUtlMemory<T, I>::CUtlMemory(int nGrowSize, int nInitAllocationCount)
|
||||
: m_pMemory(0),
|
||||
m_nAllocationCount(nInitAllocationCount),
|
||||
m_nGrowSize(nGrowSize) {
|
||||
ValidateGrowSize();
|
||||
if(m_nAllocationCount) {
|
||||
if (m_nAllocationCount) {
|
||||
m_pMemory = (T*)new unsigned char[m_nAllocationCount * sizeof(T)];
|
||||
//m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
|
||||
// m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T, I>::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory),
|
||||
m_nAllocationCount(numElements)
|
||||
{
|
||||
template <class T, class I>
|
||||
CUtlMemory<T, I>::CUtlMemory(T* pMemory, int numElements)
|
||||
: m_pMemory(pMemory), m_nAllocationCount(numElements) {
|
||||
// Special marker indicating externally supplied modifyable memory
|
||||
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T, I>::CUtlMemory(const T* pMemory, int numElements) : m_pMemory((T*)pMemory),
|
||||
m_nAllocationCount(numElements)
|
||||
{
|
||||
template <class T, class I>
|
||||
CUtlMemory<T, I>::CUtlMemory(const T* pMemory, int numElements)
|
||||
: m_pMemory((T*)pMemory), m_nAllocationCount(numElements) {
|
||||
// Special marker indicating externally supplied modifyable memory
|
||||
m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
CUtlMemory<T, I>::~CUtlMemory()
|
||||
{
|
||||
template <class T, class I>
|
||||
CUtlMemory<T, I>::~CUtlMemory() {
|
||||
Purge();
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/) {
|
||||
Purge();
|
||||
|
||||
m_nGrowSize = nGrowSize;
|
||||
m_nAllocationCount = nInitSize;
|
||||
ValidateGrowSize();
|
||||
if(m_nAllocationCount) {
|
||||
if (m_nAllocationCount) {
|
||||
UTLMEMORY_TRACK_ALLOC();
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
|
||||
@@ -137,28 +137,24 @@ void CUtlMemory<T, I>::Init(int nGrowSize /*= 0*/, int nInitSize /*= 0*/)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fast swap
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Swap(CUtlMemory<T, I> &mem)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::Swap(CUtlMemory<T, I>& mem) {
|
||||
V_swap(m_nGrowSize, mem.m_nGrowSize);
|
||||
V_swap(m_pMemory, mem.m_pMemory);
|
||||
V_swap(m_nAllocationCount, mem.m_nAllocationCount);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Switches the buffer from an external memory buffer to a reallocatable buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize)
|
||||
{
|
||||
if(!IsExternallyAllocated())
|
||||
return;
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize) {
|
||||
if (!IsExternallyAllocated()) return;
|
||||
|
||||
m_nGrowSize = nGrowSize;
|
||||
if(m_nAllocationCount) {
|
||||
if (m_nAllocationCount) {
|
||||
int nNumBytes = m_nAllocationCount * sizeof(T);
|
||||
T *pMemory = (T*)malloc(nNumBytes);
|
||||
T* pMemory = (T*)malloc(nNumBytes);
|
||||
memcpy(pMemory, m_pMemory, nNumBytes);
|
||||
m_pMemory = pMemory;
|
||||
} else {
|
||||
@@ -166,13 +162,11 @@ void CUtlMemory<T, I>::ConvertToGrowableMemory(int nGrowSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attaches the buffer to external memory....
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements) {
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
@@ -183,9 +177,8 @@ void CUtlMemory<T, I>::SetExternalBuffer(T* pMemory, int numElements)
|
||||
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements) {
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
@@ -196,9 +189,8 @@ void CUtlMemory<T, I>::SetExternalBuffer(const T* pMemory, int numElements)
|
||||
m_nGrowSize = EXTERNAL_CONST_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements) {
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
@@ -207,121 +199,100 @@ void CUtlMemory<T, I>::AssumeMemory(T* pMemory, int numElements)
|
||||
m_nAllocationCount = numElements;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void *CUtlMemory<T, I>::DetachMemory()
|
||||
{
|
||||
if(IsExternallyAllocated())
|
||||
return NULL;
|
||||
template <class T, class I>
|
||||
void* CUtlMemory<T, I>::DetachMemory() {
|
||||
if (IsExternallyAllocated()) return NULL;
|
||||
|
||||
void *pMemory = m_pMemory;
|
||||
void* pMemory = m_pMemory;
|
||||
m_pMemory = 0;
|
||||
m_nAllocationCount = 0;
|
||||
return pMemory;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline T* CUtlMemory<T, I>::Detach()
|
||||
{
|
||||
template <class T, class I>
|
||||
inline T* CUtlMemory<T, I>::Detach() {
|
||||
return (T*)DetachMemory();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element access
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline T& CUtlMemory<T, I>::operator[](I i)
|
||||
{
|
||||
template <class T, class I>
|
||||
inline T& CUtlMemory<T, I>::operator[](I i) {
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlMemory<T, I>::operator[](I i) const
|
||||
{
|
||||
template <class T, class I>
|
||||
inline const T& CUtlMemory<T, I>::operator[](I i) const {
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline T& CUtlMemory<T, I>::Element(I i)
|
||||
{
|
||||
template <class T, class I>
|
||||
inline T& CUtlMemory<T, I>::Element(I i) {
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T& CUtlMemory<T, I>::Element(I i) const
|
||||
{
|
||||
template <class T, class I>
|
||||
inline const T& CUtlMemory<T, I>::Element(I i) const {
|
||||
return m_pMemory[i];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// is the memory externally allocated?
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
bool CUtlMemory<T, I>::IsExternallyAllocated() const
|
||||
{
|
||||
template <class T, class I>
|
||||
bool CUtlMemory<T, I>::IsExternallyAllocated() const {
|
||||
return (m_nGrowSize < 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// is the memory read only?
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
bool CUtlMemory<T, I>::IsReadOnly() const
|
||||
{
|
||||
template <class T, class I>
|
||||
bool CUtlMemory<T, I>::IsReadOnly() const {
|
||||
return (m_nGrowSize == EXTERNAL_CONST_BUFFER_MARKER);
|
||||
}
|
||||
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::SetGrowSize(int nSize)
|
||||
{
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::SetGrowSize(int nSize) {
|
||||
m_nGrowSize = nSize;
|
||||
ValidateGrowSize();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets the base address (can change when adding elements!)
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline T* CUtlMemory<T, I>::Base()
|
||||
{
|
||||
template <class T, class I>
|
||||
inline T* CUtlMemory<T, I>::Base() {
|
||||
return m_pMemory;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline const T *CUtlMemory<T, I>::Base() const
|
||||
{
|
||||
template <class T, class I>
|
||||
inline const T* CUtlMemory<T, I>::Base() const {
|
||||
return m_pMemory;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Size
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline int CUtlMemory<T, I>::NumAllocated() const
|
||||
{
|
||||
template <class T, class I>
|
||||
inline int CUtlMemory<T, I>::NumAllocated() const {
|
||||
return m_nAllocationCount;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
inline int CUtlMemory<T, I>::Count() const
|
||||
{
|
||||
template <class T, class I>
|
||||
inline int CUtlMemory<T, I>::Count() const {
|
||||
return m_nAllocationCount;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is element index valid?
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline bool CUtlMemory<T, I>::IsIdxValid(I i) const
|
||||
{
|
||||
// GCC warns if I is an unsigned type and we do a ">= 0" against it (since the comparison is always 0).
|
||||
// We Get the warning even if we cast inside the expression. It only goes away if we assign to another variable.
|
||||
template <class T, class I>
|
||||
inline bool CUtlMemory<T, I>::IsIdxValid(I i) const {
|
||||
// GCC warns if I is an unsigned type and we do a ">= 0" against it (since
|
||||
// the comparison is always 0). We Get the warning even if we cast inside
|
||||
// the expression. It only goes away if we assign to another variable.
|
||||
long x = i;
|
||||
return (x >= 0) && (x < m_nAllocationCount);
|
||||
}
|
||||
@@ -329,22 +300,22 @@ inline bool CUtlMemory<T, I>::IsIdxValid(I i) const
|
||||
//-----------------------------------------------------------------------------
|
||||
// Grows the memory
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize, int nNewSize, int nBytesItem)
|
||||
{
|
||||
if(nGrowSize) {
|
||||
inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize,
|
||||
int nNewSize, int nBytesItem) {
|
||||
if (nGrowSize) {
|
||||
nAllocationCount = ((1 + ((nNewSize - 1) / nGrowSize)) * nGrowSize);
|
||||
} else {
|
||||
if(!nAllocationCount) {
|
||||
if (!nAllocationCount) {
|
||||
// Compute an allocation which is at least as big as a cache line...
|
||||
nAllocationCount = (31 + nBytesItem) / nBytesItem;
|
||||
}
|
||||
|
||||
while(nAllocationCount < nNewSize) {
|
||||
while (nAllocationCount < nNewSize) {
|
||||
#ifndef _X360
|
||||
nAllocationCount *= 2;
|
||||
#else
|
||||
int nNewAllocationCount = (nAllocationCount * 9) / 8; // 12.5 %
|
||||
if(nNewAllocationCount > nAllocationCount)
|
||||
int nNewAllocationCount = (nAllocationCount * 9) / 8; // 12.5 %
|
||||
if (nNewAllocationCount > nAllocationCount)
|
||||
nAllocationCount = nNewAllocationCount;
|
||||
else
|
||||
nAllocationCount *= 2;
|
||||
@@ -355,40 +326,43 @@ inline int UtlMemory_CalcNewAllocationCount(int nAllocationCount, int nGrowSize,
|
||||
return nAllocationCount;
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Grow(int num)
|
||||
{
|
||||
if(IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::Grow(int num) {
|
||||
if (IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto oldAllocationCount = m_nAllocationCount;
|
||||
// Make sure we have at least numallocated + num allocations.
|
||||
// Use the grow rules specified for this memory (in m_nGrowSize)
|
||||
int nAllocationRequested = m_nAllocationCount + num;
|
||||
|
||||
int nNewAllocationCount = UtlMemory_CalcNewAllocationCount(m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T));
|
||||
int nNewAllocationCount = UtlMemory_CalcNewAllocationCount(
|
||||
m_nAllocationCount, m_nGrowSize, nAllocationRequested, sizeof(T));
|
||||
|
||||
// if m_nAllocationRequested wraps index type I, recalculate
|
||||
if((int)(I)nNewAllocationCount < nAllocationRequested) {
|
||||
if((int)(I)nNewAllocationCount == 0 && (int)(I)(nNewAllocationCount - 1) >= nAllocationRequested) {
|
||||
--nNewAllocationCount; // deal w/ the common case of m_nAllocationCount == MAX_USHORT + 1
|
||||
if ((int)(I)nNewAllocationCount < nAllocationRequested) {
|
||||
if ((int)(I)nNewAllocationCount == 0 &&
|
||||
(int)(I)(nNewAllocationCount - 1) >= nAllocationRequested) {
|
||||
--nNewAllocationCount; // deal w/ the common case of
|
||||
// m_nAllocationCount == MAX_USHORT + 1
|
||||
} else {
|
||||
if((int)(I)nAllocationRequested != nAllocationRequested) {
|
||||
// we've been asked to grow memory to a size s.t. the index type can't address the requested amount of memory
|
||||
if ((int)(I)nAllocationRequested != nAllocationRequested) {
|
||||
// we've been asked to grow memory to a size s.t. the index type
|
||||
// can't address the requested amount of memory
|
||||
return;
|
||||
}
|
||||
while((int)(I)nNewAllocationCount < nAllocationRequested) {
|
||||
nNewAllocationCount = (nNewAllocationCount + nAllocationRequested) / 2;
|
||||
while ((int)(I)nNewAllocationCount < nAllocationRequested) {
|
||||
nNewAllocationCount =
|
||||
(nNewAllocationCount + nAllocationRequested) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_nAllocationCount = nNewAllocationCount;
|
||||
|
||||
if(m_pMemory) {
|
||||
if (m_pMemory) {
|
||||
auto ptr = new unsigned char[m_nAllocationCount * sizeof(T)];
|
||||
|
||||
memcpy(ptr, m_pMemory, oldAllocationCount * sizeof(T));
|
||||
@@ -398,38 +372,33 @@ void CUtlMemory<T, I>::Grow(int num)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we've got at least this much memory
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
inline void CUtlMemory<T, I>::EnsureCapacity(int num)
|
||||
{
|
||||
if(m_nAllocationCount >= num)
|
||||
return;
|
||||
template <class T, class I>
|
||||
inline void CUtlMemory<T, I>::EnsureCapacity(int num) {
|
||||
if (m_nAllocationCount >= num) return;
|
||||
|
||||
if(IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
if (IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
return;
|
||||
}
|
||||
m_nAllocationCount = num;
|
||||
|
||||
if(m_pMemory) {
|
||||
if (m_pMemory) {
|
||||
m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
|
||||
} else {
|
||||
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Purge()
|
||||
{
|
||||
if(!IsExternallyAllocated()) {
|
||||
if(m_pMemory) {
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::Purge() {
|
||||
if (!IsExternallyAllocated()) {
|
||||
if (m_pMemory) {
|
||||
free((void*)m_pMemory);
|
||||
m_pMemory = 0;
|
||||
}
|
||||
@@ -437,33 +406,32 @@ void CUtlMemory<T, I>::Purge()
|
||||
}
|
||||
}
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Purge(int numElements)
|
||||
{
|
||||
|
||||
if(numElements > m_nAllocationCount) {
|
||||
template <class T, class I>
|
||||
void CUtlMemory<T, I>::Purge(int numElements) {
|
||||
if (numElements > m_nAllocationCount) {
|
||||
// Ensure this isn't a grow request in disguise.
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have zero elements, simply do a purge:
|
||||
if(numElements == 0) {
|
||||
if (numElements == 0) {
|
||||
Purge();
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsExternallyAllocated()) {
|
||||
// Can't shrink a buffer whose memory was externally allocated, fail silently like purge
|
||||
if (IsExternallyAllocated()) {
|
||||
// Can't shrink a buffer whose memory was externally allocated, fail
|
||||
// silently like purge
|
||||
return;
|
||||
}
|
||||
|
||||
// If the number of elements is the same as the allocation count, we are done.
|
||||
if(numElements == m_nAllocationCount) {
|
||||
// If the number of elements is the same as the allocation count, we are
|
||||
// done.
|
||||
if (numElements == m_nAllocationCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(!m_pMemory) {
|
||||
if (!m_pMemory) {
|
||||
// Allocation count is non zero, but memory is null.
|
||||
assert(m_pMemory);
|
||||
return;
|
||||
@@ -476,10 +444,9 @@ void CUtlMemory<T, I>::Purge(int numElements)
|
||||
// The CUtlMemory class:
|
||||
// A growable memory class which doubles in size by default.
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
class CUtlMemoryAligned : public CUtlMemory<T>
|
||||
{
|
||||
public:
|
||||
template <class T, int nAlignment>
|
||||
class CUtlMemoryAligned : public CUtlMemory<T> {
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlMemoryAligned(int nGrowSize = 0, int nInitSize = 0);
|
||||
CUtlMemoryAligned(T* pMemory, int numElements);
|
||||
@@ -499,31 +466,29 @@ public:
|
||||
// Memory deallocation
|
||||
void Purge();
|
||||
|
||||
// Purge all but the given number of elements (NOT IMPLEMENTED IN CUtlMemoryAligned)
|
||||
// Purge all but the given number of elements (NOT IMPLEMENTED IN
|
||||
// CUtlMemoryAligned)
|
||||
void Purge(int numElements) { __debugbreak(); }
|
||||
|
||||
private:
|
||||
void *Align(const void *pAddr);
|
||||
private:
|
||||
void* Align(const void* pAddr);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Aligns a pointer
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
void *CUtlMemoryAligned<T, nAlignment>::Align(const void *pAddr)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
void* CUtlMemoryAligned<T, nAlignment>::Align(const void* pAddr) {
|
||||
size_t nAlignmentMask = nAlignment - 1;
|
||||
return (void*)(((size_t)pAddr + nAlignmentMask) & (~nAlignmentMask));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize, int nInitAllocationCount)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize,
|
||||
int nInitAllocationCount) {
|
||||
CUtlMemory<T>::m_pMemory = 0;
|
||||
CUtlMemory<T>::m_nAllocationCount = nInitAllocationCount;
|
||||
CUtlMemory<T>::m_nGrowSize = nGrowSize;
|
||||
@@ -531,78 +496,83 @@ CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(int nGrowSize, int nInitAllo
|
||||
|
||||
// Alignment must be a power of two
|
||||
COMPILE_TIME_ASSERT((nAlignment & (nAlignment - 1)) == 0);
|
||||
if(CUtlMemory<T>::m_nAllocationCount) {
|
||||
if (CUtlMemory<T>::m_nAllocationCount) {
|
||||
UTLMEMORY_TRACK_ALLOC();
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
CUtlMemory<T>::m_pMemory = (T*)_aligned_malloc(nInitAllocationCount * sizeof(T), nAlignment);
|
||||
CUtlMemory<T>::m_pMemory =
|
||||
(T*)_aligned_malloc(nInitAllocationCount * sizeof(T), nAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(T* pMemory,
|
||||
int numElements) {
|
||||
// Special marker indicating externally supplied memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
|
||||
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount =
|
||||
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
|
||||
sizeof(T);
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(const T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned(const T* pMemory,
|
||||
int numElements) {
|
||||
// Special marker indicating externally supplied memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
|
||||
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount =
|
||||
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
|
||||
sizeof(T);
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
CUtlMemoryAligned<T, nAlignment>::~CUtlMemoryAligned()
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
CUtlMemoryAligned<T, nAlignment>::~CUtlMemoryAligned() {
|
||||
Purge();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attaches the buffer to external memory....
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(T* pMemory,
|
||||
int numElements) {
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
|
||||
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount =
|
||||
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
|
||||
sizeof(T);
|
||||
|
||||
// Indicate that we don't own the memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(const T* pMemory, int numElements)
|
||||
{
|
||||
template <class T, int nAlignment>
|
||||
void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer(const T* pMemory,
|
||||
int numElements) {
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align(pMemory);
|
||||
CUtlMemory<T>::m_nAllocationCount = ((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount =
|
||||
((int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory) /
|
||||
sizeof(T);
|
||||
|
||||
// Indicate that we don't own the memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Grows the memory
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
void CUtlMemoryAligned<T, nAlignment>::Grow(int num)
|
||||
{
|
||||
if(this->IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
template <class T, int nAlignment>
|
||||
void CUtlMemoryAligned<T, nAlignment>::Grow(int num) {
|
||||
if (this->IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -612,31 +582,33 @@ void CUtlMemoryAligned<T, nAlignment>::Grow(int num)
|
||||
// Use the grow rules specified for this memory (in m_nGrowSize)
|
||||
int nAllocationRequested = CUtlMemory<T>::m_nAllocationCount + num;
|
||||
|
||||
CUtlMemory<T>::m_nAllocationCount = UtlMemory_CalcNewAllocationCount(CUtlMemory<T>::m_nAllocationCount, CUtlMemory<T>::m_nGrowSize, nAllocationRequested, sizeof(T));
|
||||
CUtlMemory<T>::m_nAllocationCount = UtlMemory_CalcNewAllocationCount(
|
||||
CUtlMemory<T>::m_nAllocationCount, CUtlMemory<T>::m_nGrowSize,
|
||||
nAllocationRequested, sizeof(T));
|
||||
|
||||
UTLMEMORY_TRACK_ALLOC();
|
||||
|
||||
if(CUtlMemory<T>::m_pMemory) {
|
||||
if (CUtlMemory<T>::m_pMemory) {
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory<T>::m_pMemory, CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(
|
||||
CUtlMemory<T>::m_pMemory,
|
||||
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
} else {
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(
|
||||
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we've got at least this much memory
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num)
|
||||
{
|
||||
if(CUtlMemory<T>::m_nAllocationCount >= num)
|
||||
return;
|
||||
template <class T, int nAlignment>
|
||||
inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num) {
|
||||
if (CUtlMemory<T>::m_nAllocationCount >= num) return;
|
||||
|
||||
if(this->IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
if (this->IsExternallyAllocated()) {
|
||||
// Can't grow a buffer whose memory was externally allocated
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -646,28 +618,131 @@ inline void CUtlMemoryAligned<T, nAlignment>::EnsureCapacity(int num)
|
||||
|
||||
UTLMEMORY_TRACK_ALLOC();
|
||||
|
||||
if(CUtlMemory<T>::m_pMemory) {
|
||||
if (CUtlMemory<T>::m_pMemory) {
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(CUtlMemory<T>::m_pMemory, CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_ReallocAligned(
|
||||
CUtlMemory<T>::m_pMemory,
|
||||
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
} else {
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
CUtlMemory<T>::m_pMemory = (T*)MemAlloc_AllocAligned(
|
||||
CUtlMemory<T>::m_nAllocationCount * sizeof(T), nAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, int nAlignment >
|
||||
void CUtlMemoryAligned<T, nAlignment>::Purge()
|
||||
{
|
||||
if(!this->IsExternallyAllocated()) {
|
||||
if(CUtlMemory<T>::m_pMemory) {
|
||||
template <class T, int nAlignment>
|
||||
void CUtlMemoryAligned<T, nAlignment>::Purge() {
|
||||
if (!this->IsExternallyAllocated()) {
|
||||
if (CUtlMemory<T>::m_pMemory) {
|
||||
UTLMEMORY_TRACK_FREE();
|
||||
MemAlloc_FreeAligned(CUtlMemory<T>::m_pMemory);
|
||||
CUtlMemory<T>::m_pMemory = 0;
|
||||
}
|
||||
CUtlMemory<T>::m_nAllocationCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The CUtlMemoryFixed class:
|
||||
// A fixed memory class
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, size_t SIZE, int nAlignment = 0>
|
||||
class CUtlMemoryFixed {
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlMemoryFixed(int nGrowSize = 0, int nInitSize = 0) {
|
||||
}
|
||||
CUtlMemoryFixed(T* pMemory, int numElements) { ; }
|
||||
|
||||
// Can we use this index?
|
||||
bool IsIdxValid(int i) const { return (i >= 0) && (i < SIZE); }
|
||||
|
||||
// Specify the invalid ('null') index that we'll only return on failure
|
||||
static const int INVALID_INDEX = -1; // For use with COMPILE_TIME_ASSERT
|
||||
static int InvalidIndex() { return INVALID_INDEX; }
|
||||
|
||||
// Gets the base address
|
||||
T* Base() {
|
||||
if (nAlignment == 0)
|
||||
return (T*)(&m_Memory[0]);
|
||||
else
|
||||
return (T*)AlignValue(&m_Memory[0], nAlignment);
|
||||
}
|
||||
const T* Base() const {
|
||||
if (nAlignment == 0)
|
||||
return (T*)(&m_Memory[0]);
|
||||
else
|
||||
return (T*)AlignValue(&m_Memory[0], nAlignment);
|
||||
}
|
||||
|
||||
// element access
|
||||
T& operator[](int i) {
|
||||
Assert(IsIdxValid(i));
|
||||
return Base()[i];
|
||||
}
|
||||
const T& operator[](int i) const {
|
||||
Assert(IsIdxValid(i));
|
||||
return Base()[i];
|
||||
}
|
||||
T& Element(int i) {
|
||||
Assert(IsIdxValid(i));
|
||||
return Base()[i];
|
||||
}
|
||||
const T& Element(int i) const {
|
||||
Assert(IsIdxValid(i));
|
||||
return Base()[i];
|
||||
}
|
||||
|
||||
// Attaches the buffer to external memory....
|
||||
void SetExternalBuffer(T* pMemory, int numElements) { }
|
||||
|
||||
// Size
|
||||
int NumAllocated() const { return SIZE; }
|
||||
int Count() const { return SIZE; }
|
||||
|
||||
// Grows the memory, so that at least allocated + num elements are allocated
|
||||
void Grow(int num = 1) { Assert(0); }
|
||||
|
||||
// Makes sure we've got at least this much memory
|
||||
void EnsureCapacity(int num) { Assert(num <= SIZE); }
|
||||
|
||||
// Memory deallocation
|
||||
void Purge() {}
|
||||
|
||||
// Purge all but the given number of elements (NOT IMPLEMENTED IN
|
||||
// CUtlMemoryFixed)
|
||||
void Purge(int numElements) { Assert(0); }
|
||||
|
||||
// is the memory externally allocated?
|
||||
bool IsExternallyAllocated() const { return false; }
|
||||
|
||||
// Set the size by which the memory grows
|
||||
void SetGrowSize(int size) {}
|
||||
|
||||
class Iterator_t {
|
||||
public:
|
||||
Iterator_t(int i) : index(i) {}
|
||||
int 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());
|
||||
}
|
||||
int GetIndex(const Iterator_t& it) const { return it.index; }
|
||||
bool IsIdxAfter(int 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()); }
|
||||
|
||||
private:
|
||||
char m_Memory[SIZE * sizeof(T) + nAlignment];
|
||||
};
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
#include "UtlMemory.hpp"
|
||||
#include "../sdk.h"
|
||||
#define _Utl_Vector_assert
|
||||
template <class T>
|
||||
inline T* CopyConstruct(T* pMemory, T const& src)
|
||||
{
|
||||
return ::new(pMemory) T(src);
|
||||
inline T* CopyConstruct(T* pMemory, T const& src) {
|
||||
return ::new (pMemory) T(src);
|
||||
}
|
||||
|
||||
template< class T, class A = CUtlMemory<T> >
|
||||
class CUtlVector
|
||||
{
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
template <class T, class A = CUtlMemory<T> >
|
||||
class CUtlVector {
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef A CAllocator;
|
||||
public:
|
||||
|
||||
public:
|
||||
typedef T ElemType_t;
|
||||
|
||||
// constructor, destructor
|
||||
@@ -24,7 +21,7 @@ public:
|
||||
~CUtlVector();
|
||||
|
||||
// Copy the array.
|
||||
CUtlVector<T, A>& operator=(const CUtlVector<T, A> &other);
|
||||
CUtlVector<T, A>& operator=(const CUtlVector<T, A>& other);
|
||||
|
||||
// element access
|
||||
T& operator[](int i);
|
||||
@@ -57,52 +54,60 @@ public:
|
||||
// Adds multiple elements, uses default constructor
|
||||
int AddMultipleToHead(int num);
|
||||
int AddMultipleToTail(int num);
|
||||
int AddMultipleToTail(int num, const T *pToCopy);
|
||||
int AddMultipleToTail(int num, const T* pToCopy);
|
||||
int InsertMultipleBefore(int elem, int num);
|
||||
int InsertMultipleBefore(int elem, int num, const T *pToCopy);
|
||||
int InsertMultipleBefore(int elem, int num, const T* pToCopy);
|
||||
int InsertMultipleAfter(int elem, int num);
|
||||
// Calls RemoveAll() then AddMultipleToTail.
|
||||
void SetSize(int size);
|
||||
void SetCount(int count);
|
||||
void SetCountNonDestructively(int count); //sets count by adding or removing elements to tail TODO: This should probably be the default behavior for SetCount
|
||||
void CopyArray(const T *pArray, int size); //Calls SetSize and copies each element.
|
||||
// Fast swap
|
||||
void Swap(CUtlVector< T, A > &vec);
|
||||
void SetCountNonDestructively(
|
||||
int count); // sets count by adding or removing elements to tail TODO:
|
||||
// This should probably be the default behavior for
|
||||
// SetCount
|
||||
void CopyArray(const T* pArray,
|
||||
int size); // Calls SetSize and copies each element.
|
||||
// Fast swap
|
||||
void Swap(CUtlVector<T, A>& vec);
|
||||
// Add the specified array to the tail.
|
||||
int AddVectorToTail(CUtlVector<T, A> const &src);
|
||||
int AddVectorToTail(CUtlVector<T, A> const& src);
|
||||
// Finds an element (element needs operator== defined)
|
||||
int GetOffset(const T& src) const;
|
||||
void FillWithValue(const T& src);
|
||||
bool HasElement(const T& src) const;
|
||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||
// Makes sure we have enough memory allocated to store a requested # of
|
||||
// elements
|
||||
void EnsureCapacity(int num);
|
||||
// Makes sure we have at least this many elements
|
||||
void EnsureCount(int num);
|
||||
// Element removal
|
||||
void FastRemove(int elem); // doesn't preserve order
|
||||
void Remove(int elem); // preserves order, shifts elements
|
||||
bool FindAndRemove(const T& src); // removes first occurrence of src, preserves order, shifts elements
|
||||
bool FindAndFastRemove(const T& src); // removes first occurrence of src, doesn't preserve order
|
||||
void RemoveMultiple(int elem, int num); // preserves order, shifts elements
|
||||
void RemoveMultipleFromHead(int num); // removes num elements from tail
|
||||
void RemoveMultipleFromTail(int num); // removes num elements from tail
|
||||
void RemoveAll(); // doesn't deallocate memory
|
||||
void Purge(); // Memory deallocation
|
||||
// Purges the list and calls delete on each element in it.
|
||||
void FastRemove(int elem); // doesn't preserve order
|
||||
void Remove(int elem); // preserves order, shifts elements
|
||||
bool FindAndRemove(const T& src); // removes first occurrence of src,
|
||||
// preserves order, shifts elements
|
||||
bool FindAndFastRemove(const T& src); // removes first occurrence of src,
|
||||
// doesn't preserve order
|
||||
void RemoveMultiple(int elem, int num); // preserves order, shifts elements
|
||||
void RemoveMultipleFromHead(int num); // removes num elements from tail
|
||||
void RemoveMultipleFromTail(int num); // removes num elements from tail
|
||||
void RemoveAll(); // doesn't deallocate memory
|
||||
void Purge(); // Memory deallocation
|
||||
// Purges the list and calls delete on each element in it.
|
||||
void PurgeAndDeleteElements();
|
||||
// Compacts the vector to the number of elements actually in use
|
||||
// Compacts the vector to the number of elements actually in use
|
||||
void Compact();
|
||||
// Set the size by which it grows when it needs to allocate more memory.
|
||||
void SetGrowSize(int size) { m_Memory.SetGrowSize(size); }
|
||||
int NumAllocated() const; // Only use this if you really know what you're doing!
|
||||
void Sort(int(__cdecl *pfnCompare)(const T *, const T *));
|
||||
int NumAllocated()
|
||||
const; // Only use this if you really know what you're doing!
|
||||
void Sort(int(__cdecl* pfnCompare)(const T*, const T*));
|
||||
|
||||
iterator begin() { return Base(); }
|
||||
const_iterator begin() const { return Base(); }
|
||||
iterator end() { return Base() + Count(); }
|
||||
const_iterator end() const { return Base() + Count(); }
|
||||
iterator begin() { return Base(); }
|
||||
const_iterator begin() const { return Base(); }
|
||||
iterator end() { return Base() + Count(); }
|
||||
const_iterator end() const { return Base() + Count(); }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Can't copy this unless we explicitly do it!
|
||||
CUtlVector(CUtlVector const& vec) { _Utl_Vector_assert(0); }
|
||||
|
||||
@@ -113,153 +118,130 @@ protected:
|
||||
void ShiftElementsRight(int elem, int num = 1);
|
||||
void ShiftElementsLeft(int elem, int num = 1);
|
||||
|
||||
public:
|
||||
public:
|
||||
CAllocator m_Memory;
|
||||
int m_Size;
|
||||
|
||||
// For easier access to the elements through the debugger
|
||||
// it's in release builds so this can be used in libraries correctly
|
||||
T *m_pElements;
|
||||
T* m_pElements;
|
||||
|
||||
inline void ResetDbgInfo()
|
||||
{
|
||||
m_pElements = Base();
|
||||
}
|
||||
inline void ResetDbgInfo() { m_pElements = Base(); }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline CUtlVector<T, A>::CUtlVector(int growSize, int initSize) :
|
||||
m_Memory(growSize, initSize), m_Size(0)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline CUtlVector<T, A>::CUtlVector(int growSize, int initSize)
|
||||
: m_Memory(growSize, initSize), m_Size(0) {
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline CUtlVector<T, A>::CUtlVector(T* pMemory, int allocationCount, int numElements) :
|
||||
m_Memory(pMemory, allocationCount), m_Size(numElements)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline CUtlVector<T, A>::CUtlVector(T* pMemory, int allocationCount,
|
||||
int numElements)
|
||||
: m_Memory(pMemory, allocationCount), m_Size(numElements) {
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline CUtlVector<T, A>::~CUtlVector()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline CUtlVector<T, A>::~CUtlVector() {
|
||||
Purge();
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline CUtlVector<T, A>& CUtlVector<T, A>::operator=(const CUtlVector<T, A> &other)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline CUtlVector<T, A>& CUtlVector<T, A>::operator=(
|
||||
const CUtlVector<T, A>& other) {
|
||||
int nCount = other.Count();
|
||||
SetSize(nCount);
|
||||
for(int i = 0; i < nCount; i++) {
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
(*this)[i] = other[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element access
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline T& CUtlVector<T, A>::operator[](int i)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline T& CUtlVector<T, A>::operator[](int i) {
|
||||
_Utl_Vector_assert(i < m_Size);
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline const T& CUtlVector<T, A>::operator[](int i) const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline const T& CUtlVector<T, A>::operator[](int i) const {
|
||||
_Utl_Vector_assert(i < m_Size);
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline T& CUtlVector<T, A>::Element(int i)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline T& CUtlVector<T, A>::Element(int i) {
|
||||
_Utl_Vector_assert(i < m_Size);
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline const T& CUtlVector<T, A>::Element(int i) const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline const T& CUtlVector<T, A>::Element(int i) const {
|
||||
_Utl_Vector_assert(i < m_Size);
|
||||
return m_Memory[i];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline T& CUtlVector<T, A>::Head()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline T& CUtlVector<T, A>::Head() {
|
||||
_Utl_Vector_assert(m_Size > 0);
|
||||
return m_Memory[0];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline const T& CUtlVector<T, A>::Head() const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline const T& CUtlVector<T, A>::Head() const {
|
||||
_Utl_Vector_assert(m_Size > 0);
|
||||
return m_Memory[0];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline T& CUtlVector<T, A>::Tail()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline T& CUtlVector<T, A>::Tail() {
|
||||
_Utl_Vector_assert(m_Size > 0);
|
||||
return m_Memory[m_Size - 1];
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline const T& CUtlVector<T, A>::Tail() const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline const T& CUtlVector<T, A>::Tail() const {
|
||||
_Utl_Vector_assert(m_Size > 0);
|
||||
return m_Memory[m_Size - 1];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Count
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::Count() const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::Count() const {
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Is element index valid?
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline bool CUtlVector<T, A>::IsValidIndex(int i) const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline bool CUtlVector<T, A>::IsValidIndex(int i) const {
|
||||
return (i >= 0) && (i < m_Size);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns in invalid index
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::InvalidIndex()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::InvalidIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Grows the vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::GrowVector(int num)
|
||||
{
|
||||
if(m_Size + num > m_Memory.NumAllocated()) {
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::GrowVector(int num) {
|
||||
if (m_Size + num > m_Memory.NumAllocated()) {
|
||||
m_Memory.Grow(m_Size + num - m_Memory.NumAllocated());
|
||||
}
|
||||
|
||||
@@ -267,29 +249,27 @@ void CUtlVector<T, A>::GrowVector(int num)
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts the vector
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::Sort(int(__cdecl *pfnCompare)(const T *, const T *))
|
||||
{
|
||||
typedef int(__cdecl *QSortCompareFunc_t)(const void *, const void *);
|
||||
if(Count() <= 1)
|
||||
return;
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::Sort(int(__cdecl* pfnCompare)(const T*, const T*)) {
|
||||
typedef int(__cdecl * QSortCompareFunc_t)(const void*, const void*);
|
||||
if (Count() <= 1) return;
|
||||
|
||||
if(Base()) {
|
||||
if (Base()) {
|
||||
qsort(Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare));
|
||||
} else {
|
||||
_Utl_Vector_assert(0);
|
||||
// this path is untested
|
||||
// if you want to sort vectors that use a non-sequential memory allocator,
|
||||
// you'll probably want to patch in a quicksort algorithm here
|
||||
// I just threw in this bubble sort to have something just in case...
|
||||
// if you want to sort vectors that use a non-sequential memory
|
||||
// allocator, you'll probably want to patch in a quicksort algorithm
|
||||
// here I just threw in this bubble sort to have something just in
|
||||
// case...
|
||||
|
||||
for(int i = m_Size - 1; i >= 0; --i) {
|
||||
for(int j = 1; j <= i; ++j) {
|
||||
if(pfnCompare(&Element(j - 1), &Element(j)) < 0) {
|
||||
for (int i = m_Size - 1; i >= 0; --i) {
|
||||
for (int j = 1; j <= i; ++j) {
|
||||
if (pfnCompare(&Element(j - 1), &Element(j)) < 0) {
|
||||
V_swap(Element(j - 1), Element(j));
|
||||
}
|
||||
}
|
||||
@@ -300,45 +280,39 @@ void CUtlVector<T, A>::Sort(int(__cdecl *pfnCompare)(const T *, const T *))
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we have enough memory allocated to store a requested # of elements
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::EnsureCapacity(int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::EnsureCapacity(int num) {
|
||||
MEM_ALLOC_CREDIT_CLASS();
|
||||
m_Memory.EnsureCapacity(num);
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Makes sure we have at least this many elements
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::EnsureCount(int num)
|
||||
{
|
||||
if(Count() < num) {
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::EnsureCount(int num) {
|
||||
if (Count() < num) {
|
||||
AddMultipleToTail(num - Count());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shifts elements
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::ShiftElementsRight(int elem, int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::ShiftElementsRight(int elem, int num) {
|
||||
_Utl_Vector_assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
|
||||
int numToMove = m_Size - elem - num;
|
||||
if((numToMove > 0) && (num > 0))
|
||||
if ((numToMove > 0) && (num > 0))
|
||||
memmove(&Element(elem + num), &Element(elem), numToMove * sizeof(T));
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num) {
|
||||
_Utl_Vector_assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
|
||||
int numToMove = m_Size - elem - num;
|
||||
if((numToMove > 0) && (num > 0)) {
|
||||
if ((numToMove > 0) && (num > 0)) {
|
||||
memmove(&Element(elem), &Element(elem + num), numToMove * sizeof(T));
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -347,31 +321,26 @@ void CUtlVector<T, A>::ShiftElementsLeft(int elem, int num)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds an element, uses default constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddToHead()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddToHead() {
|
||||
return InsertBefore(0);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddToTail()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddToTail() {
|
||||
return InsertBefore(m_Size);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::InsertAfter(int elem)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::InsertAfter(int elem) {
|
||||
return InsertBefore(elem + 1);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
int CUtlVector<T, A>::InsertBefore(int elem)
|
||||
{
|
||||
template <typename T, class A>
|
||||
int CUtlVector<T, A>::InsertBefore(int elem) {
|
||||
// Can insert at the end
|
||||
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
|
||||
|
||||
@@ -381,39 +350,38 @@ int CUtlVector<T, A>::InsertBefore(int elem)
|
||||
return elem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds an element, uses copy constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddToHead(const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddToHead(const T& src) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
|
||||
(&src >= (Base() + Count())));
|
||||
return InsertBefore(0, src);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddToTail(const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddToTail(const T& src) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
|
||||
(&src >= (Base() + Count())));
|
||||
return InsertBefore(m_Size, src);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::InsertAfter(int elem, const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::InsertAfter(int elem, const T& src) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
|
||||
(&src >= (Base() + Count())));
|
||||
return InsertBefore(elem + 1, src);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
int CUtlVector<T, A>::InsertBefore(int elem, const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
int CUtlVector<T, A>::InsertBefore(int elem, const T& src) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) || (&src >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || (&src < Base()) ||
|
||||
(&src >= (Base() + Count())));
|
||||
|
||||
// Can insert at the end
|
||||
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
|
||||
@@ -424,74 +392,69 @@ int CUtlVector<T, A>::InsertBefore(int elem, const T& src)
|
||||
return elem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds multiple elements, uses default constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddMultipleToHead(int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddMultipleToHead(int num) {
|
||||
return InsertMultipleBefore(0, num);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddMultipleToTail(int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddMultipleToTail(int num) {
|
||||
return InsertMultipleBefore(m_Size, num);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::AddMultipleToTail(int num, const T *pToCopy)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::AddMultipleToTail(int num, const T* pToCopy) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || !pToCopy || (pToCopy + num <= Base()) || (pToCopy >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || !pToCopy ||
|
||||
(pToCopy + num <= Base()) ||
|
||||
(pToCopy >= (Base() + Count())));
|
||||
|
||||
return InsertMultipleBefore(m_Size, num, pToCopy);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
int CUtlVector<T, A>::InsertMultipleAfter(int elem, int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
int CUtlVector<T, A>::InsertMultipleAfter(int elem, int num) {
|
||||
return InsertMultipleBefore(elem + 1, num);
|
||||
}
|
||||
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::SetCount(int count)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::SetCount(int count) {
|
||||
RemoveAll();
|
||||
AddMultipleToTail(count);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline void CUtlVector<T, A>::SetSize(int size)
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline void CUtlVector<T, A>::SetSize(int size) {
|
||||
SetCount(size);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::SetCountNonDestructively(int count)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::SetCountNonDestructively(int count) {
|
||||
int delta = count - m_Size;
|
||||
if(delta > 0) AddMultipleToTail(delta);
|
||||
else if(delta < 0) RemoveMultipleFromTail(-delta);
|
||||
if (delta > 0)
|
||||
AddMultipleToTail(delta);
|
||||
else if (delta < 0)
|
||||
RemoveMultipleFromTail(-delta);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::CopyArray(const T *pArray, int size)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::CopyArray(const T* pArray, int size) {
|
||||
// Can't insert something that's in the list... reallocation may hose us
|
||||
_Utl_Vector_assert((Base() == NULL) || !pArray || (Base() >= (pArray + size)) || (pArray >= (Base() + Count())));
|
||||
_Utl_Vector_assert((Base() == NULL) || !pArray ||
|
||||
(Base() >= (pArray + size)) ||
|
||||
(pArray >= (Base() + Count())));
|
||||
|
||||
SetSize(size);
|
||||
for(int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
(*this)[i] = pArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::Swap(CUtlVector< T, A > &vec)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::Swap(CUtlVector<T, A>& vec) {
|
||||
m_Memory.Swap(vec.m_Memory);
|
||||
V_swap(m_Size, vec.m_Size);
|
||||
#ifndef _X360
|
||||
@@ -499,9 +462,8 @@ void CUtlVector<T, A>::Swap(CUtlVector< T, A > &vec)
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
int CUtlVector<T, A>::AddVectorToTail(CUtlVector const &src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
int CUtlVector<T, A>::AddVectorToTail(CUtlVector const& src) {
|
||||
_Utl_Vector_assert(&src != this);
|
||||
|
||||
int base = Count();
|
||||
@@ -510,19 +472,17 @@ int CUtlVector<T, A>::AddVectorToTail(CUtlVector const &src)
|
||||
int nSrcCount = src.Count();
|
||||
EnsureCapacity(base + nSrcCount);
|
||||
|
||||
// Copy the elements.
|
||||
// Copy the elements.
|
||||
m_Size += nSrcCount;
|
||||
for(int i = 0; i < nSrcCount; i++) {
|
||||
for (int i = 0; i < nSrcCount; i++) {
|
||||
CopyConstruct(&Element(base + i), src[i]);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num)
|
||||
{
|
||||
if(num == 0)
|
||||
return elem;
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num) {
|
||||
if (num == 0) return elem;
|
||||
|
||||
// Can insert at the end
|
||||
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
|
||||
@@ -531,18 +491,17 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num)
|
||||
ShiftElementsRight(elem, num);
|
||||
|
||||
// Invoke default constructors
|
||||
for(int i = 0; i < num; ++i) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
Construct(&Element(elem + i));
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pToInsert)
|
||||
{
|
||||
if(num == 0)
|
||||
return elem;
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num,
|
||||
const T* pToInsert) {
|
||||
if (num == 0) return elem;
|
||||
|
||||
// Can insert at the end
|
||||
_Utl_Vector_assert((elem == Count()) || IsValidIndex(elem));
|
||||
@@ -551,12 +510,12 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pT
|
||||
ShiftElementsRight(elem, num);
|
||||
|
||||
// Invoke default constructors
|
||||
if(!pToInsert) {
|
||||
for(int i = 0; i < num; ++i) {
|
||||
if (!pToInsert) {
|
||||
for (int i = 0; i < num; ++i) {
|
||||
Construct(&Element(elem + i));
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < num; i++) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
CopyConstruct(&Element(elem + i), pToInsert[i]);
|
||||
}
|
||||
}
|
||||
@@ -564,204 +523,215 @@ inline int CUtlVector<T, A>::InsertMultipleBefore(int elem, int num, const T *pT
|
||||
return elem;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds an element (element needs operator== defined)
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
int CUtlVector<T, A>::GetOffset(const T& src) const
|
||||
{
|
||||
for(int i = 0; i < Count(); ++i) {
|
||||
if(Element(i) == src)
|
||||
return i;
|
||||
template <typename T, class A>
|
||||
int CUtlVector<T, A>::GetOffset(const T& src) const {
|
||||
for (int i = 0; i < Count(); ++i) {
|
||||
if (Element(i) == src) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::FillWithValue(const T& src)
|
||||
{
|
||||
for(int i = 0; i < Count(); i++) {
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::FillWithValue(const T& src) {
|
||||
for (int i = 0; i < Count(); i++) {
|
||||
Element(i) = src;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
bool CUtlVector<T, A>::HasElement(const T& src) const
|
||||
{
|
||||
template <typename T, class A>
|
||||
bool CUtlVector<T, A>::HasElement(const T& src) const {
|
||||
return (GetOffset(src) >= 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Element removal
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::FastRemove(int elem)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::FastRemove(int elem) {
|
||||
_Utl_Vector_assert(IsValidIndex(elem));
|
||||
|
||||
Destruct(&Element(elem));
|
||||
if(m_Size > 0) {
|
||||
if(elem != m_Size - 1)
|
||||
if (m_Size > 0) {
|
||||
if (elem != m_Size - 1)
|
||||
memcpy(&Element(elem), &Element(m_Size - 1), sizeof(T));
|
||||
--m_Size;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::Remove(int elem)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::Remove(int elem) {
|
||||
Destruct(&Element(elem));
|
||||
ShiftElementsLeft(elem);
|
||||
--m_Size;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
bool CUtlVector<T, A>::FindAndRemove(const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
bool CUtlVector<T, A>::FindAndRemove(const T& src) {
|
||||
int elem = GetOffset(src);
|
||||
if(elem != -1) {
|
||||
if (elem != -1) {
|
||||
Remove(elem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
bool CUtlVector<T, A>::FindAndFastRemove(const T& src)
|
||||
{
|
||||
template <typename T, class A>
|
||||
bool CUtlVector<T, A>::FindAndFastRemove(const T& src) {
|
||||
int elem = GetOffset(src);
|
||||
if(elem != -1) {
|
||||
if (elem != -1) {
|
||||
FastRemove(elem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::RemoveMultiple(int elem, int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::RemoveMultiple(int elem, int num) {
|
||||
_Utl_Vector_assert(elem >= 0);
|
||||
_Utl_Vector_assert(elem + num <= Count());
|
||||
|
||||
for(int i = elem + num; --i >= elem; )
|
||||
Destruct(&Element(i));
|
||||
for (int i = elem + num; --i >= elem;) Destruct(&Element(i));
|
||||
|
||||
ShiftElementsLeft(elem, num);
|
||||
m_Size -= num;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::RemoveMultipleFromHead(int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::RemoveMultipleFromHead(int num) {
|
||||
_Utl_Vector_assert(num <= Count());
|
||||
|
||||
for(int i = num; --i >= 0; )
|
||||
Destruct(&Element(i));
|
||||
for (int i = num; --i >= 0;) Destruct(&Element(i));
|
||||
|
||||
ShiftElementsLeft(0, num);
|
||||
m_Size -= num;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::RemoveMultipleFromTail(int num)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::RemoveMultipleFromTail(int num) {
|
||||
_Utl_Vector_assert(num <= Count());
|
||||
|
||||
for(int i = m_Size - num; i < m_Size; i++)
|
||||
Destruct(&Element(i));
|
||||
for (int i = m_Size - num; i < m_Size; i++) Destruct(&Element(i));
|
||||
|
||||
m_Size -= num;
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::RemoveAll()
|
||||
{
|
||||
for(int i = m_Size; --i >= 0; ) {
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::RemoveAll() {
|
||||
for (int i = m_Size; --i >= 0;) {
|
||||
Destruct(&Element(i));
|
||||
}
|
||||
|
||||
m_Size = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory deallocation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< typename T, class A >
|
||||
inline void CUtlVector<T, A>::Purge()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline void CUtlVector<T, A>::Purge() {
|
||||
RemoveAll();
|
||||
m_Memory.Purge();
|
||||
ResetDbgInfo();
|
||||
}
|
||||
|
||||
|
||||
template< typename T, class A >
|
||||
inline void CUtlVector<T, A>::PurgeAndDeleteElements()
|
||||
{
|
||||
for(int i = 0; i < m_Size; i++) {
|
||||
template <typename T, class A>
|
||||
inline void CUtlVector<T, A>::PurgeAndDeleteElements() {
|
||||
for (int i = 0; i < m_Size; i++) {
|
||||
delete Element(i);
|
||||
}
|
||||
Purge();
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline void CUtlVector<T, A>::Compact()
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline void CUtlVector<T, A>::Compact() {
|
||||
m_Memory.Purge(m_Size);
|
||||
}
|
||||
|
||||
template< typename T, class A >
|
||||
inline int CUtlVector<T, A>::NumAllocated() const
|
||||
{
|
||||
template <typename T, class A>
|
||||
inline int CUtlVector<T, A>::NumAllocated() const {
|
||||
return m_Memory.NumAllocated();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Data and memory validation
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef DBGFLAG_VALIDATE
|
||||
template< typename T, class A >
|
||||
void CUtlVector<T, A>::Validate(CValidator &validator, char *pchName)
|
||||
{
|
||||
template <typename T, class A>
|
||||
void CUtlVector<T, A>::Validate(CValidator& validator, char* pchName) {
|
||||
validator.Push(typeid(*this).name(), this, pchName);
|
||||
|
||||
m_Memory.Validate(validator, "m_Memory");
|
||||
|
||||
validator.Pop();
|
||||
}
|
||||
#endif // DBGFLAG_VALIDATE
|
||||
#endif // DBGFLAG_VALIDATE
|
||||
|
||||
// A vector class for storing pointers, so that the elements pointed to by the pointers are deleted
|
||||
// on exit.
|
||||
template<class T> class CUtlVectorAutoPurge : public CUtlVector< T, CUtlMemory< T, int> >
|
||||
{
|
||||
public:
|
||||
~CUtlVectorAutoPurge(void)
|
||||
{
|
||||
this->PurgeAndDeleteElements();
|
||||
}
|
||||
// A vector class for storing pointers, so that the elements pointed to by the
|
||||
// pointers are deleted on exit.
|
||||
template <class T>
|
||||
class CUtlVectorAutoPurge : public CUtlVector<T, CUtlMemory<T, int> > {
|
||||
public:
|
||||
~CUtlVectorAutoPurge(void) { this->PurgeAndDeleteElements(); }
|
||||
};
|
||||
|
||||
// easy string list class with dynamically allocated strings. For use with V_SplitString, etc.
|
||||
// Frees the dynamic strings in destructor.
|
||||
class CUtlStringList : public CUtlVectorAutoPurge< char *>
|
||||
{
|
||||
public:
|
||||
void CopyAndAddToTail(char const *pString) // clone the string and add to the end
|
||||
// easy string list class with dynamically allocated strings. For use with
|
||||
// V_SplitString, etc. Frees the dynamic strings in destructor.
|
||||
class CUtlStringList : public CUtlVectorAutoPurge<char*> {
|
||||
public:
|
||||
void CopyAndAddToTail(
|
||||
char const* pString) // clone the string and add to the end
|
||||
{
|
||||
char *pNewStr = new char[1 + strlen(pString)];
|
||||
char* pNewStr = new char[1 + strlen(pString)];
|
||||
strcpy_s(pNewStr, 1 + strlen(pString), pString);
|
||||
AddToTail(pNewStr);
|
||||
}
|
||||
|
||||
static int __cdecl SortFunc(char * const * sz1, char * const * sz2)
|
||||
{
|
||||
static int __cdecl SortFunc(char* const* sz1, char* const* sz2) {
|
||||
return strcmp(*sz1, *sz2);
|
||||
}
|
||||
};
|
||||
template <class T, size_t MAX_SIZE>
|
||||
class CUtlVectorFixed : public CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE> > {
|
||||
typedef CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE> > BaseClass;
|
||||
|
||||
};
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlVectorFixed(int growSize = 0, int initSize = 0)
|
||||
: BaseClass(growSize, initSize) {}
|
||||
CUtlVectorFixed(T* pMemory, int numElements)
|
||||
: BaseClass(pMemory, numElements) {}
|
||||
};
|
||||
|
||||
template <class T, size_t SIZE, class I = int>
|
||||
class CUtlMemoryFixedGrowable : public CUtlMemory<T, I> {
|
||||
typedef CUtlMemory<T, I> BaseClass;
|
||||
|
||||
public:
|
||||
CUtlMemoryFixedGrowable(int nGrowSize = 0, int nInitSize = SIZE)
|
||||
: BaseClass(m_pFixedMemory, SIZE) {
|
||||
Assert(nInitSize == 0 || nInitSize == SIZE);
|
||||
}
|
||||
|
||||
void EnsureCapacity(int num) {
|
||||
if (CUtlMemory<T>::m_nAllocationCount >= num) return;
|
||||
|
||||
BaseClass::EnsureCapacity(num);
|
||||
}
|
||||
|
||||
private:
|
||||
T m_pFixedMemory[SIZE];
|
||||
};
|
||||
|
||||
template <class T, size_t MAX_SIZE>
|
||||
class CUtlVectorFixedGrowable
|
||||
: public CUtlVector<T, CUtlMemoryFixedGrowable<T, MAX_SIZE> > {
|
||||
typedef CUtlVector<T, CUtlMemoryFixedGrowable<T, MAX_SIZE> > BaseClass;
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CUtlVectorFixedGrowable(int growSize = 0) : BaseClass(growSize, MAX_SIZE) {}
|
||||
};
|
||||
|
||||
8
csgo2/sdk/tier1/cbyteswap.cpp
Normal file
8
csgo2/sdk/tier1/cbyteswap.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
//========= Copyright <20> 1996-2006, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Low level byte swapping routines.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "cbyteswap.h"
|
||||
492
csgo2/sdk/tier1/cbyteswap.h
Normal file
492
csgo2/sdk/tier1/cbyteswap.h
Normal file
@@ -0,0 +1,492 @@
|
||||
//========= Copyright ?1996-2006, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Low level byte swapping routines.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#ifndef BYTESWAP_H
|
||||
#define BYTESWAP_H
|
||||
#if defined(_WIN32)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "../sdk.h"
|
||||
|
||||
typedef enum _fieldtypes {
|
||||
FIELD_VOID = 0, // No type or value
|
||||
FIELD_FLOAT, // Any floating point value
|
||||
FIELD_STRING, // A string ID (return from ALLOC_STRING)
|
||||
FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse
|
||||
FIELD_QUATERNION, // A quaternion
|
||||
FIELD_INTEGER, // Any integer or enum
|
||||
FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint
|
||||
// for compression
|
||||
FIELD_SHORT, // 2 byte integer
|
||||
FIELD_CHARACTER, // a byte
|
||||
FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color)
|
||||
FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse
|
||||
// and embedded class/structure based on an additional
|
||||
// typedescription
|
||||
FIELD_CUSTOM, // special type that contains function pointers to it's
|
||||
// read/write/parse functions
|
||||
|
||||
FIELD_CLASSPTR, // CBaseEntity *
|
||||
FIELD_EHANDLE, // Entity handle
|
||||
|
||||
FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across
|
||||
// level transitions automagically)
|
||||
FIELD_TIME, // a floating point time (these are fixed up automatically
|
||||
// too!)
|
||||
FIELD_TICK, // an integer tick count( fixed up similarly to time)
|
||||
FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache)
|
||||
|
||||
FIELD_INPUT, // a list of inputed data fields (all derived from
|
||||
// CMultiInputVar)
|
||||
FIELD_FUNCTION, // A class function pointer (Think, Use, etc)
|
||||
|
||||
FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace)
|
||||
|
||||
// NOTE: Use float arrays for local transformations that don't need to be
|
||||
// fixed up.
|
||||
FIELD_VMATRIX_WORLDSPACE, // A VMatrix that maps some local space to world
|
||||
// space (translation is fixed up on level
|
||||
// transitions)
|
||||
FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to
|
||||
// world space (translation is fixed up on
|
||||
// level transitions)
|
||||
|
||||
FIELD_INTERVAL, // a start and range floating point interval (
|
||||
// e.g., 3.2->3.6 == 3.2 and 0.4 )
|
||||
FIELD_UNUSED,
|
||||
|
||||
FIELD_VECTOR2D, // 2 floats
|
||||
FIELD_INTEGER64, // 64bit integer
|
||||
|
||||
FIELD_VECTOR4D, // 4 floats
|
||||
|
||||
FIELD_RESOURCE,
|
||||
|
||||
FIELD_TYPEUNKNOWN,
|
||||
|
||||
FIELD_CSTRING,
|
||||
FIELD_HSCRIPT,
|
||||
FIELD_VARIANT,
|
||||
FIELD_UINT64,
|
||||
FIELD_FLOAT64,
|
||||
FIELD_POSITIVEINTEGER_OR_NULL,
|
||||
FIELD_HSCRIPT_NEW_INSTANCE,
|
||||
FIELD_UINT,
|
||||
FIELD_UTLSTRINGTOKEN,
|
||||
FIELD_QANGLE,
|
||||
FIELD_NETWORK_ORIGIN_CELL_QUANTIZED_VECTOR,
|
||||
FIELD_HMATERIAL,
|
||||
FIELD_HMODEL,
|
||||
FIELD_NETWORK_QUANTIZED_VECTOR,
|
||||
FIELD_NETWORK_QUANTIZED_FLOAT,
|
||||
FIELD_DIRECTION_VECTOR_WORLDSPACE,
|
||||
FIELD_QANGLE_WORLDSPACE,
|
||||
FIELD_QUATERNION_WORLDSPACE,
|
||||
FIELD_HSCRIPT_LIGHTBINDING,
|
||||
FIELD_V8_VALUE,
|
||||
FIELD_V8_OBJECT,
|
||||
FIELD_V8_ARRAY,
|
||||
FIELD_V8_CALLBACK_INFO,
|
||||
FIELD_UTLSTRING,
|
||||
|
||||
FIELD_NETWORK_ORIGIN_CELL_QUANTIZED_POSITION_VECTOR,
|
||||
FIELD_HRENDERTEXTURE,
|
||||
|
||||
FIELD_HPARTICLESYSTEMDEFINITION,
|
||||
FIELD_UINT8,
|
||||
FIELD_UINT16,
|
||||
FIELD_CTRANSFORM,
|
||||
FIELD_CTRANSFORM_WORLDSPACE,
|
||||
FIELD_HPOSTPROCESSING,
|
||||
FIELD_MATRIX3X4,
|
||||
FIELD_SHIM,
|
||||
FIELD_CMOTIONTRANSFORM,
|
||||
FIELD_CMOTIONTRANSFORM_WORLDSPACE,
|
||||
FIELD_ATTACHMENT_HANDLE,
|
||||
FIELD_AMMO_INDEX,
|
||||
FIELD_CONDITION_ID,
|
||||
FIELD_AI_SCHEDULE_BITS,
|
||||
FIELD_MODIFIER_HANDLE,
|
||||
FIELD_ROTATION_VECTOR,
|
||||
FIELD_ROTATION_VECTOR_WORLDSPACE,
|
||||
FIELD_HVDATA,
|
||||
FIELD_SCALE32,
|
||||
FIELD_STRING_AND_TOKEN,
|
||||
FIELD_ENGINE_TIME,
|
||||
FIELD_ENGINE_TICK,
|
||||
FIELD_WORLD_GROUP_ID,
|
||||
|
||||
FIELD_TYPECOUNT
|
||||
} fieldtype_t;
|
||||
struct inputdata_t;
|
||||
|
||||
class ISaveRestoreOps;
|
||||
typedef void(__fastcall *inputfunc_t)(inputdata_t &data);
|
||||
|
||||
enum {
|
||||
PC_NON_NETWORKED_ONLY = 0,
|
||||
PC_NETWORKED_ONLY,
|
||||
|
||||
PC_COPYTYPE_COUNT,
|
||||
PC_EVERYTHING = PC_COPYTYPE_COUNT,
|
||||
};
|
||||
|
||||
enum {
|
||||
TD_OFFSET_NORMAL = 0,
|
||||
TD_OFFSET_PACKED = 1,
|
||||
|
||||
// Must be last
|
||||
TD_OFFSET_COUNT,
|
||||
};
|
||||
struct datarun_t;
|
||||
struct typedescription_t;
|
||||
struct datacopyruns_t
|
||||
{
|
||||
public:
|
||||
CUtlVector< datarun_t > m_vecRuns;
|
||||
};
|
||||
|
||||
struct flattenedoffsets_t
|
||||
{
|
||||
CUtlVector< typedescription_t > m_Flattened;
|
||||
int m_nPackedSize; // Contiguous memory to pack all of these together for TD_OFFSET_PACKED
|
||||
int m_nPackedStartOffset;
|
||||
};
|
||||
|
||||
struct datamapinfo_t
|
||||
{
|
||||
// Flattened list, with FIELD_EMBEDDED, FTYPEDESC_PRIVATE,
|
||||
// and FTYPEDESC_OVERRIDE (overridden) fields removed
|
||||
flattenedoffsets_t m_Flat;
|
||||
datacopyruns_t m_CopyRuns;
|
||||
};
|
||||
|
||||
struct optimized_datamap_t
|
||||
{
|
||||
// Optimized info for PC_NON_NETWORKED and PC_NETWORKED data
|
||||
datamapinfo_t m_Info[PC_COPYTYPE_COUNT];
|
||||
};
|
||||
|
||||
|
||||
struct datamap_t
|
||||
{
|
||||
typedescription_t* dataDesc;
|
||||
int dataNumFields;
|
||||
char const* dataClassName;
|
||||
datamap_t* baseMap;
|
||||
|
||||
int m_nPackedSize;
|
||||
optimized_datamap_t* m_pOptimizedDataMap;
|
||||
|
||||
#if defined( _DEBUG )
|
||||
bool bValidityChecked;
|
||||
#endif // _DEBUG
|
||||
};
|
||||
|
||||
struct typedescription_t {
|
||||
fieldtype_t fieldType;
|
||||
const char *fieldName;
|
||||
int fieldOffset; // Local offset value
|
||||
unsigned short fieldSize;
|
||||
short flags;
|
||||
// the name of the variable in the map/fgd data, or the name of the action
|
||||
const char *externalName;
|
||||
// pointer to the function set for save/restoring of custom data types
|
||||
ISaveRestoreOps *pSaveRestoreOps;
|
||||
// for associating function with string names
|
||||
inputfunc_t inputFunc;
|
||||
// For embedding additional datatables inside this one
|
||||
datamap_t *td;
|
||||
|
||||
// Stores the actual member variable size in bytes
|
||||
int fieldSizeInBytes;
|
||||
|
||||
// FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated
|
||||
// has occurred
|
||||
struct typedescription_t *override_field;
|
||||
|
||||
// Used to track exclusion of baseclass fields
|
||||
int override_count;
|
||||
|
||||
// Tolerance for field errors for float fields
|
||||
float fieldTolerance;
|
||||
|
||||
// For raw fields (including children of embedded stuff) this is the
|
||||
// flattened offset
|
||||
int flatOffset[TD_OFFSET_COUNT];
|
||||
unsigned short flatGroup;
|
||||
};
|
||||
struct datarun_t
|
||||
{
|
||||
datarun_t() : m_nStartFlatField(0), m_nEndFlatField(0), m_nLength(0)
|
||||
{
|
||||
for (int i = 0; i < TD_OFFSET_COUNT; ++i)
|
||||
{
|
||||
m_nStartOffset[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Indices of start/end fields in the flattened typedescription_t list
|
||||
int m_nStartFlatField;
|
||||
int m_nEndFlatField;
|
||||
|
||||
// Offsets for run in the packed/unpacked data (I think the run starts need to be properly aligned)
|
||||
int m_nStartOffset[TD_OFFSET_COUNT];
|
||||
|
||||
int m_nLength;
|
||||
};
|
||||
|
||||
class CByteswap {
|
||||
public:
|
||||
CByteswap() {
|
||||
// Default behavior sets the target endian to match the machine native
|
||||
// endian (no swap).
|
||||
SetTargetBigEndian(IsMachineBigEndian());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Write a single field.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SwapFieldToTargetEndian(void *pOutputBuffer, void *pData,
|
||||
typedescription_t *pField);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Write a block of fields. Works a bit like the saverestore code.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SwapFieldsToTargetEndian(void *pOutputBuffer, void *pBaseData,
|
||||
datamap_t *pDataMap);
|
||||
|
||||
// Swaps fields for the templated type to the output buffer.
|
||||
template <typename T>
|
||||
inline void SwapFieldsToTargetEndian(T *pOutputBuffer, void *pBaseData,
|
||||
unsigned int objectCount = 1) {
|
||||
for (unsigned int i = 0; i < objectCount; ++i, ++pOutputBuffer) {
|
||||
SwapFieldsToTargetEndian((void *)pOutputBuffer, pBaseData,
|
||||
&T::m_DataMap);
|
||||
pBaseData = (byte *)pBaseData + sizeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
// Swaps fields for the templated type in place.
|
||||
template <typename T>
|
||||
inline void SwapFieldsToTargetEndian(T *pOutputBuffer,
|
||||
unsigned int objectCount = 1) {
|
||||
SwapFieldsToTargetEndian<T>(pOutputBuffer, (void *)pOutputBuffer,
|
||||
objectCount);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// True if the current machine is detected as big endian.
|
||||
// (Endienness is effectively detected at compile time when optimizations
|
||||
// are enabled)
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool IsMachineBigEndian() {
|
||||
short nIsBigEndian = 1;
|
||||
|
||||
// if we are big endian, the first byte will be a 0, if little endian,
|
||||
// it will be a one.
|
||||
return (bool)(0 == *(char *)&nIsBigEndian);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the target byte ordering we are swapping to or from.
|
||||
//
|
||||
// Braindead Endian Reference:
|
||||
// x86 is LITTLE Endian
|
||||
// PowerPC is BIG Endian
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void SetTargetBigEndian(bool bigEndian) {
|
||||
m_bBigEndian = bigEndian;
|
||||
m_bSwapBytes = IsMachineBigEndian() != bigEndian;
|
||||
}
|
||||
|
||||
// Changes target endian
|
||||
inline void FlipTargetEndian(void) {
|
||||
m_bSwapBytes = !m_bSwapBytes;
|
||||
m_bBigEndian = !m_bBigEndian;
|
||||
}
|
||||
|
||||
// Forces byte swapping state, regardless of endianess
|
||||
inline void ActivateByteSwapping(bool bActivate) {
|
||||
SetTargetBigEndian(IsMachineBigEndian() != bActivate);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the target machine is the same as this one in endianness.
|
||||
//
|
||||
// Used to determine when a byteswap needs to take place.
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsSwappingBytes(void) // Are bytes being swapped?
|
||||
{
|
||||
return m_bSwapBytes;
|
||||
}
|
||||
|
||||
inline bool IsTargetBigEndian(void) // What is the current target endian?
|
||||
{
|
||||
return m_bBigEndian;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IsByteSwapped()
|
||||
//
|
||||
// When supplied with a chunk of input data and a constant or magic number
|
||||
// (in native format) determines the endienness of the current machine in
|
||||
// relation to the given input data.
|
||||
//
|
||||
// Returns:
|
||||
// 1 if input is the same as nativeConstant.
|
||||
// 0 if input is byteswapped relative to nativeConstant.
|
||||
// -1 if input is not the same as nativeConstant and not byteswapped
|
||||
// either.
|
||||
//
|
||||
// ( This is useful for detecting byteswapping in magic numbers in structure
|
||||
// headers for example. )
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline int SourceIsNativeEndian(T input, T nativeConstant) {
|
||||
// If it's the same, it isn't byteswapped:
|
||||
if (input == nativeConstant) return 1;
|
||||
|
||||
int output;
|
||||
LowLevelByteSwap<T>(&output, &input);
|
||||
if (output == nativeConstant) return 0;
|
||||
|
||||
Assert(0); // if we get here, input is neither a swapped nor unswapped
|
||||
// version of nativeConstant.
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swaps an input buffer full of type T into the given output buffer.
|
||||
//
|
||||
// Swaps [count] items from the inputBuffer to the outputBuffer.
|
||||
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
|
||||
// outputBuffer - effectively swapping the contents of the buffer in place.
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void SwapBuffer(T *outputBuffer, T *inputBuffer = NULL,
|
||||
int count = 1) {
|
||||
Assert(count >= 0);
|
||||
Assert(outputBuffer);
|
||||
|
||||
// Fail gracefully in release:
|
||||
if (count <= 0 || !outputBuffer) return;
|
||||
|
||||
// Optimization for the case when we are swapping in place.
|
||||
if (inputBuffer == NULL) {
|
||||
inputBuffer = outputBuffer;
|
||||
}
|
||||
|
||||
// Swap everything in the buffer:
|
||||
for (int i = 0; i < count; i++) {
|
||||
LowLevelByteSwap<T>(&outputBuffer[i], &inputBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swaps an input buffer full of type T into the given output buffer.
|
||||
//
|
||||
// Swaps [count] items from the inputBuffer to the outputBuffer.
|
||||
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
|
||||
// outputBuffer - effectively swapping the contents of the buffer in place.
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline void SwapBufferToTargetEndian(T *outputBuffer, T *inputBuffer = NULL,
|
||||
int count = 1) {
|
||||
Assert(count >= 0);
|
||||
Assert(outputBuffer);
|
||||
|
||||
// Fail gracefully in release:
|
||||
if (count <= 0 || !outputBuffer) return;
|
||||
|
||||
// Optimization for the case when we are swapping in place.
|
||||
if (inputBuffer == NULL) {
|
||||
inputBuffer = outputBuffer;
|
||||
}
|
||||
|
||||
// Are we already the correct endienness? ( or are we swapping 1 byte
|
||||
// items? )
|
||||
if (!m_bSwapBytes || (sizeof(T) == 1)) {
|
||||
// If we were just going to swap in place then return.
|
||||
if (!inputBuffer) return;
|
||||
|
||||
// Otherwise copy the inputBuffer to the outputBuffer:
|
||||
if (outputBuffer != inputBuffer)
|
||||
memcpy(outputBuffer, inputBuffer, count * sizeof(T));
|
||||
return;
|
||||
}
|
||||
|
||||
// Swap everything in the buffer:
|
||||
for (int i = 0; i < count; i++) {
|
||||
LowLevelByteSwap<T>(&outputBuffer[i], &inputBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//-----------------------------------------------------------------------------
|
||||
// The lowest level byte swapping workhorse of doom. output always contains
|
||||
// the swapped version of input. ( Doesn't compare machine to target
|
||||
// endianness )
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
static void LowLevelByteSwap(T *output, T *input) {
|
||||
T temp = *output;
|
||||
#if defined(_X360)
|
||||
// Intrinsics need the source type to be fixed-point
|
||||
DWORD *word = (DWORD *)input;
|
||||
switch (sizeof(T)) {
|
||||
case 8: {
|
||||
__storewordbytereverse(*(word + 1), 0, &temp);
|
||||
__storewordbytereverse(*(word + 0), 4, &temp);
|
||||
} break;
|
||||
|
||||
case 4:
|
||||
__storewordbytereverse(*word, 0, &temp);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
__storeshortbytereverse(*input, 0, &temp);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Q_memcpy(&temp, input, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
Assert("Invalid size in CByteswap::LowLevelByteSwap" && 0);
|
||||
}
|
||||
#else
|
||||
for (size_t i = 0; i < sizeof(T); i++) {
|
||||
((unsigned char *)&temp)[i] =
|
||||
((unsigned char *)input)[sizeof(T) - (i + 1)];
|
||||
}
|
||||
#endif
|
||||
memcpy(output, &temp, sizeof(T));
|
||||
}
|
||||
|
||||
#if defined(_X360)
|
||||
// specialized for void * to get 360 XDK compile working despite changelist
|
||||
// 281331
|
||||
//-----------------------------------------------------------------------------
|
||||
// The lowest level byte swapping workhorse of doom. output always contains
|
||||
// the swapped version of input. ( Doesn't compare machine to target
|
||||
// endianness )
|
||||
//-----------------------------------------------------------------------------
|
||||
template <>
|
||||
static void LowLevelByteSwap(void **output, void **input) {
|
||||
AssertMsgOnce(sizeof(void *) == sizeof(unsigned int),
|
||||
"void *'s on this platform are not four bytes!");
|
||||
__storewordbytereverse(*reinterpret_cast<unsigned int *>(input), 0,
|
||||
output);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int m_bSwapBytes : 1;
|
||||
unsigned int m_bBigEndian : 1;
|
||||
};
|
||||
|
||||
#endif /* !BYTESWAP_H */
|
||||
@@ -1,12 +1,3 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// A growable memory class.
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef UTLBLOCKMEMORY_H
|
||||
#define UTLBLOCKMEMORY_H
|
||||
|
||||
|
||||
1355
csgo2/sdk/tier1/utlbuffer.h
Normal file
1355
csgo2/sdk/tier1/utlbuffer.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,3 @@
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// A growable memory class.
|
||||
//===========================================================================//
|
||||
#ifndef UTLFIXEDMEMORY_H
|
||||
#define UTLFIXEDMEMORY_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user