2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2024-12-26 14:45:34 +03:00

update rehlsdk

This commit is contained in:
s1lent 2017-07-31 22:37:50 +07:00
parent d51cc853cc
commit d90f336a75
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
13 changed files with 1656 additions and 1702 deletions

View File

@ -0,0 +1,400 @@
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
// internal structures
enum
{
MAX_GROUP_NAME_LENGTH = 48
};
struct SpewGroup_t
{
char m_GroupName[MAX_GROUP_NAME_LENGTH];
int m_Level;
};
// Templates to assist in validating pointers:
void _AssertValidReadPtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!IsBadReadPtr(ptr, count));
#else
Assert(ptr);
#endif
}
void _AssertValidWritePtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!IsBadWritePtr(ptr, count));
#else
Assert(ptr);
#endif
}
void _AssertValidReadWritePtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
Assert(!(IsBadWritePtr(ptr, count) || IsBadReadPtr(ptr, count)));
#else
Assert(ptr);
#endif
}
void AssertValidStringPtr(const char* ptr, int maxchar/* = 0xFFFFFF */)
{
#ifdef _WIN32
Assert(!IsBadStringPtr(ptr, maxchar));
#else
Assert(ptr);
#endif
}
// globals
SpewRetval_t DefaultSpewFunc(SpewType_t type, char const *pMsg)
{
printf("%s", pMsg);
if (type == SPEW_ASSERT)
return SPEW_DEBUGGER;
else if (type == SPEW_ERROR)
return SPEW_ABORT;
else
return SPEW_CONTINUE;
}
static SpewOutputFunc_t s_SpewOutputFunc = DefaultSpewFunc;
static char const* s_pFileName;
static int s_Line;
static SpewType_t s_SpewType;
static SpewGroup_t* s_pSpewGroups = 0;
static int s_GroupCount = 0;
static int s_DefaultLevel = 0;
// Spew output management.
void SpewOutputFunc(SpewOutputFunc_t func)
{
s_SpewOutputFunc = func ? func : DefaultSpewFunc;
}
SpewOutputFunc_t GetSpewOutputFunc(void)
{
if (s_SpewOutputFunc)
{
return s_SpewOutputFunc;
}
else
{
return DefaultSpewFunc;
}
}
// Spew functions
void _SpewInfo(SpewType_t type, char const* pFile, int line)
{
// Only grab the file name. Ignore the path.
char const* pSlash = strrchr(pFile, '\\');
char const* pSlash2 = strrchr(pFile, '/');
if (pSlash < pSlash2) pSlash = pSlash2;
s_pFileName = pSlash ? pSlash + 1 : pFile;
s_Line = line;
s_SpewType = type;
}
SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list args)
{
char pTempBuffer[1024];
// Printf the file and line for warning + assert only...
int len = 0;
if ((spewType == SPEW_ASSERT))
{
len = sprintf(pTempBuffer, "%s (%d) : ", s_pFileName, s_Line);
}
// Create the message....
len += vsprintf(&pTempBuffer[len], pMsgFormat, args);
// Add \n for warning and assert
if ((spewType == SPEW_ASSERT))
{
len += sprintf(&pTempBuffer[len], "\n");
}
assert(len < 1024); // use normal assert here; to avoid recursion.
assert(s_SpewOutputFunc);
// direct it to the appropriate target(s)
SpewRetval_t ret = s_SpewOutputFunc(spewType, pTempBuffer);
switch (ret)
{
// Put the break into the macro so it would occur in the right place
// case SPEW_DEBUGGER:
// DebuggerBreak();
// break;
case SPEW_ABORT:
// MessageBox(NULL,"Error in _SpewMessage","Error",MB_OK);
exit(0);
default:
break;
}
return ret;
}
SpewRetval_t _SpewMessage(char const* pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
SpewRetval_t ret = _SpewMessage(s_SpewType, pMsgFormat, args);
va_end(args);
return ret;
}
SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return SPEW_CONTINUE;
va_list args;
va_start(args, pMsgFormat);
SpewRetval_t ret = _SpewMessage(s_SpewType, pMsgFormat, args);
va_end(args);
return ret;
}
void Msg(char const* pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DMsg(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void Warning(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DWarning(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void Log(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void DLog(char const *pGroupName, int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive(pGroupName, level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void Error(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_ERROR, pMsgFormat, args);
va_end(args);
}
// A couple of super-common dynamic spew messages, here for convenience
// These looked at the "developer" group, print if it's level 1 or higher
void DevMsg(int level, char const* pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DevWarning(int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DevLog(int level, char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
void DevMsg(char const *pMsgFormat, ...)
{
if (!IsSpewActive("developer", 1))
return;
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_MESSAGE, pMsgFormat, args);
va_end(args);
}
void DevWarning(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_WARNING, pMsgFormat, args);
va_end(args);
}
void DevLog(char const *pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
_SpewMessage(SPEW_LOG, pMsgFormat, args);
va_end(args);
}
// Find a group, return true if found, false if not. Return in ind the
// index of the found group, or the index of the group right before where the
// group should be inserted into the list to maintain sorted order.
bool FindSpewGroup(char const* pGroupName, int* pInd)
{
int s = 0;
if (s_GroupCount)
{
int e = (int)(s_GroupCount - 1);
while (s <= e)
{
int m = (s + e) >> 1;
int cmp = Q_stricmp(pGroupName, s_pSpewGroups[m].m_GroupName);
if (!cmp)
{
*pInd = m;
return true;
}
if (cmp < 0)
e = m - 1;
else
s = m + 1;
}
}
*pInd = s;
return false;
}
// Sets the priority level for a spew group
void SpewActivate(char const* pGroupName, int level)
{
Assert(pGroupName);
// check for the default group first...
if ((pGroupName[0] == '*') && (pGroupName[1] == '\0'))
{
s_DefaultLevel = level;
return;
}
// Normal case, search in group list using binary search.
// If not found, grow the list of groups and insert it into the
// right place to maintain sorted order. Then set the level.
int ind;
if (!FindSpewGroup(pGroupName, &ind))
{
// not defined yet, insert an entry.
++s_GroupCount;
if (s_pSpewGroups)
{
s_pSpewGroups = (SpewGroup_t*)realloc(s_pSpewGroups,
s_GroupCount * sizeof(SpewGroup_t));
// shift elements down to preserve order
int numToMove = s_GroupCount - ind - 1;
memmove(&s_pSpewGroups[ind + 1], &s_pSpewGroups[ind],
numToMove * sizeof(SpewGroup_t));
}
else
s_pSpewGroups = (SpewGroup_t*)malloc(s_GroupCount * sizeof(SpewGroup_t));
Assert(strlen(pGroupName) < MAX_GROUP_NAME_LENGTH);
strcpy(s_pSpewGroups[ind].m_GroupName, pGroupName);
}
s_pSpewGroups[ind].m_Level = level;
}
// Tests to see if a particular spew is active
bool IsSpewActive(char const* pGroupName, int level)
{
// If we don't find the spew group, use the default level.
int ind;
if (FindSpewGroup(pGroupName, &ind))
return s_pSpewGroups[ind].m_Level >= level;
else
return s_DefaultLevel >= level;
}

View File

@ -0,0 +1,427 @@
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "basetypes.h"
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
// dll export stuff
#ifdef TIER0_DLL_EXPORT
#define DBG_INTERFACE DLL_EXPORT
#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
#define DBG_CLASS DLL_CLASS_EXPORT
#else
#define DBG_INTERFACE DLL_IMPORT
#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
#define DBG_CLASS DLL_CLASS_IMPORT
#endif
// Usage model for the Dbg library
//
// 1. Spew.
//
// Spew can be used in a static and a dynamic mode. The static
// mode allows us to display assertions and other messages either only
// in debug builds, or in non-release builds. The dynamic mode allows us to
// turn on and off certain spew messages while the application is running.
//
// Static Spew messages:
//
// Assertions are used to detect and warn about invalid states
// Spews are used to display a particular status/warning message.
//
// To use an assertion, use
//
// Assert( (f == 5) );
// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
// AssertFunc( (f == 5), BadFunc() );
// AssertEquals( f, 5 );
// AssertFloatEquals( f, 5.0f, 1e-3 );
//
// The first will simply report that an assertion failed on a particular
// code file and line. The second version will display a print-f formatted message
// along with the file and line, the third will display a generic message and
// will also cause the function BadFunc to be executed, and the last two
// will report an error if f is not equal to 5 (the last one asserts within
// a particular tolerance).
//
// To use a warning, use
//
// Warning("Oh I feel so %s all over\n", "yummy");
//
// Warning will do its magic in only Debug builds. To perform spew in *all*
// builds, use RelWarning.
//
// Three other spew types, Msg, Log, and Error, are compiled into all builds.
// These error types do *not* need two sets of parenthesis.
//
// Msg( "Isn't this exciting %d?", 5 );
// Error( "I'm just thrilled" );
//
// Dynamic Spew messages
//
// It is possible to dynamically turn spew on and off. Dynamic spew is
// identified by a spew group and priority level. To turn spew on for a
// particular spew group, use SpewActivate( "group", level ). This will
// cause all spew in that particular group with priority levels <= the
// level specified in the SpewActivate function to be printed. Use DSpew
// to perform the spew:
//
// DWarning( "group", level, "Oh I feel even yummier!\n" );
//
// Priority level 0 means that the spew will *always* be printed, and group
// '*' is the default spew group. If a DWarning is encountered using a group
// whose priority has not been set, it will use the priority of the default
// group. The priority of the default group is initially set to 0.
//
// Spew output
//
// The output of the spew system can be redirected to an externally-supplied
// function which is responsible for outputting the spew. By default, the
// spew is simply printed using printf.
//
// To redirect spew output, call SpewOutput.
//
// SpewOutputFunc( OutputFunc );
//
// This will cause OutputFunc to be called every time a spew message is
// generated. OutputFunc will be passed a spew type and a message to print.
// It must return a value indicating whether the debugger should be invoked,
// whether the program should continue running, or whether the program
// should abort.
//
// 2. Code activation
//
// To cause code to be run only in debug builds, use DBG_CODE:
// An example is below.
//
// DBG_CODE(
// {
// int x = 5;
// ++x;
// }
// );
//
// Code can be activated based on the dynamic spew groups also. Use
//
// DBG_DCODE( "group", level,
// { int x = 5; ++x; }
// );
//
// 3. Breaking into the debugger.
//
// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
//
// DBG_BREAK();
//
// You can force a break in any build (release or debug) using
//
// DebuggerBreak();
//-----------------------------------------------------------------------------
// Various types of spew messages
// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
// It's because DBG_ is used all over the place in windows.h
// For example, DBG_CONTINUE is defined. Feh.
enum SpewType_t
{
SPEW_MESSAGE = 0,
SPEW_WARNING,
SPEW_ASSERT,
SPEW_ERROR,
SPEW_LOG,
SPEW_TYPE_COUNT
};
enum SpewRetval_t
{
SPEW_DEBUGGER = 0,
SPEW_CONTINUE,
SPEW_ABORT
};
// type of externally defined function used to display debug spew
typedef SpewRetval_t(*SpewOutputFunc_t)(SpewType_t spewType, char const *pMsg);
// Used to redirect spew output
void SpewOutputFunc(SpewOutputFunc_t func);
// Used ot get the current spew output function
SpewOutputFunc_t GetSpewOutputFunc(void);
// Used to manage spew groups and subgroups
void SpewActivate(char const* pGroupName, int level);
bool IsSpewActive(char const* pGroupName, int level);
// Used to display messages, should never be called directly.
void _SpewInfo(SpewType_t type, char const* pFile, int line);
SpewRetval_t _SpewMessage(char const* pMsg, ...);
SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg, ...);
// Used to define macros, never use these directly.
#define _Assert( _exp ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
if (_SpewMessage("Assertion Failed: " #_exp) == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertMsg( _exp, _msg ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
if (_SpewMessage(_msg) == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertFunc( _exp, _f ) do { \
if (!(_exp)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Assertion Failed!" #_exp); \
_f; \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertEquals( _exp, _expectedValue ) \
do { \
if ((_exp) != (_expectedValue)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Expected %d but got %d!", (_expectedValue), (_exp)); \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
#define _AssertFloatEquals( _exp, _expectedValue, _tol ) \
do { \
if (fabs((_exp) - (_expectedValue)) > (_tol)) \
{ \
_SpewInfo( SPEW_ASSERT, __FILE__, __LINE__ ); \
SpewRetval_t ret = _SpewMessage("Expected %f but got %f!", (_expectedValue), (_exp)); \
if (ret == SPEW_DEBUGGER) \
{ \
DebuggerBreak(); \
} \
} \
} while (0)
// Spew macros...
#ifdef _DEBUG
#define Assert( _exp ) _Assert( _exp )
#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg )
#define AssertFunc( _exp, _f ) _AssertFunc( _exp, _f )
#define AssertEquals( _exp, _expectedValue ) _AssertEquals( _exp, _expectedValue )
#define AssertFloatEquals( _exp, _expectedValue, _tol ) _AssertFloatEquals( _exp, _expectedValue, _tol )
#define Verify( _exp ) _Assert( _exp )
#define AssertMsg1( _exp, _msg, a1 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1 ) )
#define AssertMsg2( _exp, _msg, a1, a2 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2 ) )
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3 ) )
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4 ) )
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 ) )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ) )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 ) )
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 ) )
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) )
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) )
#else // Not _DEBUG
#define Assert( _exp ) ((void)0)
#define AssertMsg( _exp, _msg ) ((void)0)
#define AssertFunc( _exp, _f ) ((void)0)
#define AssertEquals( _exp, _expectedValue ) ((void)0)
#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
#define Verify( _exp ) (_exp)
#define AssertMsg1( _exp, _msg, a1 ) ((void)0)
#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0)
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
#endif // _DEBUG
// These are always compiled in
void Msg(char const* pMsg, ...);
void DMsg(char const *pGroupName, int level, char const *pMsg, ...);
void Warning(char const *pMsg, ...);
void DWarning(char const *pGroupName, int level, char const *pMsg, ...);
void Log(char const *pMsg, ...);
void DLog(char const *pGroupName, int level, char const *pMsg, ...);
void Error(char const *pMsg, ...);
// You can use this macro like a runtime assert macro.
// If the condition fails, then Error is called with the message. This macro is called
// like AssertMsg, where msg must be enclosed in parenthesis:
//
// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
#define ErrorIfNot( condition, msg ) \
if ( (condition) ) \
; \
else \
{ \
Error msg; \
}
// A couple of super-common dynamic spew messages, here for convenience
// These looked at the "developer" group
void DevMsg(int level, char const* pMsg, ...);
void DevWarning(int level, char const *pMsg, ...);
void DevLog(int level, char const *pMsg, ...);
// default level versions (level 1)
void DevMsg(char const* pMsg, ...);
void DevWarning(char const *pMsg, ...);
void DevLog(char const *pMsg, ...);
// Code macros, debugger interface
#ifdef _DEBUG
#define DBG_CODE( _code ) if (0) ; else { _code }
#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
#define DBG_BREAK() DebuggerBreak() // defined in platform.h
#else // not _DEBUG
#define DBG_CODE( _code ) ((void)0)
#define DBG_DCODE( _g, _l, _code ) ((void)0)
#define DBG_BREAK() ((void)0)
#endif // _DEBUG
// Macro to assist in asserting constant invariants during compilation
#define UID_PREFIX generated_id_
#define UID_CAT1(a,c) a ## c
#define UID_CAT2(a,c) UID_CAT1(a,c)
#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
#ifdef _DEBUG
#define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
#define ASSERT_INVARIANT( pred ) static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) }
#else
#define COMPILE_TIME_ASSERT( pred )
#define ASSERT_INVARIANT( pred )
#endif
// Templates to assist in validating pointers:
// Have to use these stubs so we don't have to include windows.h here.
void _AssertValidReadPtr(void* ptr, int count = 1);
void _AssertValidWritePtr(void* ptr, int count = 1);
void _AssertValidReadWritePtr(void* ptr, int count = 1);
void AssertValidStringPtr(const char* ptr, int maxchar = 0xFFFFFF);
template<class T> inline void AssertValidReadPtr(T* ptr, int count = 1) { _AssertValidReadPtr((void*)ptr, count); }
template<class T> inline void AssertValidWritePtr(T* ptr, int count = 1) { _AssertValidWritePtr((void*)ptr, count); }
template<class T> inline void AssertValidReadWritePtr(T* ptr, int count = 1) { _AssertValidReadWritePtr((void*)ptr, count); }
#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
// Macro to protect functions that are not reentrant
#ifdef _DEBUG
class CReentryGuard
{
public:
CReentryGuard(int *pSemaphore)
: m_pSemaphore(pSemaphore)
{
++(*m_pSemaphore);
}
~CReentryGuard()
{
--(*m_pSemaphore);
}
private:
int *m_pSemaphore;
};
#define ASSERT_NO_REENTRY() \
static int fSemaphore##__LINE__; \
Assert( !fSemaphore##__LINE__ ); \
CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
#else
#define ASSERT_NO_REENTRY()
#endif
// Purpose: Inline string formatter
class CDbgFmtMsg
{
public:
CDbgFmtMsg(const char *pszFormat, ...)
{
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
_vsnprintf(m_szBuf, sizeof(m_szBuf) - 1, pszFormat, arg_ptr);
va_end(arg_ptr);
m_szBuf[sizeof(m_szBuf) - 1] = 0;
}
operator const char *() const
{
return m_szBuf;
}
private:
char m_szBuf[256];
};

View File

@ -0,0 +1,129 @@
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include "osconfig.h"
#include <malloc.h> // need this for _alloca
#include <string.h> // need this for memset
#include "archtypes.h"
// Defines MAX_PATH
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
// Used to step into the debugger
#define DebuggerBreak() __asm { int 3 }
// C functions for external declarations that call the appropriate C++ methods
#ifndef EXPORT
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT /* */
#endif
#endif
#ifdef _WIN32
// Used for dll exporting and importing
#define DLL_EXPORT extern "C" __declspec(dllexport)
#define DLL_IMPORT extern "C" __declspec(dllimport)
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT __declspec(dllexport)
#define DLL_CLASS_IMPORT __declspec(dllimport)
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern __declspec(dllexport)
#define DLL_GLOBAL_IMPORT extern __declspec(dllimport)
#elif defined __linux__
// Used for dll exporting and importing
#define DLL_EXPORT extern "C"
#define DLL_IMPORT extern "C"
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT
#define DLL_CLASS_IMPORT
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern
#define DLL_GLOBAL_IMPORT extern
#else
#error "Unsupported Platform."
#endif
#ifdef _WIN32
// Remove warnings from warning level 4.
#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning(disable : 4706) // warning C4706: assignment within conditional expression
#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined
#pragma warning(disable : 4702) // warning C4702: unreachable code
#pragma warning(disable : 4505) // unreferenced local function has been removed
#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& )
#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex'
#pragma warning(disable : 4324) // Padding was added at the end of a structure
#pragma warning(disable : 4244) // type conversion warning.
#pragma warning(disable : 4305) // truncation from 'const double ' to 'float '
#pragma warning(disable : 4786) // Disable warnings about long symbol names
#if _MSC_VER >= 1300
#pragma warning(disable : 4511) // Disable warnings about private copy constructors
#endif
#endif
// Methods to invoke the constructor, copy constructor, and destructor
template <class T>
inline void Construct(T *pMemory)
{
new(pMemory) T;
}
template <class T>
inline void CopyConstruct(T *pMemory, T const &src)
{
new(pMemory) T(src);
}
template <class T>
inline void Destruct(T *pMemory)
{
pMemory->~T();
#ifdef _DEBUG
memset(pMemory, 0xDD, sizeof(T));
#endif
}

View File

@ -1,32 +1,54 @@
//========= Copyright <20> 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#ifdef _WIN32
#pragma once
#endif
#include "interface.h"
#include <stdio.h>
#include <stdlib.h>
// There is only one instance of the IFileSystem interface,
// located in the filesystem_stdio library (filesystem_steam is obsolete).
#ifdef _WIN32
#define STDIO_FILESYSTEM_LIB "filesystem_stdio.dll"
#define STEAM_FILESYSTEM_LIB "filesystem_steam.dll"
#else
#define STDIO_FILESYSTEM_LIB "filesystem_stdio.so"
#define STEAM_FILESYSTEM_LIB "filesystem_steam.so"
#endif // _WIN32
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
typedef FILE * FileHandle_t;
typedef FILE *FileHandle_t;
typedef int FileFindHandle_t;
typedef int WaitForResourcesHandle_t;
typedef void (*WarningFunc_t)(const char *fmt, ...);
//-----------------------------------------------------------------------------
// Enums used by the interface
//-----------------------------------------------------------------------------
#ifndef FILESYSTEM_INTERNAL_H
typedef enum
{
@ -42,148 +64,138 @@ enum
typedef enum
{
// Don't print anything
FILESYSTEM_WARNING_QUIET = 0,
// On shutdown, report names of files left unclosed
FILESYSTEM_WARNING_REPORTUNCLOSED,
// Report number of times a file was opened, closed
FILESYSTEM_WARNING_REPORTUSAGE,
// Report all open/close events to console ( !slow! )
FILESYSTEM_WARNING_REPORTALLACCESSES
FILESYSTEM_WARNING_QUIET = 0, // Don't print anything
FILESYSTEM_WARNING_REPORTUNCLOSED, // On shutdown, report names of files left unclosed
FILESYSTEM_WARNING_REPORTUSAGE, // Report number of times a file was opened, closed
FILESYSTEM_WARNING_REPORTALLACCESSES // Report all open/close events to console (!slow!)
} FileWarningLevel_t;
#define FILESYSTEM_INVALID_HANDLE ( FileHandle_t )0
#endif
#define FILESYSTEM_INVALID_HANDLE (FileHandle_t)0
#endif // FILESYSTEM_INTERNAL_H
// turn off any windows defines
#undef GetCurrentDirectory
//-----------------------------------------------------------------------------
// Purpose: Main file system interface
//-----------------------------------------------------------------------------
class IFileSystem : public IBaseInterface
{
public:
// Mount and unmount the filesystem
virtual void Mount( void ) = 0;
virtual void Unmount( void ) = 0;
virtual void Mount() = 0;
virtual void Unmount() = 0;
// Remove all search paths (including write path?)
virtual void RemoveAllSearchPaths( void ) = 0;
virtual void RemoveAllSearchPaths() = 0;
// Add paths in priority order (mod dir, game dir, ....)
// If one or more .pak files are in the specified directory, then they are
// added after the file system path
// If the path is the relative path to a .bsp file, then any previous .bsp file
// If the path is the relative path to a .bsp file, then any previous .bsp file
// override is cleared and the current .bsp is searched for an embedded PAK file
// and this file becomes the highest priority search path ( i.e., it's looked at first
// even before the mod's file system path ).
virtual void AddSearchPath( const char *pPath, const char *pathID ) = 0;
virtual bool RemoveSearchPath( const char *pPath ) = 0;
// and this file becomes the highest priority search path (i.e., it's looked at first
// even before the mod's file system path).
virtual void AddSearchPath(const char *pPath, const char *pathID) = 0;
virtual bool RemoveSearchPath(const char *pPath) = 0;
// Deletes a file
virtual void RemoveFile( const char *pRelativePath, const char *pathID ) = 0;
virtual void RemoveFile(const char *pRelativePath, const char *pathID) = 0;
// this isn't implementable on STEAM as is.
virtual void CreateDirHierarchy( const char *path, const char *pathID ) = 0;
virtual void CreateDirHierarchy(const char *path, const char *pathID) = 0;
// File I/O and info
virtual bool FileExists( const char *pFileName ) = 0;
virtual bool IsDirectory( const char *pFileName ) = 0;
virtual bool FileExists(const char *pFileName) = 0;
virtual bool IsDirectory(const char *pFileName) = 0;
// opens a file
// if pathID is NULL, all paths will be searched for the file
virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0;
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0L) = 0;
virtual void Close( FileHandle_t file ) = 0;
virtual void Close(FileHandle_t file) = 0;
virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) = 0;
virtual unsigned int Tell( FileHandle_t file ) = 0;
virtual void Seek(FileHandle_t file, int pos, FileSystemSeek_t seekType) = 0;
virtual unsigned int Tell(FileHandle_t file) = 0;
virtual unsigned int Size( FileHandle_t file ) = 0;
virtual unsigned int Size( const char *pFileName ) = 0;
virtual unsigned int Size(FileHandle_t file) = 0;
virtual unsigned int Size(const char *pFileName) = 0;
virtual long GetFileTime( const char *pFileName ) = 0;
virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) = 0;
virtual long GetFileTime(const char *pFileName) = 0;
virtual void FileTimeToString(char *pStrip, int maxCharsIncludingTerminator, long fileTime) = 0;
virtual bool IsOk( FileHandle_t file ) = 0;
virtual bool IsOk(FileHandle_t file) = 0;
virtual void Flush( FileHandle_t file ) = 0;
virtual bool EndOfFile( FileHandle_t file ) = 0;
virtual void Flush(FileHandle_t file) = 0;
virtual bool EndOfFile(FileHandle_t file) = 0;
virtual int Read( void* pOutput, int size, FileHandle_t file ) = 0;
virtual int Write( void const* pInput, int size, FileHandle_t file ) = 0;
virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) = 0;
virtual int FPrintf( FileHandle_t file, char *pFormat, ... ) = 0;
virtual int Read(void *pOutput, int size, FileHandle_t file) = 0;
virtual int Write(void const *pInput, int size, FileHandle_t file) = 0;
virtual char *ReadLine(char *pOutput, int maxChars, FileHandle_t file) = 0;
virtual int FPrintf(FileHandle_t file, char *pFormat, ...) = 0;
// direct filesystem buffer access
// returns a handle to a buffer containing the file data
// this is the optimal way to access the complete data for a file,
// this is the optimal way to access the complete data for a file,
// since the file preloader has probably already got it in memory
virtual void *GetReadBuffer( FileHandle_t file, int *outBufferSize, bool failIfNotInCache ) = 0;
virtual void ReleaseReadBuffer( FileHandle_t file, void *readBuffer ) = 0;
virtual void *GetReadBuffer(FileHandle_t file, int *outBufferSize, bool failIfNotInCache) = 0;
virtual void ReleaseReadBuffer(FileHandle_t file, void *readBuffer) = 0;
// FindFirst/FindNext
virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID = 0L ) = 0;
virtual const char *FindNext( FileFindHandle_t handle ) = 0;
virtual bool FindIsDirectory( FileFindHandle_t handle ) = 0;
virtual void FindClose( FileFindHandle_t handle ) = 0;
virtual const char *FindFirst(const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID = 0L) = 0;
virtual const char *FindNext(FileFindHandle_t handle) = 0;
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
virtual void FindClose(FileFindHandle_t handle) = 0;
virtual void GetLocalCopy( const char *pFileName ) = 0;
virtual void GetLocalCopy(const char *pFileName) = 0;
virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0;
virtual const char *GetLocalPath(const char *pFileName, char *pLocalPath, int localPathBufferSize) = 0;
// Note: This is sort of a secondary feature; but it's really useful to have it here
virtual char *ParseFile( char* pFileBytes, char* pToken, bool* pWasQuoted ) = 0;
virtual char *ParseFile(char *pFileBytes, char *pToken, bool *pWasQuoted) = 0;
// Returns true on success ( based on current list of search paths, otherwise false if it can't be resolved )
virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative ) = 0;
// Returns true on success (based on current list of search paths, otherwise false if it can't be resolved)
virtual bool FullPathToRelativePath(const char *pFullpath, char *pRelative) = 0;
// Gets the current working directory
virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0;
virtual bool GetCurrentDirectory(char *pDirectory, int maxlen) = 0;
// Dump to printf/OutputDebugString the list of files that have not been closed
virtual void PrintOpenedFiles( void ) = 0;
virtual void PrintOpenedFiles() = 0;
virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) ) = 0;
virtual void SetWarningLevel( FileWarningLevel_t level ) = 0;
virtual void SetWarningFunc(WarningFunc_t pfnWarning) = 0;
virtual void SetWarningLevel(FileWarningLevel_t level) = 0;
virtual void LogLevelLoadStarted( const char *name ) = 0;
virtual void LogLevelLoadFinished( const char *name ) = 0;
virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) = 0;
virtual int PauseResourcePreloading( void ) = 0;
virtual int ResumeResourcePreloading( void ) = 0;
virtual int SetVBuf( FileHandle_t stream, char *buffer, int mode, long size ) = 0;
virtual void GetInterfaceVersion( char *p, int maxlen ) = 0;
virtual void LogLevelLoadStarted(const char *name) = 0;
virtual void LogLevelLoadFinished(const char *name) = 0;
virtual int HintResourceNeed(const char *hintlist, int forgetEverything) = 0;
virtual int PauseResourcePreloading() = 0;
virtual int ResumeResourcePreloading() = 0;
virtual int SetVBuf(FileHandle_t stream, char *buffer, int mode, long size) = 0;
virtual void GetInterfaceVersion(char *p, int maxlen) = 0;
virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0;
// starts waiting for resources to be available
// returns FILESYSTEM_INVALID_HANDLE if there is nothing to wait on
virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) = 0;
virtual WaitForResourcesHandle_t WaitForResources(const char *resourcelist) = 0;
// get progress on waiting for resources; progress is a float [0, 1], complete is true on the waiting being done
// returns false if no progress is available
// any calls after complete is true or on an invalid handle will return false, 0.0f, true
virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */ ) = 0;
virtual bool GetWaitForResourcesProgress(WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */) = 0;
// cancels a progress call
virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) = 0;
virtual void CancelWaitForResources(WaitForResourcesHandle_t handle) = 0;
// returns true if the appID has all its caches fully preloaded
virtual bool IsAppReadyForOfflinePlay( int appID ) = 0;
virtual bool IsAppReadyForOfflinePlay(int appID) = 0;
// interface for custom pack files > 4Gb
virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0;
// open a file but force the data to come from the steam cache, NOT from disk
virtual FileHandle_t OpenFromCacheForRead( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0;
virtual bool AddPackFile(const char *fullpath, const char *pathID) = 0;
virtual void AddSearchPathNoWrite( const char *pPath, const char *pathID ) = 0;
// open a file but force the data to come from the steam cache, NOT from disk
virtual FileHandle_t OpenFromCacheForRead(const char *pFileName, const char *pOptions, const char *pathID = 0L) = 0;
virtual void AddSearchPathNoWrite(const char *pPath, const char *pathID) = 0;
};
// Steam3/Src compat
#define IBaseFileSystem IFileSystem
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem009"
#endif // FILESYSTEM_H

View File

@ -1,9 +1,30 @@
//========= Copyright 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef BASETYPES_H
#define BASETYPES_H
@ -12,9 +33,9 @@
#endif
#include "osconfig.h"
#include "protected_things.h"
#include "commonmacros.h"
#include "archtypes.h"
#include "mathlib.h"
// For backward compatibilty only...
@ -25,32 +46,16 @@
#define NULL 0
#endif
#define ExecuteNTimes( nTimes, x ) \
{ \
static int __executeCount=0;\
if ( __executeCount < nTimes )\
{ \
x; \
++__executeCount; \
} \
}
#define ExecuteOnce( x ) ExecuteNTimes( 1, x )
// Pad a number so it lies on an N byte boundary.
// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
#define PAD_NUMBER(number, boundary) \
( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
(((number) + ((boundary) - 1)) / (boundary)) * (boundary)
#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
#endif
typedef int BOOL;
typedef int qboolean;
typedef unsigned long ULONG;
@ -60,216 +65,14 @@ typedef unsigned short word;
typedef float vec_t;
// FIXME: this should move
#ifndef __cplusplus
#define true TRUE
#define false FALSE
#endif
//-----------------------------------------------------------------------------
// look for NANs, infinities, and underflows.
// This assumes the ANSI/IEEE 754-1985 standard
//-----------------------------------------------------------------------------
#ifdef __cplusplus
inline unsigned long& FloatBits(vec_t& f)
{
return *reinterpret_cast<unsigned long*>(&f);
}
inline unsigned long const& FloatBits(vec_t const& f)
{
return *reinterpret_cast<unsigned long const*>(&f);
}
inline vec_t BitsToFloat(unsigned long i)
{
return *reinterpret_cast<vec_t*>(&i);
}
inline bool IsFinite(vec_t f)
{
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
}
inline unsigned long FloatAbsBits(vec_t f)
{
return FloatBits(f) & 0x7FFFFFFF;
}
inline float FloatMakeNegative(vec_t f)
{
return BitsToFloat(FloatBits(f) | 0x80000000);
}
#if defined( WIN32 )
//#include <math.h>
// Just use prototype from math.h
#ifdef __cplusplus
extern "C"
{
#endif
double __cdecl fabs(double);
#ifdef __cplusplus
}
#endif
// In win32 try to use the intrinsic fabs so the optimizer can do it's thing inline in the code
#pragma intrinsic( fabs )
// Also, alias float make positive to use fabs, too
// NOTE: Is there a perf issue with double<->float conversion?
inline float FloatMakePositive(vec_t f)
{
return fabs(f);
}
#else
inline float FloatMakePositive(vec_t f)
{
return BitsToFloat(FloatBits(f) & 0x7FFFFFFF);
}
#endif
inline float FloatNegate(vec_t f)
{
return BitsToFloat(FloatBits(f) ^ 0x80000000);
}
#define FLOAT32_NAN_BITS (unsigned long)0x7FC00000 // not a number!
#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
#define VEC_T_NAN FLOAT32_NAN
#endif
// FIXME: why are these here? Hardly anyone actually needs them.
struct valve_color24
{
byte r, g, b;
};
typedef struct valve_color32_s
{
bool operator!=(const struct valve_color32_s &other) const;
byte r, g, b, a;
} valve_color32;
inline bool valve_color32::operator!=(const valve_color32 &other) const
{
return r != other.r || g != other.g || b != other.b || a != other.a;
}
struct valve_colorRGBExp32
{
byte r, g, b;
signed char exponent;
};
struct valve_colorVec
{
unsigned r, g, b, a;
};
#ifndef UNUSED
#define UNUSED(x) (x = x) // for pesky compiler / lint warnings
#endif
#ifdef __cplusplus
struct vrect_t
{
int x, y, width, height;
vrect_t *pnext;
int x, y, width, height;
vrect_t *pnext;
};
#endif
//-----------------------------------------------------------------------------
// MaterialRect_t struct - used for DrawDebugText
//-----------------------------------------------------------------------------
struct Rect_t
{
int x, y;
int width, height;
};
//-----------------------------------------------------------------------------
// Declares a type-safe handle type; you can't assign one handle to the next
//-----------------------------------------------------------------------------
// 32-bit pointer handles.
// Typesafe 8-bit and 16-bit handles.
template< class HandleType >
class CBaseIntHandle
{
public:
inline bool operator==(const CBaseIntHandle &other) { return m_Handle == other.m_Handle; }
inline bool operator!=(const CBaseIntHandle &other) { return m_Handle != other.m_Handle; }
// Only the code that doles out these handles should use these functions.
// Everyone else should treat them as a transparent type.
inline HandleType GetHandleValue() { return m_Handle; }
inline void SetHandleValue(HandleType val) { m_Handle = val; }
typedef HandleType HANDLE_TYPE;
protected:
HandleType m_Handle;
};
template< class DummyType >
class CIntHandle16 : public CBaseIntHandle < unsigned short >
{
public:
inline CIntHandle16() {}
static inline CIntHandle16<DummyType> MakeHandle(HANDLE_TYPE val)
{
return CIntHandle16<DummyType>(val);
}
protected:
inline CIntHandle16(HANDLE_TYPE val)
{
m_Handle = val;
}
};
template< class DummyType >
class CIntHandle32 : public CBaseIntHandle < unsigned long >
{
public:
inline CIntHandle32() {}
static inline CIntHandle32<DummyType> MakeHandle(HANDLE_TYPE val)
{
return CIntHandle32<DummyType>(val);
}
protected:
inline CIntHandle32(HANDLE_TYPE val)
{
m_Handle = val;
}
};
// NOTE: This macro is the same as windows uses; so don't change the guts of it
#define DECLARE_HANDLE_16BIT(name) typedef CIntHandle16< struct name##__handle * > name;
#define DECLARE_HANDLE_32BIT(name) typedef CIntHandle32< struct name##__handle * > name;
#define DECLARE_POINTER_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#define FORWARD_DECLARE_HANDLE(name) typedef struct name##__ *name
#endif // BASETYPES_H

View File

@ -1,26 +1,98 @@
#include "precompiled.h"
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "interface.h"
#if !defined ( _WIN32 )
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif // _WIN32
// InterfaceReg
InterfaceReg *InterfaceReg::s_pInterfaceRegs = nullptr;
InterfaceReg::InterfaceReg(InstantiateInterfaceFn fn, const char *pName) : m_pName(pName)
{
m_CreateFn = fn;
m_pNext = s_pInterfaceRegs;
s_pInterfaceRegs = this;
}
// This is the primary exported function by a dll, referenced by name via dynamic binding
// that exposes an opqaue function pointer to the interface.
//
// We have the Internal variant so Sys_GetFactoryThis() returns the correct internal
// symbol under GCC/Linux/Mac as CreateInterface is DLL_EXPORT so its global so the loaders
// on those OS's pick exactly 1 of the CreateInterface symbols to be the one that is process wide and
// all Sys_GetFactoryThis() calls find that one, which doesn't work. Using the internal walkthrough here
// makes sure Sys_GetFactoryThis() has the dll specific symbol and GetProcAddress() returns the module specific
// function for CreateInterface again getting the dll specific symbol we need.
EXPORT_FUNCTION IBaseInterface *CreateInterface(const char *pName, int *pReturnCode)
{
InterfaceReg *pCur;
for (pCur = InterfaceReg::s_pInterfaceRegs; pCur; pCur = pCur->m_pNext)
{
if (strcmp(pCur->m_pName, pName) == 0)
{
if (pReturnCode)
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if (pReturnCode)
{
*pReturnCode = IFACE_FAILED;
}
return nullptr;
}
#ifndef _WIN32
// Linux doesn't have this function so this emulates its functionality
//
//
void *GetModuleHandle(const char *name)
{
void *handle;
if (name == NULL)
if (name == nullptr)
{
// hmm, how can this be handled under linux....
// is it even needed?
return NULL;
return nullptr;
}
if ((handle=dlopen(name, RTLD_NOW)) == NULL)
if ((handle = dlopen(name, RTLD_NOW)) == nullptr)
{
//printf("Error:%s\n",dlerror());
// couldn't open this file
return NULL;
return nullptr;
}
// read "man dlopen" for details
@ -29,151 +101,67 @@ void *GetModuleHandle(const char *name)
dlclose(handle);
return handle;
}
#endif
#endif // _WIN32
// ------------------------------------------------------------------------------------ //
// InterfaceReg.
// ------------------------------------------------------------------------------------ //
InterfaceReg *InterfaceReg::s_pInterfaceRegs = NULL;
InterfaceReg::InterfaceReg( InstantiateInterfaceFn fn, const char *pName ) : m_pName(pName)
{
m_CreateFn = fn;
m_pNext = s_pInterfaceRegs;
s_pInterfaceRegs = this;
}
// ------------------------------------------------------------------------------------ //
// CreateInterface.
// ------------------------------------------------------------------------------------ //
EXPORT_FUNCTION IBaseInterface *CreateInterface( const char *pName, int *pReturnCode )
{
InterfaceReg *pCur;
for(pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext)
{
if(strcmp(pCur->m_pName, pName) == 0)
{
if ( pReturnCode )
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if ( pReturnCode )
{
*pReturnCode = IFACE_FAILED;
}
return NULL;
}
#ifdef LINUX
static IBaseInterface *CreateInterfaceLocal( const char *pName, int *pReturnCode )
{
InterfaceReg *pCur;
for(pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext)
{
if(strcmp(pCur->m_pName, pName) == 0)
{
if ( pReturnCode )
{
*pReturnCode = IFACE_OK;
}
return pCur->m_CreateFn();
}
}
if ( pReturnCode )
{
*pReturnCode = IFACE_FAILED;
}
return NULL;
}
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : pModuleName - module name
// *pName - proc name
//-----------------------------------------------------------------------------
//static hlds_run wants to use this function
void *Sys_GetProcAddress( const char *pModuleName, const char *pName )
//static hlds_run wants to use this function
void *Sys_GetProcAddress(const char *pModuleName, const char *pName)
{
return GetProcAddress( GetModuleHandle(pModuleName), pName );
return GetProcAddress(GetModuleHandle(pModuleName), pName);
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : pModuleName - module name
// *pName - proc name
//-----------------------------------------------------------------------------
// hlds_run wants to use this function
void *Sys_GetProcAddress( void *pModuleHandle, const char *pName )
// hlds_run wants to use this function
void *Sys_GetProcAddress(void *pModuleHandle, const char *pName)
{
#if defined ( _WIN32 )
return GetProcAddress( (HINSTANCE)pModuleHandle, pName );
#else
return GetProcAddress( pModuleHandle, pName );
#endif
return GetProcAddress((HMODULE)pModuleHandle, pName);
}
//-----------------------------------------------------------------------------
// Purpose: Loads a DLL/component from disk and returns a handle to it
// Input : *pModuleName - filename of the component
// Output : opaque handle to the module (hides system dependency)
//-----------------------------------------------------------------------------
CSysModule *Sys_LoadModule( const char *pModuleName )
CSysModule *Sys_LoadModule(const char *pModuleName)
{
#if defined ( _WIN32 )
HMODULE hDLL = LoadLibrary( pModuleName );
#ifdef _WIN32
HMODULE hDLL = LoadLibrary(pModuleName);
#else
HMODULE hDLL = NULL;
HMODULE hDLL = nullptr;
char szAbsoluteModuleName[1024];
szAbsoluteModuleName[0] = 0;
if ( pModuleName[0] != '/' )
if (pModuleName[0] != '/')
{
char szCwd[1024];
char szAbsoluteModuleName[1024];
getcwd(szCwd, sizeof(szCwd));
if (szCwd[strlen(szCwd) - 1] == '/')
szCwd[strlen(szCwd) - 1] = '\0';
getcwd( szCwd, sizeof( szCwd ) );
if ( szCwd[ strlen( szCwd ) - 1 ] == '/' )
szCwd[ strlen( szCwd ) - 1 ] = 0;
_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName );
hDLL = dlopen( szAbsoluteModuleName, RTLD_NOW );
_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", szCwd, pModuleName);
hDLL = dlopen(szAbsoluteModuleName, RTLD_NOW);
}
else
{
_snprintf( szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s", pModuleName );
hDLL = dlopen( pModuleName, RTLD_NOW );
_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s", pModuleName);
hDLL = dlopen(pModuleName, RTLD_NOW);
}
#endif
#endif // _WIN32
if( !hDLL )
if (!hDLL)
{
char str[512];
#if defined ( _WIN32 )
_snprintf( str, sizeof(str), "%s.dll", pModuleName );
hDLL = LoadLibrary( str );
#if defined(_WIN32)
_snprintf(str, sizeof(str), "%s.dll", pModuleName);
hDLL = LoadLibrary(str);
#elif defined(OSX)
printf("Error:%s\n",dlerror());
_snprintf( str, sizeof(str), "%s.dylib", szAbsoluteModuleName );
hDLL = dlopen(str, RTLD_NOW);
printf("Error: %s\n", dlerror());
_snprintf(str, sizeof(str), "%s.dylib", szAbsoluteModuleName);
hDLL = dlopen(str, RTLD_NOW);
#else
printf("Error:%s\n",dlerror());
_snprintf( str, sizeof(str), "%s.so", szAbsoluteModuleName );
printf("Error: %s\n", dlerror());
_snprintf(str, sizeof(str), "%s.so", szAbsoluteModuleName);
hDLL = dlopen(str, RTLD_NOW);
#endif
}
@ -181,83 +169,68 @@ CSysModule *Sys_LoadModule( const char *pModuleName )
return reinterpret_cast<CSysModule *>(hDLL);
}
//-----------------------------------------------------------------------------
// Purpose: Unloads a DLL/component from
// Input : *pModuleName - filename of the component
// Output : opaque handle to the module (hides system dependency)
//-----------------------------------------------------------------------------
void Sys_UnloadModule( CSysModule *pModule )
void Sys_UnloadModule(CSysModule *pModule)
{
if ( !pModule )
if (!pModule)
return;
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
#if defined ( _WIN32 )
FreeLibrary( hDLL );
#else
dlclose((void *)hDLL);
#endif
#ifdef _WIN32
FreeLibrary(hDLL);
#else
dlclose(hDLL);
#endif // _WIN32
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to a function, given a module
// Input : module - windows HMODULE from Sys_LoadModule()
// Input : module - windows HMODULE from Sys_LoadModule()
// *pName - proc name
// Output : factory for this module
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactory( CSysModule *pModule )
CreateInterfaceFn Sys_GetFactory(CSysModule *pModule)
{
if ( !pModule )
return NULL;
if (!pModule)
return nullptr;
HMODULE hDLL = reinterpret_cast<HMODULE>(pModule);
#if defined ( _WIN32 )
return reinterpret_cast<CreateInterfaceFn>(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
#else
// Linux gives this error:
//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory
//(CSysModule *)) (const char *, int *)':
//../public/interface.cpp:154: ISO C++ forbids casting between
//pointer-to-function and pointer-to-object
//
// so lets get around it :)
return (CreateInterfaceFn)(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME ));
#endif
return reinterpret_cast<CreateInterfaceFn>(Sys_GetProcAddress(pModule, CREATEINTERFACE_PROCNAME));
}
//-----------------------------------------------------------------------------
// Purpose: returns the instance of this module
// Output : interface_instance_t
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactoryThis( void )
// Output : CreateInterfaceFn
CreateInterfaceFn Sys_GetFactoryThis()
{
#ifdef LINUX
return CreateInterfaceLocal;
#else
return CreateInterface;
#endif
}
//-----------------------------------------------------------------------------
// Purpose: returns the instance of the named module
// Input : *pModuleName - name of the module
// Output : interface_instance_t - instance of that module
//-----------------------------------------------------------------------------
CreateInterfaceFn Sys_GetFactory( const char *pModuleName )
// Output : CreateInterfaceFn - instance of that module
CreateInterfaceFn Sys_GetFactory(const char *pModuleName)
{
#if defined ( _WIN32 )
return static_cast<CreateInterfaceFn>( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
#else
// Linux gives this error:
//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory
//(const char *)) (const char *, int *)':
//../public/interface.cpp:186: invalid static_cast from type `void *' to
//type `IBaseInterface *(*) (const char *, int *)'
//
// so lets use the old style cast.
return (CreateInterfaceFn)( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) );
#endif
return reinterpret_cast<CreateInterfaceFn>(Sys_GetProcAddress(pModuleName, CREATEINTERFACE_PROCNAME));
}
// Purpose: finds a particular interface in the factory set
void *InitializeInterface(char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories)
{
void *retval;
for (int i = 0; i < numFactories; i++)
{
CreateInterfaceFn factory = factoryList[ i ];
if (!factory)
continue;
retval = factory(interfaceName, nullptr);
if (retval)
return retval;
}
// No provider for requested interface!!!
// assert(!"No provider for requested interface!!!");
return nullptr;
}

View File

@ -1,4 +1,3 @@
// This header defines the interface convention used in the valve engine.
// To make an interface and expose it:
// 1. Derive from IBaseInterface.
@ -8,22 +7,17 @@
// Versioning
// There are two versioning cases that are handled by this:
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface.
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// expose it for the old interface.
//#if _MSC_VER >= 1300 // VC7
//#include "tier1/interface.h"
//#else
#pragma once
#ifndef INTERFACE_H
#define INTERFACE_H
#ifndef _WIN32
#if !defined ( _WIN32 )
#include <dlfcn.h> // dlopen,dlclose, et al
#include <dlfcn.h> // dlopen, dlclose, et al
#include <unistd.h>
#define HMODULE void *
@ -31,7 +25,7 @@
#define _snprintf snprintf
#endif
#endif // _WIN32
void *Sys_GetProcAddress(const char *pModuleName, const char *pName);
void *Sys_GetProcAddress(void *pModuleHandle, const char *pName);
@ -40,17 +34,13 @@ void *Sys_GetProcAddress(void *pModuleHandle, const char *pName);
class IBaseInterface
{
public:
virtual ~IBaseInterface() {}
virtual ~IBaseInterface() {}
};
#define CREATEINTERFACE_PROCNAME "CreateInterface"
#define CREATEINTERFACE_PROCNAME "CreateInterface"
typedef IBaseInterface* (*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef IBaseInterface* (*InstantiateInterfaceFn)();
typedef IBaseInterface *(*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef IBaseInterface *(*InstantiateInterfaceFn)();
// Used internally to register classes.
class InterfaceReg
@ -60,19 +50,18 @@ public:
public:
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InterfaceReg *m_pNext; // For the global list.
static InterfaceReg *s_pInterfaceRegs;
InterfaceReg *m_pNext; // For the global list.
static InterfaceReg *s_pInterfaceRegs;
};
// Use this to expose an interface that can have multiple instances.
// e.g.:
// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" )
// EXPOSE_INTERFACE(CInterfaceImp, IInterface, "MyInterface001")
// This will expose a class called CInterfaceImp that implements IInterface (a pure class)
// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" )
// clients can receive a pointer to this class by calling CreateInterface("MyInterface001")
//
// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001")
// so that each component can use these names/vtables to communicate
@ -80,71 +69,55 @@ public:
// A single class can support multiple interfaces through multiple inheritance
//
// Use this if you want to write the factory function.
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName)\
static InterfaceReg __g_Create##className##_reg(functionName, versionName);
#define EXPOSE_INTERFACE(className, interfaceName, versionName) \
static IBaseInterface* __Create##className##_interface() {return (interfaceName *)new className;}\
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName );
#define EXPOSE_INTERFACE(className, interfaceName, versionName)\
static IBaseInterface *__Create##className##_interface() {return (interfaceName *)new className;}\
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName);
// Use this to expose a singleton interface with a global variable you've created.
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \
static IBaseInterface* __Create##className##interfaceName##_interface() {return (IBaseInterface *)&globalVarName;}\
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName)\
static IBaseInterface *__Create##className##interfaceName##_interface() {return (IBaseInterface *)&globalVarName;}\
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName);
// Use this to expose a singleton interface. This creates the global variable for you automatically.
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName)\
static className __g_##className##_singleton;\
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#ifdef _WIN32
#define EXPORT_FUNCTION __declspec(dllexport)
#else
#define EXPORT_FUNCTION __attribute__ ((visibility("default")))
#endif
#define EXPORT_FUNCTION __attribute__((visibility("default")))
#endif // _WIN32
// This function is automatically exported and allows you to access any interfaces exposed with the above macros.
// if pReturnCode is set, it will return one of the following values
// extend this for other error conditions/code
enum
enum
{
IFACE_OK = 0,
IFACE_FAILED
};
extern "C"
{
EXPORT_FUNCTION IBaseInterface* CreateInterface(const char *pName, int *pReturnCode);
EXPORT_FUNCTION IBaseInterface *CreateInterface(const char *pName, int *pReturnCode);
};
extern CreateInterfaceFn Sys_GetFactoryThis();
extern CreateInterfaceFn Sys_GetFactoryThis( void );
//-----------------------------------------------------------------------------
// UNDONE: This is obsolete, use the module load/unload/get instead!!!
//-----------------------------------------------------------------------------
extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName );
extern CreateInterfaceFn Sys_GetFactory(const char *pModuleName);
// load/unload components
class CSysModule;
//-----------------------------------------------------------------------------
// Load & Unload should be called in exactly one place for each module
// The factory for that module should be passed on to dependent components for
// proper versioning.
//-----------------------------------------------------------------------------
extern CSysModule *Sys_LoadModule( const char *pModuleName );
extern void Sys_UnloadModule( CSysModule *pModule );
extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule );
#endif
//#endif // MSVC 6.0
extern CSysModule *Sys_LoadModule(const char *pModuleName);
extern void Sys_UnloadModule(CSysModule *pModule);
extern CreateInterfaceFn Sys_GetFactory(CSysModule *pModule);
extern void *InitializeInterface(char const *interfaceName, CreateInterfaceFn *factoryList, int numFactories);

View File

@ -1,187 +0,0 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PROTECTED_THINGS_H
#define PROTECTED_THINGS_H
#ifdef _WIN32
#pragma once
#endif
// This header tries to prevent people from using potentially dangerous functions
// (like the notorious non-null-terminating strncpy) and functions that will break
// VCR mode (like time, input, registry, etc).
//
// This header should be included by ALL of our source code.
// Eventually, ALL of these should be protected, but one man can only accomplish so much in
// one day AND work on features too!
#if defined( PROTECT_STRING_FUNCTIONS )
#if defined( strncpy )
#undef strncpy
#endif
#define strncpy strncpy__HEY_YOU__USE_VSTDLIB
#if defined( _snprintf )
#undef _snprintf
#endif
#define _snprintf snprintf__HEY_YOU__USE_VSTDLIB
#if defined( sprintf )
#undef sprintf
#endif
#define sprintf sprintf__HEY_YOU__USE_VSTDLIB
#if defined( _vsnprintf )
#undef _vsnprintf
#endif
#define _vsnprintf vsnprintf__HEY_YOU__USE_VSTDLIB
#if defined( strcat )
#undef strcat
#endif
#define strcat strcat__HEY_YOU__USE_VSTDLIB
#endif
#if defined( PROTECT_FILEIO_FUNCTIONS )
#if defined( fopen )
#undef fopen
#endif
#define fopen fopen_USE_FILESYSTEM_INSTEAD
#endif
#if defined( PROTECTED_THINGS_ENABLE )
#if defined( GetTickCount )
#undef GetTickCount
#endif
#define GetTickCount GetTickCount__HEY_YOU__USE_PLATFORM_LIB
#if defined( timeGetTime )
#undef timeGetTime
#endif
#define timeGetTime timeGetTime__HEY_YOU__USE_PLATFORM_LIB
#if defined( clock )
#undef clock
#endif
#define time time__HEY_YOU__USE_PLATFORM_LIB
#if defined( recvfrom )
#undef recvfrom
#endif
#define recvfrom recvfrom__HEY_YOU__USE_PLATFORM_LIB
#if defined( GetCursorPos )
#undef GetCursorPos
#endif
#define GetCursorPos GetCursorPos__HEY_YOU__USE_PLATFORM_LIB
#if defined( ScreenToClient )
#undef ScreenToClient
#endif
#define ScreenToClient ScreenToClient__HEY_YOU__USE_PLATFORM_LIB
#if defined( GetCommandLine )
#undef GetCommandLine
#endif
#define GetCommandLine GetCommandLine__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegOpenKeyEx )
#undef RegOpenKeyEx
#endif
#define RegOpenKeyEx RegOpenKeyEx__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegOpenKey )
#undef RegOpenKey
#endif
#define RegOpenKey RegOpenKey__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegSetValueEx )
#undef RegSetValueEx
#endif
#define RegSetValueEx RegSetValueEx__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegSetValue )
#undef RegSetValue
#endif
#define RegSetValue RegSetValue__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegQueryValueEx )
#undef RegQueryValueEx
#endif
#define RegQueryValueEx RegQueryValueEx__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegQueryValue )
#undef RegQueryValue
#endif
#define RegQueryValue RegQueryValue__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegCreateKeyEx )
#undef RegCreateKeyEx
#endif
#define RegCreateKeyEx RegCreateKeyEx__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegCreateKey )
#undef RegCreateKey
#endif
#define RegCreateKey RegCreateKey__HEY_YOU__USE_PLATFORM_LIB
#if defined( RegCloseKey )
#undef RegCloseKey
#endif
#define RegCloseKey RegCloseKey__HEY_YOU__USE_PLATFORM_LIB
#if defined( GetNumberOfConsoleInputEvents )
#undef GetNumberOfConsoleInputEvents
#endif
#define GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents__HEY_YOU__USE_PLATFORM_LIB
#if defined( ReadConsoleInput )
#undef ReadConsoleInput
#endif
#define ReadConsoleInput ReadConsoleInput__HEY_YOU__USE_PLATFORM_LIB
#if defined( GetAsyncKeyState )
#undef GetAsyncKeyState
#endif
#define GetAsyncKeyState GetAsyncKeyState__HEY_YOU__USE_PLATFORM_LIB
#if defined( GetKeyState )
#undef GetKeyState
#endif
#define GetKeyState GetKeyState__HEY_YOU__USE_PLATFORM_LIB
#endif
#endif // PROTECTED_THINGS_H

View File

@ -1,22 +1,34 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The main debug library implementation
//=============================================================================
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include "precompiled.h"
//-----------------------------------------------------------------------------
// internal structures
//-----------------------------------------------------------------------------
enum
{
MAX_GROUP_NAME_LENGTH = 48
@ -28,10 +40,7 @@ struct SpewGroup_t
int m_Level;
};
//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:
void _AssertValidReadPtr(void* ptr, int count/* = 1*/)
{
#ifdef _WIN32
@ -69,11 +78,7 @@ void AssertValidStringPtr(const char* ptr, int maxchar/* = 0xFFFFFF */)
#endif
}
//-----------------------------------------------------------------------------
// globals
//-----------------------------------------------------------------------------
SpewRetval_t DefaultSpewFunc(SpewType_t type, char const *pMsg)
{
printf("%s", pMsg);
@ -85,7 +90,7 @@ SpewRetval_t DefaultSpewFunc(SpewType_t type, char const *pMsg)
return SPEW_CONTINUE;
}
static SpewOutputFunc_t s_SpewOutputFunc = DefaultSpewFunc;
static SpewOutputFunc_t s_SpewOutputFunc = DefaultSpewFunc;
static char const* s_pFileName;
static int s_Line;
@ -95,13 +100,8 @@ static SpewGroup_t* s_pSpewGroups = 0;
static int s_GroupCount = 0;
static int s_DefaultLevel = 0;
//-----------------------------------------------------------------------------
// Spew output management.
//-----------------------------------------------------------------------------
void SpewOutputFunc(SpewOutputFunc_t func)
void SpewOutputFunc(SpewOutputFunc_t func)
{
s_SpewOutputFunc = func ? func : DefaultSpewFunc;
}
@ -118,11 +118,8 @@ SpewOutputFunc_t GetSpewOutputFunc(void)
}
}
//-----------------------------------------------------------------------------
// Spew functions
//-----------------------------------------------------------------------------
void _SpewInfo(SpewType_t type, char const* pFile, int line)
void _SpewInfo(SpewType_t type, char const* pFile, int line)
{
// Only grab the file name. Ignore the path.
char const* pSlash = strrchr(pFile, '\\');
@ -134,18 +131,18 @@ void _SpewInfo(SpewType_t type, char const* pFile, int line)
s_SpewType = type;
}
SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list args)
SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list args)
{
char pTempBuffer[1024];
/* Printf the file and line for warning + assert only... */
// Printf the file and line for warning + assert only...
int len = 0;
if ((spewType == SPEW_ASSERT))
{
len = sprintf(pTempBuffer, "%s (%d) : ", s_pFileName, s_Line);
}
/* Create the message.... */
// Create the message....
len += vsprintf(&pTempBuffer[len], pMsgFormat, args);
// Add \n for warning and assert
@ -154,10 +151,10 @@ SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list
len += sprintf(&pTempBuffer[len], "\n");
}
assert(len < 1024); /* use normal assert here; to avoid recursion. */
assert(len < 1024); // use normal assert here; to avoid recursion.
assert(s_SpewOutputFunc);
/* direct it to the appropriate target(s) */
// direct it to the appropriate target(s)
SpewRetval_t ret = s_SpewOutputFunc(spewType, pTempBuffer);
switch (ret)
{
@ -176,7 +173,7 @@ SpewRetval_t _SpewMessage(SpewType_t spewType, char const* pMsgFormat, va_list
return ret;
}
SpewRetval_t _SpewMessage(char const* pMsgFormat, ...)
SpewRetval_t _SpewMessage(char const* pMsgFormat, ...)
{
va_list args;
va_start(args, pMsgFormat);
@ -262,12 +259,8 @@ void Error(char const *pMsgFormat, ...)
va_end(args);
}
//-----------------------------------------------------------------------------
// A couple of super-common dynamic spew messages, here for convenience
// These looked at the "developer" group, print if it's level 1 or higher
//-----------------------------------------------------------------------------
void DevMsg(int level, char const* pMsgFormat, ...)
{
if (!IsSpewActive("developer", level))
@ -328,12 +321,9 @@ void DevLog(char const *pMsgFormat, ...)
va_end(args);
}
//-----------------------------------------------------------------------------
// Find a group, return true if found, false if not. Return in ind the
// index of the found group, or the index of the group right before where the
// group should be inserted into the list to maintain sorted order.
//-----------------------------------------------------------------------------
bool FindSpewGroup(char const* pGroupName, int* pInd)
{
int s = 0;
@ -359,11 +349,7 @@ bool FindSpewGroup(char const* pGroupName, int* pInd)
return false;
}
//-----------------------------------------------------------------------------
// Sets the priority level for a spew group
//-----------------------------------------------------------------------------
void SpewActivate(char const* pGroupName, int level)
{
Assert(pGroupName);
@ -402,11 +388,7 @@ void SpewActivate(char const* pGroupName, int level)
s_pSpewGroups[ind].m_Level = level;
}
//-----------------------------------------------------------------------------
// Tests to see if a particular spew is active
//-----------------------------------------------------------------------------
bool IsSpewActive(char const* pGroupName, int level)
{
// If we don't find the spew group, use the default level.
@ -416,20 +398,3 @@ bool IsSpewActive(char const* pGroupName, int level)
else
return s_DefaultLevel >= level;
}
// If we don't have a function from math.h, then it doesn't link certain floating-point
// functions in and printfs with %f cause runtime errors in the C libraries.
float CrackSmokingCompiler(float a)
{
return fabs(a);
}
void* Plat_SimpleLog(const char* file, int line)
{
FILE* f = fopen("simple.log", "at+");
fprintf(f, "%s:%i\n", file, line);
fclose(f);
return NULL;
}

View File

@ -1,36 +1,40 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// The main debug library interfaces
//=============================================================================
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef DBG_H
#define DBG_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
#include "basetypes.h"
#include "tier0/platform.h"
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
//-----------------------------------------------------------------------------
// dll export stuff
//-----------------------------------------------------------------------------
#ifdef TIER0_DLL_EXPORT
#define DBG_INTERFACE DLL_EXPORT
#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
@ -41,17 +45,15 @@
#define DBG_CLASS DLL_CLASS_IMPORT
#endif
//-----------------------------------------------------------------------------
// Usage model for the Dbg library
//
// 1. Spew.
//
//
// Spew can be used in a static and a dynamic mode. The static
// mode allows us to display assertions and other messages either only
// in debug builds, or in non-release builds. The dynamic mode allows us to
// turn on and off certain spew messages while the application is running.
//
//
// Static Spew messages:
//
// Assertions are used to detect and warn about invalid states
@ -66,14 +68,14 @@
// AssertFloatEquals( f, 5.0f, 1e-3 );
//
// The first will simply report that an assertion failed on a particular
// code file and line. The second version will display a print-f formatted message
// code file and line. The second version will display a print-f formatted message
// along with the file and line, the third will display a generic message and
// will also cause the function BadFunc to be executed, and the last two
// will report an error if f is not equal to 5 (the last one asserts within
// a particular tolerance).
//
// To use a warning, use
//
//
// Warning("Oh I feel so %s all over\n", "yummy");
//
// Warning will do its magic in only Debug builds. To perform spew in *all*
@ -87,24 +89,24 @@
//
// Dynamic Spew messages
//
// It is possible to dynamically turn spew on and off. Dynamic spew is
// identified by a spew group and priority level. To turn spew on for a
// particular spew group, use SpewActivate( "group", level ). This will
// cause all spew in that particular group with priority levels <= the
// level specified in the SpewActivate function to be printed. Use DSpew
// It is possible to dynamically turn spew on and off. Dynamic spew is
// identified by a spew group and priority level. To turn spew on for a
// particular spew group, use SpewActivate( "group", level ). This will
// cause all spew in that particular group with priority levels <= the
// level specified in the SpewActivate function to be printed. Use DSpew
// to perform the spew:
//
// DWarning( "group", level, "Oh I feel even yummier!\n" );
//
// Priority level 0 means that the spew will *always* be printed, and group
// '*' is the default spew group. If a DWarning is encountered using a group
// whose priority has not been set, it will use the priority of the default
// group. The priority of the default group is initially set to 0.
// '*' is the default spew group. If a DWarning is encountered using a group
// whose priority has not been set, it will use the priority of the default
// group. The priority of the default group is initially set to 0.
//
// Spew output
//
//
// The output of the spew system can be redirected to an externally-supplied
// function which is responsible for outputting the spew. By default, the
// function which is responsible for outputting the spew. By default, the
// spew is simply printed using printf.
//
// To redirect spew output, call SpewOutput.
@ -114,8 +116,8 @@
// This will cause OutputFunc to be called every time a spew message is
// generated. OutputFunc will be passed a spew type and a message to print.
// It must return a value indicating whether the debugger should be invoked,
// whether the program should continue running, or whether the program
// should abort.
// whether the program should continue running, or whether the program
// should abort.
//
// 2. Code activation
//
@ -127,10 +129,10 @@
// int x = 5;
// ++x;
// }
// );
// );
//
// Code can be activated based on the dynamic spew groups also. Use
//
//
// DBG_DCODE( "group", level,
// { int x = 5; ++x; }
// );
@ -146,7 +148,7 @@
// DebuggerBreak();
//-----------------------------------------------------------------------------
/* Various types of spew messages */
// Various types of spew messages
// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
// It's because DBG_ is used all over the place in windows.h
// For example, DBG_CONTINUE is defined. Feh.
@ -168,25 +170,25 @@ enum SpewRetval_t
SPEW_ABORT
};
/* type of externally defined function used to display debug spew */
// type of externally defined function used to display debug spew
typedef SpewRetval_t(*SpewOutputFunc_t)(SpewType_t spewType, char const *pMsg);
/* Used to redirect spew output */
// Used to redirect spew output
void SpewOutputFunc(SpewOutputFunc_t func);
/* Used ot get the current spew output function */
// Used ot get the current spew output function
SpewOutputFunc_t GetSpewOutputFunc(void);
/* Used to manage spew groups and subgroups */
// Used to manage spew groups and subgroups
void SpewActivate(char const* pGroupName, int level);
bool IsSpewActive(char const* pGroupName, int level);
/* Used to display messages, should never be called directly. */
// Used to display messages, should never be called directly.
void _SpewInfo(SpewType_t type, char const* pFile, int line);
SpewRetval_t _SpewMessage(char const* pMsg, ...);
SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg, ...);
/* Used to define macros, never use these directly. */
// Used to define macros, never use these directly.
#define _Assert( _exp ) do { \
if (!(_exp)) \
{ \
@ -248,14 +250,14 @@ SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg
} \
} while (0)
/* Spew macros... */
// Spew macros...
#ifdef _DEBUG
#define Assert( _exp ) _Assert( _exp )
#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg )
#define AssertFunc( _exp, _f ) _AssertFunc( _exp, _f )
#define AssertEquals( _exp, _expectedValue ) _AssertEquals( _exp, _expectedValue )
#define AssertEquals( _exp, _expectedValue ) _AssertEquals( _exp, _expectedValue )
#define AssertFloatEquals( _exp, _expectedValue, _tol ) _AssertFloatEquals( _exp, _expectedValue, _tol )
#define Verify( _exp ) _Assert( _exp )
@ -271,7 +273,7 @@ SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) _AssertMsg( _exp, CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) )
#else /* Not _DEBUG */
#else // Not _DEBUG
#define Assert( _exp ) ((void)0)
#define AssertMsg( _exp, _msg ) ((void)0)
@ -291,11 +293,9 @@ SpewRetval_t _DSpewMessage(char const *pGroupName, int level, char const* pMsg
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
#endif /* _DEBUG */
#endif // _DEBUG
/* These are always compiled in */
// These are always compiled in
void Msg(char const* pMsg, ...);
void DMsg(char const *pGroupName, int level, char const *pMsg, ...);
@ -320,42 +320,39 @@ void Error(char const *pMsg, ...);
Error msg; \
}
/* A couple of super-common dynamic spew messages, here for convenience */
/* These looked at the "developer" group */
// A couple of super-common dynamic spew messages, here for convenience
// These looked at the "developer" group
void DevMsg(int level, char const* pMsg, ...);
void DevWarning(int level, char const *pMsg, ...);
void DevLog(int level, char const *pMsg, ...);
/* default level versions (level 1) */
// default level versions (level 1)
void DevMsg(char const* pMsg, ...);
void DevWarning(char const *pMsg, ...);
void DevLog(char const *pMsg, ...);
/* Code macros, debugger interface */
// Code macros, debugger interface
#ifdef _DEBUG
#define DBG_CODE( _code ) if (0) ; else { _code }
#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */
#define DBG_BREAK() DebuggerBreak() // defined in platform.h
#else /* not _DEBUG */
#else // not _DEBUG
#define DBG_CODE( _code ) ((void)0)
#define DBG_DCODE( _g, _l, _code ) ((void)0)
#define DBG_BREAK() ((void)0)
#endif /* _DEBUG */
#endif // _DEBUG
//-----------------------------------------------------------------------------
// Macro to assist in asserting constant invariants during compilation
#define UID_PREFIX generated_id_
#define UID_CAT1(a,c) a ## c
#define UID_CAT2(a,c) UID_CAT1(a,c)
#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
#ifdef _DEBUG
#define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
#define ASSERT_INVARIANT( pred ) static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) }
@ -364,10 +361,7 @@ void DevLog(char const *pMsg, ...);
#define ASSERT_INVARIANT( pred )
#endif
//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:
// Have to use these stubs so we don't have to include windows.h here.
void _AssertValidReadPtr(void* ptr, int count = 1);
void _AssertValidWritePtr(void* ptr, int count = 1);
@ -380,9 +374,7 @@ template<class T> inline void AssertValidReadWritePtr(T* ptr, int count = 1)
#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
//-----------------------------------------------------------------------------
// Macro to protect functions that are not reentrant
#ifdef _DEBUG
class CReentryGuard
{
@ -410,11 +402,7 @@ private:
#define ASSERT_NO_REENTRY()
#endif
//-----------------------------------------------------------------------------
//
// Purpose: Inline string formatter
//
class CDbgFmtMsg
{
public:
@ -437,17 +425,3 @@ public:
private:
char m_szBuf[256];
};
//-----------------------------------------------------------------------------
//
// Purpose: Embed debug info in each file.
//
//#ifdef _WIN32
//#ifdef _DEBUG
//#pragma comment(compiler)
//#pragma comment(exestr,"*** DEBUG file detected, Last Compile: " __DATE__ ", " __TIME__ " ***")
//#endif
//#endif
#endif /* DBG_H */

View File

@ -1,102 +1,40 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Extremely low-level platform-specific stuff
//=============================================================================
/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef PLATFORM_H
#define PLATFORM_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
// need this for _alloca
#include <malloc.h>
// need this for memset
#include <string.h>
#include <malloc.h> // need this for _alloca
#include <string.h> // need this for memset
#include "archtypes.h"
typedef float float32;
typedef double float64;
// for when we don't care about how many bits we use
typedef unsigned int uint;
// This can be used to ensure the size of pointers to members when declaring
// a pointer type for a class that has only been forward declared
#ifdef _MSC_VER
#define SINGLE_INHERITANCE __single_inheritance
#define MULTIPLE_INHERITANCE __multiple_inheritance
#else
#define SINGLE_INHERITANCE
#define MULTIPLE_INHERITANCE
#endif
/*
FIXME: Enable this when we no longer fear change =)
// need these for the limits
#include <limits.h>
#include <float.h>
// Maximum and minimum representable values
#define INT8_MAX SCHAR_MAX
#define INT16_MAX SHRT_MAX
#define INT32_MAX LONG_MAX
#define INT64_MAX (((int64)~0) >> 1)
#define INT8_MIN SCHAR_MIN
#define INT16_MIN SHRT_MIN
#define INT32_MIN LONG_MIN
#define INT64_MIN (((int64)1) << 63)
#define UINT8_MAX ((uint8)~0)
#define UINT16_MAX ((uint16)~0)
#define UINT32_MAX ((uint32)~0)
#define UINT64_MAX ((uint64)~0)
#define UINT8_MIN 0
#define UINT16_MIN 0
#define UINT32_MIN 0
#define UINT64_MIN 0
#ifndef UINT_MIN
#define UINT_MIN UINT32_MIN
#endif
#define FLOAT32_MAX FLT_MAX
#define FLOAT64_MAX DBL_MAX
#define FLOAT32_MIN FLT_MIN
#define FLOAT64_MIN DBL_MIN
*/
// portability / compiler settings
#if defined(_WIN32) && !defined(WINDED)
#if defined(_M_IX86)
#define __i386__ 1
#endif
#elif __linux__
typedef void * HINSTANCE;
#define _MAX_PATH PATH_MAX
#endif // defined(_WIN32) && !defined(WINDED)
// Defines MAX_PATH
#ifndef MAX_PATH
#define MAX_PATH 260
@ -108,92 +46,42 @@ typedef void * HINSTANCE;
// C functions for external declarations that call the appropriate C++ methods
#ifndef EXPORT
#ifdef _WIN32
#define EXPORT _declspec( dllexport )
#else
#define EXPORT __declspec(dllexport)
#else
#define EXPORT /* */
#endif
#endif
#if defined __i386__ && !defined __linux__
#define id386 1
#else
#define id386 0
#endif // __i386__
#ifdef _WIN32
// Used for dll exporting and importing
#define DLL_EXPORT extern "C" __declspec( dllexport )
#define DLL_IMPORT extern "C" __declspec( dllimport )
#define DLL_EXPORT extern "C" __declspec(dllexport)
#define DLL_IMPORT extern "C" __declspec(dllimport)
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT __declspec( dllexport )
#define DLL_CLASS_IMPORT __declspec( dllimport )
#define DLL_CLASS_EXPORT __declspec(dllexport)
#define DLL_CLASS_IMPORT __declspec(dllimport)
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern __declspec( dllexport )
#define DLL_GLOBAL_IMPORT extern __declspec( dllimport )
#define DLL_GLOBAL_EXPORT extern __declspec(dllexport)
#define DLL_GLOBAL_IMPORT extern __declspec(dllimport)
#elif defined __linux__
// Used for dll exporting and importing
#define DLL_EXPORT extern "C"
#define DLL_IMPORT extern "C"
#define DLL_EXPORT extern "C"
#define DLL_IMPORT extern "C"
// Can't use extern "C" when DLL exporting a class
#define DLL_CLASS_EXPORT
#define DLL_CLASS_IMPORT
#define DLL_CLASS_EXPORT
#define DLL_CLASS_IMPORT
// Can't use extern "C" when DLL exporting a global
#define DLL_GLOBAL_EXPORT extern
#define DLL_GLOBAL_IMPORT extern
#define DLL_GLOBAL_EXPORT extern
#define DLL_GLOBAL_IMPORT extern
#else
#error "Unsupported Platform."
#endif
// Used for standard calling conventions
#ifdef _WIN32
#define FASTCALL __fastcall
#define FORCEINLINE __forceinline
#else
#define FASTCALL
#define FORCEINLINE inline
#endif
// Force a function call site -not- to inlined. (useful for profiling)
#define DONT_INLINE(a) (((int)(a)+1)?(a):(a))
// Pass hints to the compiler to prevent it from generating unnessecary / stupid code
// in certain situations. Several compilers other than MSVC also have an equivilent
// construct.
//
// Essentially the 'Hint' is that the condition specified is assumed to be true at
// that point in the compilation. If '0' is passed, then the compiler assumes that
// any subsequent code in the same 'basic block' is unreachable, and thus usually
// removed.
#ifdef _MSC_VER
#define HINT(THE_HINT) __assume((THE_HINT))
#else
#define HINT(THE_HINT) 0
#endif
// Marks the codepath from here until the next branch entry point as unreachable,
// and asserts if any attempt is made to execute it.
#define UNREACHABLE() { Assert(0); HINT(0); }
// In cases where no default is present or appropriate, this causes MSVC to generate
// as little code as possible, and throw an assertion in debug.
#define NO_DEFAULT default: UNREACHABLE();
#ifdef _WIN32
// Alloca defined for this platform
#define stackalloc( _size ) _alloca( _size )
#define stackfree( _p ) 0
#elif __linux__
// Alloca defined for this platform
#define stackalloc( _size ) alloca( _size )
#define stackfree( _p ) 0
#endif
#ifdef _WIN32
// Remove warnings from warning level 4.
#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
@ -216,274 +104,22 @@ typedef void * HINSTANCE;
#pragma warning(disable : 4511) // Disable warnings about private copy constructors
#endif
#endif
//-----------------------------------------------------------------------------
// Purpose: Standard functions for handling endian-ness
//-----------------------------------------------------------------------------
//-------------------------------------
// Basic swaps
//-------------------------------------
template <typename T>
inline T WordSwapC(T w)
{
uint16 temp;
temp = ((*((uint16 *)&w) & 0xff00) >> 8);
temp |= ((*((uint16 *)&w) & 0x00ff) << 8);
return *((T*)&temp);
}
template <typename T>
inline T DWordSwapC(T dw)
{
uint32 temp;
temp = *((uint32 *)&dw) >> 24;
temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8);
temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8);
temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24);
return *((T*)&temp);
}
//-------------------------------------
// Fast swaps
//-------------------------------------
#ifdef _MSC_VER
#define WordSwap WordSwapAsm
#define DWordSwap DWordSwapAsm
#pragma warning(push)
#pragma warning (disable:4035) // no return value
template <typename T>
inline T WordSwapAsm(T w)
{
__asm
{
mov ax, w
xchg al, ah
}
}
template <typename T>
inline T DWordSwapAsm(T dw)
{
__asm
{
mov eax, dw
bswap eax
}
}
#pragma warning(pop)
// The assembly implementation is not compatible with floats
template <>
inline float DWordSwapAsm<float>(float f)
{
return DWordSwapC(f);
}
#else
#define WordSwap WordSwapC
#define DWordSwap DWordSwapC
#endif
//-------------------------------------
// The typically used methods.
//-------------------------------------
#if defined(__i386__)
#define VALVE_LITTLE_ENDIAN 1
#endif
#ifdef _SGI_SOURCE
#define VALVE_BIG_ENDIAN 1
#endif
#if defined(VALVE_LITTLE_ENDIAN)
#define Valve_BigShort( val ) WordSwap( val )
#define Valve_BigWord( val ) WordSwap( val )
#define Valve_BigLong( val ) DWordSwap( val )
#define Valve_BigDWord( val ) DWordSwap( val )
#define Valve_BigFloat( val ) DWordSwap( val )
#define Valve_LittleShort( val ) ( val )
#define Valve_LittleWord( val ) ( val )
#define Valve_LittleLong( val ) ( val )
#define Valve_LittleDWord( val ) ( val )
#define Valve_LittleFloat( val ) ( val )
#elif defined(BIG_ENDIAN)
#define Valve_BigShort( val ) ( val )
#define Valve_BigWord( val ) ( val )
#define Valve_BigLong( val ) ( val )
#define Valve_BigDWord( val ) ( val )
#define Valve_BigFloat( val ) ( val )
#define Valve_LittleShort( val ) WordSwap( val )
#define Valve_LittleWord( val ) WordSwap( val )
#define Valve_LittleLong( val ) DWordSwap( val )
#define Valve_LittleDWord( val ) DWordSwap( val )
#define Valve_LittleFloat( val ) DWordSwap( val )
#else
// @Note (toml 05-02-02): this technique expects the compiler to
// optimize the expression and eliminate the other path. On any new
// platform/compiler this should be tested.
inline short BigShort(short val) { int test = 1; return (*(char *)&test == 1) ? WordSwap(val) : val; }
inline uint16 BigWord(uint16 val) { int test = 1; return (*(char *)&test == 1) ? WordSwap(val) : val; }
inline long BigLong(long val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline uint32 BigDWord(uint32 val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline float BigFloat(float val) { int test = 1; return (*(char *)&test == 1) ? DWordSwap(val) : val; }
inline short LittleShort(short val) { int test = 1; return (*(char *)&test == 1) ? val : WordSwap(val); }
inline uint16 LittleWord(uint16 val) { int test = 1; return (*(char *)&test == 1) ? val : WordSwap(val); }
inline long LittleLong(long val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
inline uint32 LittleDWord(uint32 val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
inline float LittleFloat(float val) { int test = 1; return (*(char *)&test == 1) ? val : DWordSwap(val); }
#endif
#ifdef TIER0_DLL_EXPORT
#define PLATFORM_INTERFACE DLL_EXPORT
#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT
#else
#define PLATFORM_INTERFACE DLL_IMPORT
#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT
#endif
/*
PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
PLATFORM_INTERFACE unsigned long Plat_MSTime(); // Time in milliseconds.
// b/w compatibility
#define Sys_FloatTime Plat_FloatTime
*/
// Processor Information:
struct CPUInformation
{
int m_Size; // Size of this structure, for forward compatability.
bool m_bRDTSC : 1, // Is RDTSC supported?
m_bCMOV : 1, // Is CMOV supported?
m_bFCMOV : 1, // Is FCMOV supported?
m_bSSE : 1, // Is SSE supported?
m_bSSE2 : 1, // Is SSE2 Supported?
m_b3DNow : 1, // Is 3DNow! Supported?
m_bMMX : 1, // Is MMX supported?
m_bHT : 1; // Is HyperThreading supported?
unsigned char m_nLogicalProcessors, // Number op logical processors.
m_nPhysicalProcessors; // Number of physical processors
int64 m_Speed; // In cycles per second.
char* m_szProcessorID; // Processor vendor Identification.
};
PLATFORM_INTERFACE const CPUInformation& GetCPUInformation();
//-----------------------------------------------------------------------------
// Thread related functions
//-----------------------------------------------------------------------------
// Registers the current thread with Tier0's thread management system.
// This should be called on every thread created in the game.
PLATFORM_INTERFACE unsigned long Plat_RegisterThread(const char *pName = "Source Thread");
// Registers the current thread as the primary thread.
PLATFORM_INTERFACE unsigned long Plat_RegisterPrimaryThread();
// VC-specific. Sets the thread's name so it has a friendly name in the debugger.
// This should generally only be handled by Plat_RegisterThread and Plat_RegisterPrimaryThread
PLATFORM_INTERFACE void Plat_SetThreadName(unsigned long dwThreadID, const char *pName);
// These would be private if it were possible to export private variables from a .DLL.
// They need to be variables because they are checked by inline functions at performance
// critical places.
PLATFORM_INTERFACE unsigned long Plat_PrimaryThreadID;
// Returns the ID of the currently executing thread.
PLATFORM_INTERFACE unsigned long Plat_GetCurrentThreadID();
// Returns the ID of the primary thread.
inline unsigned long Plat_GetPrimaryThreadID()
{
return Plat_PrimaryThreadID;
}
// Returns true if the current thread is the primary thread.
inline bool Plat_IsPrimaryThread()
{
//return true;
return (Plat_GetPrimaryThreadID() == Plat_GetCurrentThreadID());
}
//-----------------------------------------------------------------------------
// Security related functions
//-----------------------------------------------------------------------------
// Ensure that the hardware key's drivers have been installed.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver();
// Ok, so this isn't a very secure way to verify the hardware key for now. It
// is primarially depending on the fact that all the binaries have been wrapped
// with the secure wrapper provided by the hardware keys vendor.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKey();
// The same as above, but notifies user with a message box when the key isn't in
// and gives him an opportunity to correct the situation.
PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt();
// Can be called in real time, doesn't perform the verify every frame. Mainly just
// here to allow the game to drop out quickly when the key is removed, rather than
// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't
// like much.
PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey();
//-----------------------------------------------------------------------------
// Include additional dependant header components.
//-----------------------------------------------------------------------------
//#include "tier0/fasttimer.h"
//-----------------------------------------------------------------------------
// Just logs file and line to simple.log
//-----------------------------------------------------------------------------
void* Plat_SimpleLog(const char* file, int line);
//#define Plat_dynamic_cast Plat_SimpleLog(__FILE__,__LINE__),dynamic_cast
//-----------------------------------------------------------------------------
// Methods to invoke the constructor, copy constructor, and destructor
//-----------------------------------------------------------------------------
template <class T>
inline void Construct(T* pMemory)
inline void Construct(T *pMemory)
{
new(pMemory)T;
new(pMemory) T;
}
template <class T>
inline void CopyConstruct(T* pMemory, T const& src)
inline void CopyConstruct(T *pMemory, T const &src)
{
new(pMemory)T(src);
new(pMemory) T(src);
}
template <class T>
inline void Destruct(T* pMemory)
inline void Destruct(T *pMemory)
{
pMemory->~T();
@ -491,140 +127,3 @@ inline void Destruct(T* pMemory)
memset(pMemory, 0xDD, sizeof(T));
#endif
}
//
// GET_OUTER()
//
// A platform-independent way for a contained class to get a pointer to its
// owner. If you know a class is exclusively used in the context of some
// "outer" class, this is a much more space efficient way to get at the outer
// class than having the inner class store a pointer to it.
//
// class COuter
// {
// class CInner // Note: this does not need to be a nested class to work
// {
// void PrintAddressOfOuter()
// {
// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) );
// }
// };
//
// CInner m_Inner;
// friend class CInner;
// };
#define GET_OUTER( OuterType, OuterMember ) \
( ( OuterType * ) ( (char *)this - offsetof( OuterType, OuterMember ) ) )
/* TEMPLATE_FUNCTION_TABLE()
(Note added to platform.h so platforms that correctly support templated
functions can handle portions as templated functions rather than wrapped
functions)
Helps automate the process of creating an array of function
templates that are all specialized by a single integer.
This sort of thing is often useful in optimization work.
For example, using TEMPLATE_FUNCTION_TABLE, this:
TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10)
{
return argument * argument;
}
is equivilent to the following:
(NOTE: the function has to be wrapped in a class due to code
generation bugs involved with directly specializing a function
based on a constant.)
template<int argument>
class FunctionWrapper
{
public:
int Function( int blah, int blah )
{
return argument*argument;
}
}
typedef int (*FunctionType)( int blah, int blah );
class FunctionName
{
public:
enum { count = 10 };
FunctionType functions[10];
};
FunctionType FunctionName::functions[] =
{
FunctionWrapper<0>::Function,
FunctionWrapper<1>::Function,
FunctionWrapper<2>::Function,
FunctionWrapper<3>::Function,
FunctionWrapper<4>::Function,
FunctionWrapper<5>::Function,
FunctionWrapper<6>::Function,
FunctionWrapper<7>::Function,
FunctionWrapper<8>::Function,
FunctionWrapper<9>::Function
};
*/
bool vtune(bool resume);
#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \
\
typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \
\
template<const int nArgument> \
struct __Function_##NAME \
{ \
static RETURN_TYPE FASTCALL Run ARGS; \
}; \
\
template <int i> \
struct __MetaLooper_##NAME : __MetaLooper_##NAME<i-1> \
{ \
__Type_##NAME func; \
inline __MetaLooper_##NAME() { func = __Function_##NAME<i>::Run; } \
}; \
\
template<> \
struct __MetaLooper_##NAME<0> \
{ \
__Type_##NAME func; \
inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \
}; \
\
class NAME \
{ \
private: \
static const __MetaLooper_##NAME<COUNT> m; \
public: \
enum { count = COUNT }; \
static const __Type_##NAME* functions; \
}; \
const __MetaLooper_##NAME<COUNT> NAME::m; \
const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \
template<int nArgument> \
RETURN_TYPE FASTCALL __Function_##NAME<nArgument>::Run ARGS
#define LOOP_INTERCHANGE(BOOLEAN, CODE)\
if( (BOOLEAN) )\
{\
CODE;\
} else\
{\
CODE;\
}
#endif /* PLATFORM_H */

View File

@ -26,12 +26,7 @@
*
*/
#ifndef UTLMEMORY_H
#define UTLMEMORY_H
#ifdef _WIN32
#pragma once
#endif
#include "osconfig.h"
#include "tier0/dbg.h"
@ -40,55 +35,56 @@
#pragma warning (disable:4100)
#pragma warning (disable:4514)
/*template <class T>
inline void Construct(T *pMemory)
{
::new(pMemory) T;
}
template <class T>
inline void CopyConstruct(T *pMemory,T const& src)
{
::new(pMemory) T(src);
}
template <class T>
inline void Destruct(T *pMemory)
{
pMemory->~T();
#ifdef _DEBUG
memset(pMemory,0xDD,sizeof(T));
#endif
}*/
//-----------------------------------------------------------------------------
// The CUtlMemory class:
// A growable memory class which doubles in size by default.
//-----------------------------------------------------------------------------
template< class T >
template <class T, class I = int>
class CUtlMemory
{
public:
// constructor, destructor
CUtlMemory(int nGrowSize = 0, int nInitSize = 0);
CUtlMemory(T* pMemory, int numElements);
CUtlMemory(T *pMemory, int numElements);
~CUtlMemory();
// Set the size by which the memory grows
void Init(int nGrowSize = 0, int nInitSize = 0);
class Iterator_t
{
public:
Iterator_t(I i) : m_index(i) {}
I m_index;
bool operator==(const Iterator_t it) const { return m_index == it.m_index; }
bool operator!=(const Iterator_t it) const { return m_index != it.m_index; }
};
Iterator_t First() const { return Iterator_t(IsIdxValid(0) ? 0 : InvalidIndex()); }
Iterator_t Next(const Iterator_t &it) const { return Iterator_t(IsIdxValid(it.index + 1) ? it.index + 1 : InvalidIndex()); }
I GetIndex(const Iterator_t &it) const { return it.index; }
bool IsIdxAfter(I i, const Iterator_t &it) const { return i > it.index; }
bool IsValidIterator(const Iterator_t &it) const { return IsIdxValid(it.index); }
Iterator_t InvalidIterator() const { return Iterator_t(InvalidIndex()); }
// element access
T& operator[](int i);
T const& operator[](int i) const;
T& Element(int i);
T const& Element(int i) const;
T& Element(I i);
T const& Element(I i) const;
T& operator[](I i);
T const& operator[](I i) const;
// Can we use this index?
bool IsIdxValid(int i) const;
bool IsIdxValid(I i) const;
// Specify the invalid ('null') index that we'll only return on failure
static const I INVALID_INDEX = (I)-1; // For use with COMPILE_TIME_ASSERT
static I InvalidIndex() { return INVALID_INDEX; }
// Gets the base address (can change when adding elements!)
T* Base();
T const* Base() const;
T *Base();
T const *Base() const;
// Attaches the buffer to external memory....
void SetExternalBuffer(T* pMemory, int numElements);
void SetExternalBuffer(T *pMemory, int numElements);
// Size
int NumAllocated() const;
@ -115,46 +111,54 @@ private:
EXTERNAL_BUFFER_MARKER = -1,
};
T* m_pMemory;
T *m_pMemory;
int m_nAllocationCount;
int m_nGrowSize;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T >
CUtlMemory<T>::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 nInitSize) : m_pMemory(0),
m_nAllocationCount(nInitSize), m_nGrowSize(nGrowSize)
{
Assert((nGrowSize >= 0) && (nGrowSize != EXTERNAL_BUFFER_MARKER));
if (m_nAllocationCount)
{
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
m_pMemory = (T *)malloc(m_nAllocationCount * sizeof(T));
}
}
template< class T >
CUtlMemory<T>::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory),
template <class T, class I>
CUtlMemory<T, I>::CUtlMemory(T *pMemory, int numElements) : m_pMemory(pMemory),
m_nAllocationCount(numElements)
{
// Special marker indicating externally supplied memory
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
template< class T >
CUtlMemory<T>::~CUtlMemory()
template <class T, class I>
CUtlMemory<T, I>::~CUtlMemory()
{
Purge();
}
template <class T, class I>
void CUtlMemory<T,I>::Init(int nGrowSize, int nInitSize)
{
Purge();
m_nGrowSize = nGrowSize;
m_nAllocationCount = nInitSize;
Assert(nGrowSize >= 0);
if (m_nAllocationCount)
{
m_pMemory = (T *)malloc(m_nAllocationCount * sizeof(T));
}
}
//-----------------------------------------------------------------------------
// Attaches the buffer to external memory....
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::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();
@ -166,110 +170,91 @@ void CUtlMemory<T>::SetExternalBuffer(T* pMemory, int numElements)
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T >
inline T& CUtlMemory<T>::operator[](int i)
template <class T, class I>
inline T& CUtlMemory<T, I>::operator[](I i)
{
Assert(IsIdxValid(i));
return m_pMemory[i];
}
template< class T >
inline T const& CUtlMemory<T>::operator[](int i) const
template <class T, class I>
inline T const& CUtlMemory<T, I>::operator[](I i) const
{
Assert(IsIdxValid(i));
return m_pMemory[i];
}
template< class T >
inline T& CUtlMemory<T>::Element(int i)
template <class T, class I>
inline T& CUtlMemory<T, I>::Element(I i)
{
Assert(IsIdxValid(i));
return m_pMemory[i];
}
template< class T >
inline T const& CUtlMemory<T>::Element(int i) const
template <class T, class I>
inline T const& CUtlMemory<T, I>::Element(I i) const
{
Assert(IsIdxValid(i));
return m_pMemory[i];
}
//-----------------------------------------------------------------------------
// is the memory externally allocated?
//-----------------------------------------------------------------------------
template< class T >
bool CUtlMemory<T>::IsExternallyAllocated() const
template <class T, class I>
bool CUtlMemory<T, I>::IsExternallyAllocated() const
{
return m_nGrowSize == EXTERNAL_BUFFER_MARKER;
}
template< class T >
void CUtlMemory<T>::SetGrowSize(int nSize)
template <class T, class I>
void CUtlMemory<T, I>::SetGrowSize(int nSize)
{
Assert((nSize >= 0) && (nSize != EXTERNAL_BUFFER_MARKER));
m_nGrowSize = nSize;
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T >
inline T* CUtlMemory<T>::Base()
template <class T, class I>
inline T *CUtlMemory<T, I>::Base()
{
return m_pMemory;
}
template< class T >
inline T const* CUtlMemory<T>::Base() const
template <class T, class I>
inline T const *CUtlMemory<T, I>::Base() const
{
return m_pMemory;
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlMemory<T>::NumAllocated() const
template <class T, class I>
inline int CUtlMemory<T, I>::NumAllocated() const
{
return m_nAllocationCount;
}
template< class T >
inline int CUtlMemory<T>::Count() const
template <class T, class I>
inline int CUtlMemory<T, I>::Count() const
{
return m_nAllocationCount;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T >
inline bool CUtlMemory<T>::IsIdxValid(int i) const
template <class T, class I>
inline bool CUtlMemory<T, I>::IsIdxValid(I i) const
{
return (i >= 0) && (i < m_nAllocationCount);
return (((int)i) >= 0) && (((int) i) < m_nAllocationCount);
}
//-----------------------------------------------------------------------------
// Grows the memory
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::Grow(int num)
template <class T, class I>
void CUtlMemory<T, I>::Grow(int num)
{
Assert(num > 0);
if (IsExternallyAllocated())
{
// Can't grow a buffer whose memory was externally allocated
// Can't grow a buffer whose memory was externally allocated
Assert(0);
return;
}
@ -300,27 +285,24 @@ void CUtlMemory<T>::Grow(int num)
if (m_pMemory)
{
m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
m_pMemory = (T *)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
}
else
{
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
m_pMemory = (T *)malloc(m_nAllocationCount * sizeof(T));
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T >
inline void CUtlMemory<T>::EnsureCapacity(int num)
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
// Can't grow a buffer whose memory was externally allocated
Assert(0);
return;
}
@ -328,30 +310,25 @@ inline void CUtlMemory<T>::EnsureCapacity(int num)
m_nAllocationCount = num;
if (m_pMemory)
{
m_pMemory = (T*)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
m_pMemory = (T *)realloc(m_pMemory, m_nAllocationCount * sizeof(T));
}
else
{
m_pMemory = (T*)malloc(m_nAllocationCount * sizeof(T));
m_pMemory = (T *)malloc(m_nAllocationCount * sizeof(T));
}
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::Purge()
template <class T, class I>
void CUtlMemory<T, I>::Purge()
{
if (!IsExternallyAllocated())
{
if (m_pMemory)
{
free((void*)m_pMemory);
free((void *)m_pMemory);
m_pMemory = 0;
}
m_nAllocationCount = 0;
}
}
#endif // UTLMEMORY_H

View File

@ -1,3 +1,16 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// A growable memory class.
//=============================================================================
#ifndef UTLVECTOR_H
#define UTLVECTOR_H
#ifdef _WIN32
@ -5,6 +18,7 @@
#endif
#include "utlmemory.h"
#include "tier0/platform.h"
template<class T>
class CUtlVector
@ -13,18 +27,18 @@ public:
typedef T ElemType_t;
// constructor, destructor
CUtlVector(int growSize = 0, int initSize = 0);
CUtlVector(T* pMemory, int numElements);
CUtlVector( int growSize = 0, int initSize = 0 );
CUtlVector( T* pMemory, int numElements );
~CUtlVector();
// Copy the array.
CUtlVector<T>& operator=(const CUtlVector<T> &other);
CUtlVector<T>& operator=( const CUtlVector<T> &other );
// element access
T& operator[](int i);
T const& operator[](int i) const;
T& Element(int i);
T const& Element(int i) const;
T& operator[]( int i );
T const& operator[]( int i ) const;
T& Element( int i );
T const& Element( int i ) const;
// Gets the base address (can change when adding elements!)
T* Base();
@ -36,53 +50,53 @@ public:
int Size() const; // don't use me!
// Is element index valid?
bool IsValidIndex(int i) const;
static int InvalidIndex(void);
bool IsValidIndex( int i ) const;
static int InvalidIndex( void );
// Adds an element, uses default constructor
int AddToHead();
int AddToTail();
int InsertBefore(int elem);
int InsertAfter(int elem);
int InsertBefore( int elem );
int InsertAfter( int elem );
// Adds an element, uses copy constructor
int AddToHead(T const& src);
int AddToTail(T const& src);
int InsertBefore(int elem, T const& src);
int InsertAfter(int elem, T const& src);
int AddToHead( T const& src );
int AddToTail( T const& src );
int InsertBefore( int elem, T const& src );
int InsertAfter( int elem, T const& src );
// Adds multiple elements, uses default constructor
int AddMultipleToHead(int num);
int AddMultipleToTail(int num, const T *pToCopy=NULL);
int InsertMultipleBefore(int elem, int num, const T *pToCopy=NULL); // If pToCopy is set, then it's an array of length 'num' and
int InsertMultipleAfter(int elem, int num);
int AddMultipleToHead( int num );
int AddMultipleToTail( int num, const T *pToCopy=NULL );
int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); // If pToCopy is set, then it's an array of length 'num' and
int InsertMultipleAfter( int elem, int num );
// Calls RemoveAll() then AddMultipleToTail.
void SetSize(int size);
void SetCount(int count);
void SetSize( int size );
void SetCount( int count );
// Calls SetSize and copies each element.
void CopyArray(T const *pArray, int size);
void CopyArray( T const *pArray, int size );
// Add the specified array to the tail.
int AddVectorToTail(CUtlVector<T> const &src);
int AddVectorToTail( CUtlVector<T> const &src );
// Finds an element (element needs operator== defined)
int Find(T const& src) const;
int Find( T const& src ) const;
bool HasElement(T const& src);
bool HasElement( T const& src );
// Makes sure we have enough memory allocated to store a requested # of elements
void EnsureCapacity(int num);
void EnsureCapacity( int num );
// Makes sure we have at least this many elements
void EnsureCount(int num);
void EnsureCount( int num );
// Element removal
void FastRemove(int elem); // doesn't preserve order
void Remove(int elem); // preserves order, shifts elements
void FindAndRemove(T const& src); // removes first occurrence of src, preserves order, shifts elements
void RemoveMultiple(int elem, int num); // preserves order, shifts elements
void FastRemove( int elem ); // doesn't preserve order
void Remove( int elem ); // preserves order, shifts elements
void FindAndRemove( T const& src ); // removes first occurrence of src, preserves order, shifts elements
void RemoveMultiple( int elem, int num ); // preserves order, shifts elements
void RemoveAll(); // doesn't deallocate memory
// Memory deallocation
@ -92,18 +106,19 @@ public:
void PurgeAndDeleteElements();
// Set the size by which it grows when it needs to allocate more memory.
void SetGrowSize(int size);
void SetGrowSize( int size );
protected:
// Can't copy this unless we explicitly do it!
CUtlVector(CUtlVector const& vec) { assert(0); }
CUtlVector( CUtlVector const& vec ) { assert(0);
}
// Grows the vector
void GrowVector(int num = 1);
void GrowVector( int num = 1 );
// Shifts elements....
void ShiftElementsRight(int elem, int num = 1);
void ShiftElementsLeft(int elem, int num = 1);
void ShiftElementsRight( int elem, int num = 1 );
void ShiftElementsLeft( int elem, int num = 1 );
// For easier access to the elements through the debugger
void ResetDbgInfo();
@ -119,7 +134,6 @@ protected:
//-----------------------------------------------------------------------------
// For easier access to the elements through the debugger
//-----------------------------------------------------------------------------
template< class T >
inline void CUtlVector<T>::ResetDbgInfo()
{
@ -129,16 +143,15 @@ inline void CUtlVector<T>::ResetDbgInfo()
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T >
inline CUtlVector<T>::CUtlVector(int growSize, int initSize) :
inline CUtlVector<T>::CUtlVector( int growSize, int initSize ) :
m_Memory(growSize, initSize), m_Size(0)
{
ResetDbgInfo();
}
template< class T >
inline CUtlVector<T>::CUtlVector(T* pMemory, int numElements) :
inline CUtlVector<T>::CUtlVector( T* pMemory, int numElements ) :
m_Memory(pMemory, numElements), m_Size(0)
{
ResetDbgInfo();
@ -151,48 +164,46 @@ inline CUtlVector<T>::~CUtlVector()
}
template<class T>
inline CUtlVector<T>& CUtlVector<T>::operator=(const CUtlVector<T> &other)
inline CUtlVector<T>& CUtlVector<T>::operator=( const CUtlVector<T> &other )
{
CopyArray(other.Base(), other.Count());
CopyArray( other.Base(), other.Count() );
return *this;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T >
inline T& CUtlVector<T>::operator[](int i)
inline T& CUtlVector<T>::operator[]( int i )
{
assert(IsValidIndex(i));
assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T const& CUtlVector<T>::operator[](int i) const
inline T const& CUtlVector<T>::operator[]( int i ) const
{
assert(IsValidIndex(i));
assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T& CUtlVector<T>::Element(int i)
inline T& CUtlVector<T>::Element( int i )
{
assert(IsValidIndex(i));
assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T const& CUtlVector<T>::Element(int i) const
inline T const& CUtlVector<T>::Element( int i ) const
{
assert(IsValidIndex(i));
assert( IsValidIndex(i) );
return m_Memory[i];
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T >
inline T* CUtlVector<T>::Base()
{
@ -208,7 +219,6 @@ inline T const* CUtlVector<T>::Base() const
//-----------------------------------------------------------------------------
// Count
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::Size() const
{
@ -224,9 +234,8 @@ inline int CUtlVector<T>::Count() const
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T >
inline bool CUtlVector<T>::IsValidIndex(int i) const
inline bool CUtlVector<T>::IsValidIndex( int i ) const
{
return (i >= 0) && (i < m_Size);
}
@ -235,7 +244,7 @@ inline bool CUtlVector<T>::IsValidIndex(int i) const
// Returns in invalid index
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::InvalidIndex(void)
inline int CUtlVector<T>::InvalidIndex( void )
{
return -1;
}
@ -244,11 +253,11 @@ inline int CUtlVector<T>::InvalidIndex(void)
// Grows the vector
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::GrowVector(int num)
void CUtlVector<T>::GrowVector( int num )
{
if (m_Size + num - 1 >= m_Memory.NumAllocated())
{
m_Memory.Grow(m_Size + num - m_Memory.NumAllocated());
m_Memory.Grow( m_Size + num - m_Memory.NumAllocated() );
}
m_Size += num;
@ -259,7 +268,7 @@ void CUtlVector<T>::GrowVector(int num)
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::EnsureCapacity(int num)
void CUtlVector<T>::EnsureCapacity( int num )
{
m_Memory.EnsureCapacity(num);
ResetDbgInfo();
@ -269,35 +278,35 @@ void CUtlVector<T>::EnsureCapacity(int num)
// Makes sure we have at least this many elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::EnsureCount(int num)
void CUtlVector<T>::EnsureCount( int num )
{
if (Count() < num)
AddMultipleToTail(num - Count());
AddMultipleToTail( num - Count() );
}
//-----------------------------------------------------------------------------
// Shifts elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::ShiftElementsRight(int elem, int num)
void CUtlVector<T>::ShiftElementsRight( int elem, int num )
{
assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 ));
int numToMove = m_Size - elem - num;
if ((numToMove > 0) && (num > 0))
memmove(&Element(elem+num), &Element(elem), numToMove * sizeof(T));
memmove( &Element(elem+num), &Element(elem), numToMove * sizeof(T) );
}
template< class T >
void CUtlVector<T>::ShiftElementsLeft(int elem, int num)
void CUtlVector<T>::ShiftElementsLeft( int elem, int num )
{
assert(IsValidIndex(elem) || (m_Size == 0) || (num == 0));
assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 ));
int numToMove = m_Size - elem - num;
if ((numToMove > 0) && (num > 0))
{
memmove(&Element(elem), &Element(elem+num), numToMove * sizeof(T));
memmove( &Element(elem), &Element(elem+num), numToMove * sizeof(T) );
#ifdef _DEBUG
memset(&Element(m_Size-num), 0xDD, num * sizeof(T));
memset( &Element(m_Size-num), 0xDD, num * sizeof(T) );
#endif
}
}
@ -315,24 +324,24 @@ inline int CUtlVector<T>::AddToHead()
template< class T >
inline int CUtlVector<T>::AddToTail()
{
return InsertBefore(m_Size);
return InsertBefore( m_Size );
}
template< class T >
inline int CUtlVector<T>::InsertAfter(int elem)
inline int CUtlVector<T>::InsertAfter( int elem )
{
return InsertBefore(elem + 1);
return InsertBefore( elem + 1 );
}
template< class T >
int CUtlVector<T>::InsertBefore(int elem)
int CUtlVector<T>::InsertBefore( int elem )
{
// Can insert at the end
assert((elem == Count()) || IsValidIndex(elem));
assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector();
ShiftElementsRight(elem);
Construct(&Element(elem));
Construct( &Element(elem) );
return elem;
}
@ -341,32 +350,32 @@ int CUtlVector<T>::InsertBefore(int elem)
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::AddToHead(T const& src)
inline int CUtlVector<T>::AddToHead( T const& src )
{
return InsertBefore(0, src);
return InsertBefore( 0, src );
}
template< class T >
inline int CUtlVector<T>::AddToTail(T const& src)
inline int CUtlVector<T>::AddToTail( T const& src )
{
return InsertBefore(m_Size, src);
return InsertBefore( m_Size, src );
}
template< class T >
inline int CUtlVector<T>::InsertAfter(int elem, T const& src)
inline int CUtlVector<T>::InsertAfter( int elem, T const& src )
{
return InsertBefore(elem + 1, src);
return InsertBefore( elem + 1, src );
}
template< class T >
int CUtlVector<T>::InsertBefore(int elem, T const& src)
int CUtlVector<T>::InsertBefore( int elem, T const& src )
{
// Can insert at the end
assert((elem == Count()) || IsValidIndex(elem));
assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector();
ShiftElementsRight(elem);
CopyConstruct(&Element(elem), src);
CopyConstruct( &Element(elem), src );
return elem;
}
@ -376,82 +385,82 @@ int CUtlVector<T>::InsertBefore(int elem, T const& src)
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::AddMultipleToHead(int num)
inline int CUtlVector<T>::AddMultipleToHead( int num )
{
return InsertMultipleBefore(0, num);
return InsertMultipleBefore( 0, num );
}
template< class T >
inline int CUtlVector<T>::AddMultipleToTail(int num, const T *pToCopy)
inline int CUtlVector<T>::AddMultipleToTail( int num, const T *pToCopy )
{
return InsertMultipleBefore(m_Size, num, pToCopy);
return InsertMultipleBefore( m_Size, num, pToCopy );
}
template< class T >
int CUtlVector<T>::InsertMultipleAfter(int elem, int num)
int CUtlVector<T>::InsertMultipleAfter( int elem, int num )
{
return InsertMultipleBefore(elem + 1, num);
return InsertMultipleBefore( elem + 1, num );
}
template< class T >
void CUtlVector<T>::SetCount(int count)
void CUtlVector<T>::SetCount( int count )
{
RemoveAll();
AddMultipleToTail(count);
AddMultipleToTail( count );
}
template< class T >
inline void CUtlVector<T>::SetSize(int size)
inline void CUtlVector<T>::SetSize( int size )
{
SetCount(size);
SetCount( size );
}
template< class T >
void CUtlVector<T>::CopyArray(T const *pArray, int size)
void CUtlVector<T>::CopyArray( T const *pArray, int size )
{
SetSize(size);
for(int i=0; i < size; i++)
SetSize( size );
for( int i=0; i < size; i++ )
(*this)[i] = pArray[i];
}
template< class T >
int CUtlVector<T>::AddVectorToTail(CUtlVector const &src)
int CUtlVector<T>::AddVectorToTail( CUtlVector const &src )
{
int base = Count();
// Make space.
AddMultipleToTail(src.Count());
AddMultipleToTail( src.Count() );
// Copy the elements.
for (int i=0; i < src.Count(); i++)
for ( int i=0; i < src.Count(); i++ )
(*this)[base + i] = src[i];
return base;
}
template< class T >
inline int CUtlVector<T>::InsertMultipleBefore(int elem, int num, const T *pToInsert)
inline int CUtlVector<T>::InsertMultipleBefore( int elem, int num, const T *pToInsert )
{
if(num == 0)
if( num == 0 )
return elem;
// Can insert at the end
assert((elem == Count()) || IsValidIndex(elem));
assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector(num);
ShiftElementsRight(elem, num);
// Invoke default constructors
for (int i = 0; i < num; ++i)
Construct(&Element(elem+i));
Construct( &Element(elem+i) );
// Copy stuff in?
if (pToInsert)
if ( pToInsert )
{
for (int i=0; i < num; i++)
for ( int i=0; i < num; i++ )
{
Element(elem+i) = pToInsert[i];
Element( elem+i ) = pToInsert[i];
}
}
@ -462,9 +471,9 @@ inline int CUtlVector<T>::InsertMultipleBefore(int elem, int num, const T *pToIn
// Finds an element (element needs operator== defined)
//-----------------------------------------------------------------------------
template< class T >
int CUtlVector<T>::Find(T const& src) const
int CUtlVector<T>::Find( T const& src ) const
{
for (int i = 0; i < Count(); ++i)
for ( int i = 0; i < Count(); ++i )
{
if (Element(i) == src)
return i;
@ -473,9 +482,9 @@ int CUtlVector<T>::Find(T const& src) const
}
template< class T >
bool CUtlVector<T>::HasElement(T const& src)
bool CUtlVector<T>::HasElement( T const& src )
{
return (Find(src) >= 0);
return ( Find(src) >= 0 );
}
//-----------------------------------------------------------------------------
@ -483,43 +492,43 @@ bool CUtlVector<T>::HasElement(T const& src)
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::FastRemove(int elem)
void CUtlVector<T>::FastRemove( int elem )
{
assert(IsValidIndex(elem));
assert( IsValidIndex(elem) );
Destruct(&Element(elem));
Destruct( &Element(elem) );
if (m_Size > 0)
{
Q_memcpy(&Element(elem), &Element(m_Size-1), sizeof(T));
memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) );
--m_Size;
}
}
template< class T >
void CUtlVector<T>::Remove(int elem)
void CUtlVector<T>::Remove( int elem )
{
Destruct(&Element(elem));
Destruct( &Element(elem) );
ShiftElementsLeft(elem);
--m_Size;
}
template< class T >
void CUtlVector<T>::FindAndRemove(T const& src)
void CUtlVector<T>::FindAndRemove( T const& src )
{
int elem = Find(src);
if (elem != -1)
int elem = Find( src );
if ( elem != -1 )
{
Remove(elem);
Remove( elem );
}
}
template< class T >
void CUtlVector<T>::RemoveMultiple(int elem, int num)
void CUtlVector<T>::RemoveMultiple( int elem, int num )
{
assert(IsValidIndex(elem));
assert(elem + num <= Count());
assert( IsValidIndex(elem) );
assert( elem + num <= Count() );
for (int i = elem + num; --i >= elem;)
for (int i = elem + num; --i >= elem; )
Destruct(&Element(i));
ShiftElementsLeft(elem, num);
@ -529,7 +538,7 @@ void CUtlVector<T>::RemoveMultiple(int elem, int num)
template< class T >
void CUtlVector<T>::RemoveAll()
{
for (int i = m_Size; --i >= 0;)
for (int i = m_Size; --i >= 0; )
Destruct(&Element(i));
m_Size = 0;
@ -543,23 +552,23 @@ template< class T >
void CUtlVector<T>::Purge()
{
RemoveAll();
m_Memory.Purge();
m_Memory.Purge( );
ResetDbgInfo();
}
template<class T>
inline void CUtlVector<T>::PurgeAndDeleteElements()
{
for (int i = 0; i < m_Size; i++)
for( int i=0; i < m_Size; i++ )
delete Element(i);
Purge();
}
template< class T >
void CUtlVector<T>::SetGrowSize(int size)
void CUtlVector<T>::SetGrowSize( int size )
{
m_Memory.SetGrowSize(size);
m_Memory.SetGrowSize( size );
}
#endif // CCVECTOR_H