From d1d4c4766c4ff9443eec66f0a1028a632d878198 Mon Sep 17 00:00:00 2001 From: s1lent Date: Sun, 24 Sep 2017 18:05:17 +0700 Subject: [PATCH] Minor refactoring --- Makefile | 3 +- common/mathlib.h | 170 +++-- dlls/vector.h | 74 +- public/basetypes.h | 272 +------ public/interface.cpp | 2 +- public/interface.h | 4 +- public/strtools.h | 211 ++++++ public/tier0/dbg.h | 3 +- public/tier0/mem.h | 37 - public/tier0/memalloc.h | 77 -- public/tier0/memdbgoff.h | 21 - public/tier0/memdbgon.h | 93 --- public/tier0/platform.h | 597 ++------------- public/tier0/platform_linux.cpp | 59 -- public/tier0/platform_win32.cpp | 95 --- public/utlbuffer.cpp | 8 +- public/utllinkedlist.h | 2 +- public/utlmemory.h | 231 +++--- public/utlrbtree.h | 1201 ++++++++++++++----------------- public/utlvector.h | 267 ++++--- src/cmdexec.cpp | 32 +- src/cmdexec.h | 2 +- src/meta_api.cpp | 2 +- src/precompiled.h | 7 +- src/rechecker_api_impl.cpp | 6 +- 25 files changed, 1282 insertions(+), 2194 deletions(-) create mode 100644 public/strtools.h delete mode 100644 public/tier0/mem.h delete mode 100644 public/tier0/memalloc.h delete mode 100644 public/tier0/memdbgoff.h delete mode 100644 public/tier0/memdbgon.h delete mode 100644 public/tier0/platform_linux.cpp delete mode 100644 public/tier0/platform_win32.cpp diff --git a/Makefile b/Makefile index b27a998..8401e14 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,7 @@ OBJECTS = src/main.cpp src/meta_api.cpp src/dllapi.cpp src/cmdexec.cpp \ src/sdk_util.cpp src/hookchains_impl.cpp src/rechecker_api_impl.cpp public/interface.cpp LINK = -lm -ldl -static-intel -static-libgcc -no-intel-extensions -fno-exceptions - -OPT_FLAGS = -O3 -msse3 -ipo -no-prec-div -fp-model fast=2 -funroll-loops -fomit-frame-pointer -fno-stack-protector +OPT_FLAGS = -m32 -O3 -msse3 -fPIC -ipo -no-prec-div -fp-model fast=2 -funroll-loops -fomit-frame-pointer -fno-stack-protector INCLUDE = -I. -Isrc -Icommon -Idlls -Iengine -Ipm_shared -Ipublic -Imetamod diff --git a/common/mathlib.h b/common/mathlib.h index af30ae7..50b36aa 100644 --- a/common/mathlib.h +++ b/common/mathlib.h @@ -1,44 +1,48 @@ /* * -* 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 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. +* 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 +* 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. +* 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 MATHLIB_H -#define MATHLIB_H -#ifdef _WIN32 #pragma once -#endif + +#ifdef PLAY_GAMEDLL + +// probably gamedll compiled with flag /fpmath:fasted, +// so we need to use type double, otherwise will be the test failed + +typedef double float_precision; + +#else + +typedef float float_precision; + +#endif // PLAY_GAMEDLL typedef float vec_t; - -#if !defined DID_VEC3_T_DEFINE && !defined vec3_t -#define DID_VEC3_T_DEFINE typedef vec_t vec3_t[3]; -#endif - typedef vec_t vec4_t[4]; typedef int fixed16_t; @@ -65,35 +69,16 @@ typedef union DLONG_u #endif template -inline T min(T a, T b) -{ - return (a < b) ? a : b; -} +const T& min(const T& a, const T& b) { return (a < b) ? a : b; } template -inline T max(T a, T b) -{ - return (a < b) ? b : a; -} +const T& max(const T& a, const T& b) { return (a > b) ? a : b; } template -inline T clamp(T a, T min, T max) -{ - return (a > max) ? max : (a < min) ? min : a; -} +const T& clamp(const T& a, const T& min, const T& max) { return (a > max) ? max : (a < min) ? min : a; } -template -inline T bswap(T s) -{ - switch (sizeof(T)) - { - case 2: {auto res = __builtin_bswap16(*(uint16 *)&s); return *(T *)&res; } - case 4: {auto res = __builtin_bswap32(*(uint32 *)&s); return *(T *)&res; } - case 8: {auto res = __builtin_bswap64(*(uint64 *)&s); return *(T *)&res; } - default: return s; - } -} #else // __cplusplus + #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif @@ -105,4 +90,83 @@ inline T bswap(T s) #define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) #endif // __cplusplus -#endif // MATHLIB_H +// bitwise operators templates +//template::type> +//inline T operator~ (T a) { return (T)~(type)a; } +//template::type> +//inline T operator| (T a, T b) { return (T)((type)a | (type)b); } +//template::type> +//inline T operator& (T a, T b) { return (T)((type)a & (type)b); } +//template::type> +//inline T operator^ (T a, T b) { return (T)((type)a ^ (type)b); } +//template::type> +//inline T& operator|= (T& a, T b) { return (T&)((type&)a |= (type)b); } +//template::type> +//inline T& operator&= (T& a, T b) { return (T&)((type&)a &= (type)b); } +//template::type> +//inline T& operator^= (T& a, T b) { return (T&)((type&)a ^= (type)b); } + +inline float M_sqrt(float value) { + return _mm_cvtss_f32(_mm_sqrt_ss(_mm_load_ss(&value))); +} + +inline double M_sqrt(double value) { + auto v = _mm_load_sd(&value); + return _mm_cvtsd_f64(_mm_sqrt_sd(v, v)); +} + +template +inline double M_sqrt(T value) { + return sqrt(value); +} + +inline float M_min(float a, float b) { + return _mm_cvtss_f32(_mm_min_ss(_mm_load_ss(&a), _mm_load_ss(&b))); +} + +inline double M_min(double a, double b) { + return _mm_cvtsd_f64(_mm_min_sd(_mm_load_sd(&a), _mm_load_sd(&b))); +} + +template +inline T M_min(T a, T b) { + return min(a, b); +} + +inline float M_max(float a, float b) { + return _mm_cvtss_f32(_mm_max_ss(_mm_load_ss(&a), _mm_load_ss(&b))); +} + +inline double M_max(double a, double b) { + return _mm_cvtsd_f64(_mm_max_sd(_mm_load_sd(&a), _mm_load_sd(&b))); +} + +template +inline T M_max(T a, T b) { + return max(a, b); +} + +inline float M_clamp(float a, float min, float max) { + return _mm_cvtss_f32(_mm_min_ss(_mm_max_ss(_mm_load_ss(&a), _mm_load_ss(&min)), _mm_load_ss(&max))); +} + +inline double M_clamp(double a, double min, double max) { + return _mm_cvtsd_f64(_mm_min_sd(_mm_max_sd(_mm_load_sd(&a), _mm_load_sd(&min)), _mm_load_sd(&max))); +} + +template +inline T M_clamp(T a, T min, T max) { + return clamp(a, min, max); +} + +template +inline void SWAP(T &first, T &second) { + T temp = first; + first = second; + second = temp; +} + +#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} +#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} +#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} +#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;} diff --git a/dlls/vector.h b/dlls/vector.h index 6427e1e..f86a275 100644 --- a/dlls/vector.h +++ b/dlls/vector.h @@ -25,21 +25,36 @@ * version. * */ + #pragma once // 2DVector - used for many pathfinding and many other // operations that are treated as planar rather than 3d. class Vector2D { public: + // Construction/destruction inline Vector2D() : x(), y() {} inline Vector2D(float X, float Y) : x(X), y(Y) {} - inline Vector2D(const Vector2D &v) { *(int*)&x = *(int*)&v.x; *(int*)&y = *(int*)&v.y; } - inline Vector2D operator+(const Vector2D &v) const { return Vector2D(x + v.x, y + v.y); } - inline Vector2D operator-(const Vector2D &v) const { return Vector2D(x - v.x, y - v.y); } - inline Vector2D operator*(float fl) const { return Vector2D(x * fl, y * fl); } - inline Vector2D operator/(float fl) const { return Vector2D(x / fl, y / fl); } + inline Vector2D(const Vector2D &v) { *(int *)&x = *(int *)&v.x; *(int *)&y = *(int *)&v.y; } + + // Operators + inline bool operator==(const Vector2D &v) const { return x == v.x && y == v.y; } + inline bool operator!=(const Vector2D &v) const { return !(*this == v); } + + inline Vector2D operator*(float fl) const { return Vector2D(x * fl, y * fl); } + inline Vector2D operator/(float fl) const { return Vector2D(x / fl, y / fl); } inline Vector2D operator/=(float fl) const { return Vector2D(x / fl, y / fl); } + inline Vector2D operator+(const Vector2D &v) const { return Vector2D(x + v.x, y + v.y); } + inline Vector2D operator-(const Vector2D &v) const { return Vector2D(x - v.x, y - v.y); } + inline Vector2D operator*(const Vector2D &v) const { return Vector2D(x * v.x, y * v.y); } + inline Vector2D operator/(const Vector2D &v) const { return Vector2D(x / v.x, y / v.y); } + + inline Vector2D operator+=(const Vector2D &v) const { return Vector2D(x + v.x, y + v.y); } + inline Vector2D operator-=(const Vector2D &v) const { return Vector2D(x - v.x, y - v.y); } + inline Vector2D operator*=(const Vector2D &v) const { return Vector2D(x * v.x, y * v.y); } + inline Vector2D operator/=(const Vector2D &v) const { return Vector2D(x / v.x, y / v.y); } + inline float Length() const { return sqrt(x * x + y * y); } inline float LengthSquared() const { return (x * x + y * y); } @@ -56,7 +71,7 @@ public: return Vector2D(x * flLen, y * flLen); } - inline bool IsLengthLessThan(float length) const { return (LengthSquared() < length * length); } + inline bool IsLengthLessThan (float length) const { return (LengthSquared() < length * length); } inline bool IsLengthGreaterThan(float length) const { return (LengthSquared() > length * length); } inline float NormalizeInPlace() { @@ -93,26 +108,35 @@ public: // Construction/destruction inline Vector() : x(), y(), z() {} inline Vector(float X, float Y, float Z) : x(X), y(Y), z(Z) {} - inline Vector(const Vector &v) { *(int*)&x = *(int*)&v.x; *(int*)&y = *(int*)&v.y; *(int*)&z = *(int*)&v.z; } - inline Vector(const float rgfl[3]) { *(int*)&x = *(int*)&rgfl[0]; *(int*)&y = *(int*)&rgfl[1]; *(int*)&z = *(int*)&rgfl[2]; } + inline Vector(const Vector &v) { *(int *)&x = *(int *)&v.x; *(int *)&y = *(int *)&v.y; *(int *)&z = *(int *)&v.z; } + inline Vector(const float rgfl[3]) { *(int *)&x = *(int *)&rgfl[0]; *(int *)&y = *(int *)&rgfl[1]; *(int *)&z = *(int *)&rgfl[2]; } // Operators inline Vector operator-() const { return Vector(-x, -y, -z); } - inline int operator==(const Vector &v) const { return x == v.x && y == v.y && z == v.z; } - inline int operator!=(const Vector &v) const { return !(*this == v); } - inline Vector operator+(const Vector &v) const { return Vector(x + v.x, y + v.y, z + v.z); } - inline Vector operator-(const Vector &v) const { return Vector(x - v.x, y - v.y, z - v.z); } - inline Vector operator*(float fl) const { return Vector(x * fl, y * fl, z * fl); } - inline Vector operator/(float fl) const { return Vector(x / fl, y / fl, z / fl); } - inline Vector operator/=(float fl) const{ return Vector(x / fl, y / fl, z / fl); } + inline Vector operator*(float fl) const { return Vector(x * fl, y * fl, z * fl); } + inline Vector operator/(float fl) const { return Vector(x / fl, y / fl, z / fl); } + inline Vector operator/=(float fl) const { return Vector(x / fl, y / fl, z / fl); } + + inline bool operator==(const Vector &v) const { return x == v.x && y == v.y && z == v.z; } + inline bool operator!=(const Vector &v) const { return !(*this == v); } + + inline Vector operator+(const Vector &v) const { return Vector(x + v.x, y + v.y, z + v.z); } + inline Vector operator-(const Vector &v) const { return Vector(x - v.x, y - v.y, z - v.z); } + inline Vector operator*(const Vector &v) const { return Vector(x * v.x, y * v.y, z * v.z); } + inline Vector operator/(const Vector &v) const { return Vector(x / v.x, y / v.y, z / v.z); } + + inline Vector operator+=(const Vector &v) const { return Vector(x + v.x, y + v.y, z + v.z); } + inline Vector operator-=(const Vector &v) const { return Vector(x - v.x, y - v.y, z - v.z); } + inline Vector operator*=(const Vector &v) const { return Vector(x * v.x, y * v.y, z * v.z); } + inline Vector operator/=(const Vector &v) const { return Vector(x / v.x, y / v.y, z / v.z); } // Methods - inline void CopyToArray(float *rgfl) const { *(int*)&rgfl[0] = *(int*)&x; *(int*)&rgfl[1] = *(int*)&y; *(int*)&rgfl[2] = *(int*)&z; } + inline void CopyToArray(float *rgfl) const { *(int *)&rgfl[0] = *(int *)&x; *(int *)&rgfl[1] = *(int *)&y; *(int *)&rgfl[2] = *(int *)&z; } inline float Length() const { return sqrt(x * x + y * y + z * z); } inline float LengthSquared() const { return (x * x + y * y + z * z); } - operator float*() { return &x; } // Vectors will now automatically convert to float * when needed - operator const float*() const { return &x; } // Vectors will now automatically convert to float * when needed + operator float*() { return &x; } // Vectors will now automatically convert to float * when needed + operator const float*() const { return &x; } // Vectors will now automatically convert to float * when needed inline Vector Normalize() { @@ -126,14 +150,14 @@ public: inline Vector2D Make2D() const { Vector2D Vec2; - *(int*)&Vec2.x = *(int*)&x; - *(int*)&Vec2.y = *(int*)&y; + *(int *)&Vec2.x = *(int *)&x; + *(int *)&Vec2.y = *(int *)&y; return Vec2; } inline float Length2D() const { return sqrt(x * x + y * y); } - inline bool IsLengthLessThan(float length) const { return (LengthSquared() < length * length); } + inline bool IsLengthLessThan (float length) const { return (LengthSquared() < length * length); } inline bool IsLengthGreaterThan(float length) const { return (LengthSquared() > length * length); } inline float NormalizeInPlace() @@ -166,11 +190,3 @@ inline Vector operator*(float fl, const Vector &v) { return v * fl; } inline float DotProduct(const Vector &a, const Vector &b) { return (a.x * b.x + a.y * b.y + a.z * b.z); } inline float DotProduct2D(const Vector &a, const Vector &b) { return (a.x * b.x + a.y * b.y); } inline Vector CrossProduct(const Vector &a, const Vector &b) { return Vector(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } - -template -inline void SWAP(T &first, T &second) -{ - T temp = first; - first = second; - second = temp; -} diff --git a/public/basetypes.h b/public/basetypes.h index a953ffe..5975e0e 100644 --- a/public/basetypes.h +++ b/public/basetypes.h @@ -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 "mathlib.h" // For backward compatibilty only... #include "tier0/platform.h" @@ -24,45 +45,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) - -#ifndef MATHLIB_H -// In case this ever changes -#define M_PI 3.14159265358979323846 - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#endif // MATHLIB_H + (((number) + ((boundary) - 1)) / (boundary)) * (boundary) #ifndef FALSE #define FALSE 0 #define TRUE (!FALSE) #endif - typedef int BOOL; typedef int qboolean; typedef unsigned long ULONG; @@ -72,216 +64,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(&f); -} - -inline unsigned long const& FloatBits(vec_t const& f) -{ - return *reinterpret_cast(&f); -} - -inline vec_t BitsToFloat(unsigned long i) -{ - return *reinterpret_cast(&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 -// 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 MakeHandle(HANDLE_TYPE val) - { - return CIntHandle16(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 MakeHandle(HANDLE_TYPE val) - { - return CIntHandle32(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 diff --git a/public/interface.cpp b/public/interface.cpp index 1bd0c92..e6de1be 100644 --- a/public/interface.cpp +++ b/public/interface.cpp @@ -26,7 +26,7 @@ * */ -#include "interface.h" +#include "precompiled.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN diff --git a/public/interface.h b/public/interface.h index 9773a99..0aeaca4 100644 --- a/public/interface.h +++ b/public/interface.h @@ -87,9 +87,9 @@ public: EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton) #ifdef _WIN32 - #define EXPORT_FUNCTION __declspec(dllexport) + #define EXPORT_FUNCTION __declspec(dllexport) EXT_FUNC #else - #define EXPORT_FUNCTION __attribute__((visibility("default"))) + #define EXPORT_FUNCTION __attribute__((visibility("default"))) EXT_FUNC #endif // _WIN32 // This function is automatically exported and allows you to access any interfaces exposed with the above macros. diff --git a/public/strtools.h b/public/strtools.h new file mode 100644 index 0000000..8b414bf --- /dev/null +++ b/public/strtools.h @@ -0,0 +1,211 @@ +/* +* +* 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 + +#ifdef _WIN32 +const char CORRECT_PATH_SEPARATOR = '\\'; +const char INCORRECT_PATH_SEPARATOR = '/'; +#else +const char CORRECT_PATH_SEPARATOR = '/'; +const char INCORRECT_PATH_SEPARATOR = '\\'; +#endif + +#if !defined(_WIN32) +inline char *_strupr(char *start) +{ + char *str = start; + while (str && *str) + { + *str = (char)toupper(*str); + str++; + } + + return start; +} + +inline char *_strlwr(char *start) +{ + char *str = start; + while (str && *str) + { + *str = (char)tolower(*str); + str++; + } + + return start; +} +#endif + +#if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS) + #define Q_memset A_memset + #define Q_memcpy A_memcpy + #define Q_memcmp A_memcmp + #define Q_memmove A_memmove + #define Q_strlen A_strlen + #define Q_strcpy A_strcpy + #define Q_strncpy strncpy + #define Q_strcat A_strcat + #define Q_strncat strncat + #define Q_strcmp A_strcmp + #define Q_strncmp strncmp + #define Q_strdup _strdup + #define Q_stricmp A_stricmp + #define Q_strnicmp _strnicmp + #define Q_strstr A_strstr + #define Q_strchr strchr + #define Q_strrchr strrchr + #define Q_strlwr A_strtolower + #define Q_strupr A_strtoupper + #define Q_sprintf sprintf + #define Q_snprintf _snprintf + #define Q_vsnprintf _vsnprintf + #define Q_vsnwprintf _vsnwprintf + #define Q_atoi atoi + #define Q_atof atof + #define Q_sqrt M_sqrt + #define Q_min M_min + #define Q_max M_max + #define Q_clamp M_clamp + #define Q_abs abs + #define Q_fabs fabs + #define Q_tan tan + #define Q_atan atan + #define Q_atan2 atan2 + #define Q_acos acos + #define Q_cos cos + #define Q_sin sin + #define Q_pow pow + #define Q_fmod fmod +#else + #define Q_memset memset + #define Q_memcpy memcpy + #define Q_memcmp memcmp + #define Q_memmove memmove + #define Q_strlen strlen + #define Q_strcpy strcpy + #define Q_strncpy strncpy + #define Q_strcat strcat + #define Q_strncat strncat + #define Q_strcmp strcmp + #define Q_strncmp strncmp + #define Q_strdup _strdup + #define Q_stricmp _stricmp + #define Q_strnicmp _strnicmp + #define Q_strstr strstr + #define Q_strchr strchr + #define Q_strrchr strrchr + #define Q_strlwr _strlwr + #define Q_strupr _strupr + #define Q_sprintf sprintf + #define Q_snprintf _snprintf + #define Q_vsnprintf _vsnprintf + #define Q_vsnwprintf _vsnwprintf + #define Q_atoi atoi + #define Q_atof atof + #define Q_sqrt sqrt + #define Q_min min + #define Q_max max + #define Q_clamp clamp + #define Q_abs abs + #define Q_fabs fabs + #define Q_tan tan + #define Q_atan atan + #define Q_atan2 atan2 + #define Q_acos acos + #define Q_cos cos + #define Q_sin sin + #define Q_pow pow + #define Q_fmod fmod +#endif // #if defined(ASMLIB_H) && defined(HAVE_OPT_STRTOOLS) + +// a safe variant of strcpy that truncates the result to fit in the destination buffer +template +char *Q_strlcpy(char (&dest)[size], const char *src) { + Q_strncpy(dest, src, size - 1); + dest[size - 1] = '\0'; + return dest; +} + +inline char *Q_strnlcpy(char *dest, const char *src, size_t n) { + Q_strncpy(dest, src, n - 1); + dest[n - 1] = '\0'; + return dest; +} + +// safely concatenate two strings. +// a variant of strcat that truncates the result to fit in the destination buffer +template +size_t Q_strlcat(char (&dest)[size], const char *src) +{ + size_t srclen; // Length of source string + size_t dstlen; // Length of destination string + + // Figure out how much room is left + dstlen = Q_strlen(dest); + size_t length = size - dstlen + 1; + + if (!length) { + // No room, return immediately + return dstlen; + } + + // Figure out how much room is needed + srclen = Q_strlen(src); + + // Copy the appropriate amount + if (srclen > length) { + srclen = length; + } + + Q_memcpy(dest + dstlen, src, srclen); + dest[dstlen + srclen] = '\0'; + + return dstlen + srclen; +} + +// Force slashes of either type to be = separator character +inline void Q_FixSlashes(char *pname, char separator = CORRECT_PATH_SEPARATOR) +{ + while (*pname) + { + if (*pname == INCORRECT_PATH_SEPARATOR || *pname == CORRECT_PATH_SEPARATOR) + { + *pname = separator; + } + + pname++; + } +} + +// strcpy that works correctly with overlapping src and dst buffers +inline char *Q_strcpy_s(char *dst, char *src) { + int len = Q_strlen(src); + Q_memmove(dst, src, len + 1); + return dst; +} diff --git a/public/tier0/dbg.h b/public/tier0/dbg.h index 37b4d0a..e1b67bf 100644 --- a/public/tier0/dbg.h +++ b/public/tier0/dbg.h @@ -19,9 +19,8 @@ #pragma once #endif -#include "osconfig.h" #include "basetypes.h" -#include "tier0/platform.h" + #include #include #include diff --git a/public/tier0/mem.h b/public/tier0/mem.h deleted file mode 100644 index b539eb3..0000000 --- a/public/tier0/mem.h +++ /dev/null @@ -1,37 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: Memory allocation! -// -// $NoKeywords: $ -//============================================================================= - -#ifndef TIER0_MEM_H -#define TIER0_MEM_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "osconfig.h" -#include -#include "tier0/platform.h" - -#ifdef TIER0_DLL_EXPORT -# define MEM_INTERFACE DLL_EXPORT -#else -# define MEM_INTERFACE DLL_IMPORT -#endif - - -//----------------------------------------------------------------------------- -// DLL-exported methods for particular kinds of memory -//----------------------------------------------------------------------------- -MEM_INTERFACE void *MemAllocScratch(int nMemSize); -MEM_INTERFACE void MemFreeScratch(); - -#ifdef __linux__ -MEM_INTERFACE void ZeroMemory(void *mem, size_t length); -#endif - - -#endif /* TIER0_MEM_H */ diff --git a/public/tier0/memalloc.h b/public/tier0/memalloc.h deleted file mode 100644 index 45ceede..0000000 --- a/public/tier0/memalloc.h +++ /dev/null @@ -1,77 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: This header should never be used directly from leaf code!!! -// Instead, just add the file memoverride.cpp into your project and all this -// will automagically be used -// -// $NoKeywords: $ -//============================================================================= - -#ifndef TIER0_MEMALLOC_H -#define TIER0_MEMALLOC_H - -#ifdef _WIN32 -#pragma once -#endif - -#include "osconfig.h" -#include -#include "tier0/mem.h" - -struct _CrtMemState; - -//----------------------------------------------------------------------------- -// NOTE! This should never be called directly from leaf code -// Just use new,delete,malloc,free etc. They will call into this eventually -//----------------------------------------------------------------------------- -class IMemAlloc -{ -public: - // Release versions - virtual void *Alloc(size_t nSize) = 0; - virtual void *Realloc(void *pMem, size_t nSize) = 0; - virtual void Free(void *pMem) = 0; - virtual void *Expand(void *pMem, size_t nSize) = 0; - - // Debug versions - virtual void *Alloc(size_t nSize, const char *pFileName, int nLine) = 0; - virtual void *Realloc(void *pMem, size_t nSize, const char *pFileName, int nLine) = 0; - virtual void Free(void *pMem, const char *pFileName, int nLine) = 0; - virtual void *Expand(void *pMem, size_t nSize, const char *pFileName, int nLine) = 0; - - // Returns size of a particular allocation - virtual size_t GetSize(void *pMem) = 0; - - // Force file + line information for an allocation - virtual void PushAllocDbgInfo(const char *pFileName, int nLine) = 0; - virtual void PopAllocDbgInfo() = 0; - - // FIXME: Remove when we have our own allocator - // these methods of the Crt debug code is used in our codebase currently - virtual long CrtSetBreakAlloc(long lNewBreakAlloc) = 0; - virtual int CrtSetReportMode(int nReportType, int nReportMode) = 0; - virtual int CrtIsValidHeapPointer(const void *pMem) = 0; - virtual int CrtCheckMemory(void) = 0; - virtual int CrtSetDbgFlag(int nNewFlag) = 0; - virtual void CrtMemCheckpoint(_CrtMemState *pState) = 0; - - // FIXME: Make a better stats interface - virtual void DumpStats() = 0; - - // FIXME: Remove when we have our own allocator - virtual void* CrtSetReportFile(int nRptType, void* hFile) = 0; - virtual void* CrtSetReportHook(void* pfnNewHook) = 0; - virtual int CrtDbgReport(int nRptType, const char * szFile, - int nLine, const char * szModule, const char * pMsg) = 0; - - virtual int heapchk() = 0; -}; - - -//----------------------------------------------------------------------------- -// Singleton interface -//----------------------------------------------------------------------------- -IMemAlloc *g_pMemAlloc; - - -#endif /* TIER0_MEMALLOC_H */ diff --git a/public/tier0/memdbgoff.h b/public/tier0/memdbgoff.h deleted file mode 100644 index e11e382..0000000 --- a/public/tier0/memdbgoff.h +++ /dev/null @@ -1,21 +0,0 @@ -//========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============ -// -// Purpose: This header, which must be the final line of a .h file, -// causes all crt methods to stop using debugging versions of the memory allocators. -// NOTE: Use memdbgon.h to re-enable memory debugging. -// -// $NoKeywords: $ -//============================================================================= - -#ifdef MEM_DEBUG_ON - -#undef malloc -#undef realloc -#undef calloc -#undef free -#undef _expand -#undef _msize -#undef new -#undef MEM_DEBUG_ON - -#endif diff --git a/public/tier0/memdbgon.h b/public/tier0/memdbgon.h deleted file mode 100644 index 42be466..0000000 --- a/public/tier0/memdbgon.h +++ /dev/null @@ -1,93 +0,0 @@ -//========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============ -// -// Purpose: This header, which must be the final include in a .cpp (or .h) file, -// causes all crt methods to use debugging versions of the memory allocators. -// NOTE: Use memdbgoff.h to disable memory debugging. -// -// $NoKeywords: $ -//============================================================================= - -// SPECIAL NOTE! This file must *not* use include guards; we need to be able -// to include this potentially multiple times (since we can deactivate debugging -// by including memdbgoff.h) - -// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!! -#include "osconfig.h" - -#ifdef _DEBUG - -#include -#include -#include -#include - -#include "tier0/memdbgoff.h" - -#define MEM_DEBUG_ON 1 - -#undef malloc -#undef realloc -#undef calloc -#undef _expand -#undef free -#undef _msize - -#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define free(p) _free_dbg(p, _NORMAL_BLOCK) -#define _msize(p) _msize_dbg(p, _NORMAL_BLOCK) -#define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) - - -#if defined(__AFX_H__) && defined(DEBUG_NEW) -#define new DEBUG_NEW -#else -#undef new -#define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) -#define new MEMALL_DEBUG_NEW -#endif - -#undef _strdup -#undef strdup -#undef _wcsdup -#undef wcsup - -#define _strdup(s) strdup_dbg(s, __FILE__, __LINE__) -#define strdup(s) strdup_dbg(s, __FILE__, __LINE__) -#define _wcsdup(s) wcsdup_dbg(s, __FILE__, __LINE__) -#define wcsdup(s) wcsdup_dbg(s, __FILE__, __LINE__) - -// Make sure we don't define strdup twice -#ifndef MEM_DBG_DEFINED_STRDUP -#define MEM_DBG_DEFINED_STRDUP 1 - -inline char *strdup_dbg(const char *pString, const char *pFileName, unsigned nLine) -{ - char *pMemory; - - if (!pString) - return NULL; - - if ((pMemory = (char *)_malloc_dbg(strlen(pString) + 1, _NORMAL_BLOCK, pFileName, nLine)) != NULL) - return strcpy(pMemory, pString); - - return NULL; -} - -inline wchar_t *wcsdup_dbg(const wchar_t *pString, const char *pFileName, unsigned nLine) -{ - wchar_t *pMemory; - - if (!pString) - return NULL; - - if ((pMemory = (wchar_t *)_malloc_dbg((wcslen(pString) + 1) * sizeof(wchar_t), _NORMAL_BLOCK, pFileName, nLine)) != NULL) - return wcscpy(pMemory, pString); - - return NULL; -} - -#endif // DBMEM_DEFINED_STRDUP - -#endif // _DEBUG diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 1f85749..b2b1f22 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -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 - -// need this for memset -#include +#include // need this for _alloca +#include // 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 -#include - -// 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 -inline T WordSwapC(T w) -{ - uint16 temp; - - temp = ((*((uint16 *)&w) & 0xff00) >> 8); - temp |= ((*((uint16 *)&w) & 0x00ff) << 8); - - return *((T*)&temp); -} - -template -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 -inline T WordSwapAsm(T w) -{ - __asm - { - mov ax, w - xchg al, ah - } -} - -template -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 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 -inline void Construct(T* pMemory) +inline void Construct(T *pMemory) { - new(pMemory)T; + new(pMemory) T; } template -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 -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 -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 \ -struct __Function_##NAME \ -{ \ - static RETURN_TYPE FASTCALL Run ARGS; \ -}; \ - \ -template \ -struct __MetaLooper_##NAME : __MetaLooper_##NAME \ -{ \ - __Type_##NAME func; \ - inline __MetaLooper_##NAME() { func = __Function_##NAME::Run; } \ -}; \ - \ -template<> \ -struct __MetaLooper_##NAME<0> \ -{ \ - __Type_##NAME func; \ - inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \ -}; \ - \ -class NAME \ -{ \ -private: \ - static const __MetaLooper_##NAME m; \ -public: \ - enum { count = COUNT }; \ - static const __Type_##NAME* functions; \ -}; \ -const __MetaLooper_##NAME NAME::m; \ -const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \ -template \ -RETURN_TYPE FASTCALL __Function_##NAME::Run ARGS - - -#define LOOP_INTERCHANGE(BOOLEAN, CODE)\ - if( (BOOLEAN) )\ - {\ - CODE;\ - } else\ - {\ - CODE;\ - } - - -#endif /* PLATFORM_H */ diff --git a/public/tier0/platform_linux.cpp b/public/tier0/platform_linux.cpp deleted file mode 100644 index ca1e44e..0000000 --- a/public/tier0/platform_linux.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "precompiled.h" - -double Plat_FloatTime() -{ - struct timeval tp; - static int secbase = 0; - - gettimeofday(&tp, NULL); - - if (!secbase) - { - secbase = tp.tv_sec; - return (tp.tv_usec / 1000000.0); - } - - return ((tp.tv_sec - secbase) + tp.tv_usec / 1000000.0); -} - -unsigned long Plat_MSTime() -{ - struct timeval tp; - static int secbase = 0; - - gettimeofday(&tp, NULL); - - if (!secbase) - { - secbase = tp.tv_sec; - return (tp.tv_usec / 1000000.0); - } - - return (unsigned long)((tp.tv_sec - secbase) + tp.tv_usec / 1000000.0); - -} - - - -bool vtune(bool resume) -{ - return true; -} - - -// -------------------------------------------------------------------------------------------------- // -// Memory stuff. -// -------------------------------------------------------------------------------------------------- // - - -void Plat_SetThreadName(unsigned long dwThreadID, const char *pName) -{ - Assert("Plat_SetThreadName not implemented"); -} diff --git a/public/tier0/platform_win32.cpp b/public/tier0/platform_win32.cpp deleted file mode 100644 index 765d0a6..0000000 --- a/public/tier0/platform_win32.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "precompiled.h" - -static LARGE_INTEGER g_PerformanceFrequency; -static LARGE_INTEGER g_MSPerformanceFrequency; -static LARGE_INTEGER g_ClockStart; -static HINSTANCE g_pVTuneDLL; - -static void InitTime() -{ - if (!g_PerformanceFrequency.QuadPart) - { - QueryPerformanceFrequency(&g_PerformanceFrequency); - g_MSPerformanceFrequency.QuadPart = g_PerformanceFrequency.QuadPart / 1000; - QueryPerformanceCounter(&g_ClockStart); - } -} - -double Plat_FloatTime() -{ - InitTime(); - - LARGE_INTEGER CurrentTime; - - QueryPerformanceCounter(&CurrentTime); - - double fRawSeconds = (double)(CurrentTime.QuadPart - g_ClockStart.QuadPart) / (double)(g_PerformanceFrequency.QuadPart); - - return fRawSeconds; -} - -unsigned long Plat_MSTime() -{ - InitTime(); - - LARGE_INTEGER CurrentTime; - - QueryPerformanceCounter(&CurrentTime); - - return (unsigned long)((CurrentTime.QuadPart - g_ClockStart.QuadPart) / g_MSPerformanceFrequency.QuadPart); -} - -void free_vtune() -{ - FreeLibrary(g_pVTuneDLL); -} - -bool vtune(bool resume) -{ - static bool bInitialized = false; - static void(__cdecl *VTResume)(void) = NULL; - static void(__cdecl *VTPause) (void) = NULL; - - // Grab the Pause and Resume function pointers from the VTune DLL the first time through: - if (!bInitialized) - { - bInitialized = true; - - g_pVTuneDLL = LoadLibrary("vtuneapi.dll"); - - if (g_pVTuneDLL) - { - VTResume = (void(__cdecl *)())GetProcAddress(g_pVTuneDLL, "VTResume"); - VTPause = (void(__cdecl *)())GetProcAddress(g_pVTuneDLL, "VTPause"); - atexit(free_vtune); - } - } - - // Call the appropriate function, as indicated by the argument: - if (resume && VTResume) - { - VTResume(); - return true; - - } - else if (!resume && VTPause) - { - VTPause(); - return true; - } - - return false; - -} - - -// -------------------------------------------------------------------------------------------------- // -// Memory stuff. -// -------------------------------------------------------------------------------------------------- // diff --git a/public/utlbuffer.cpp b/public/utlbuffer.cpp index 53ad7f4..2a4811e 100644 --- a/public/utlbuffer.cpp +++ b/public/utlbuffer.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ +//========= Copyright 1996-2001, Valve LLC, 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 @@ -13,6 +13,12 @@ #include "precompiled.h" +#include +#include +#include +#include +#include + //----------------------------------------------------------------------------- // constructors //----------------------------------------------------------------------------- diff --git a/public/utllinkedlist.h b/public/utllinkedlist.h index a4d973d..d324ba0 100644 --- a/public/utllinkedlist.h +++ b/public/utllinkedlist.h @@ -21,7 +21,7 @@ #include "osconfig.h" #include "basetypes.h" #include "utlmemory.h" -#include "tier0/dbg.h" +//#include "tier0/dbg.h" // This is a useful macro to iterate from head to tail in a linked list. diff --git a/public/utlmemory.h b/public/utlmemory.h index 7ccce20..4aecc6c 100644 --- a/public/utlmemory.h +++ b/public/utlmemory.h @@ -1,59 +1,90 @@ -//=========== (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. -//============================================================================= +/* +* +* 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 UTLMEMORY_H -#define UTLMEMORY_H - -#ifdef _WIN32 #pragma once -#endif #include "osconfig.h" #include "tier0/dbg.h" #include -#include "tier0/platform.h" #pragma warning (disable:4100) #pragma warning (disable:4514) -//----------------------------------------------------------------------------- // The CUtlMemory class: // A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T > +template 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; @@ -80,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::CUtlMemory(int nGrowSize, int nInitAllocationCount) : m_pMemory(0), -m_nAllocationCount(nInitAllocationCount), m_nGrowSize(nGrowSize) +template +CUtlMemory::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::CUtlMemory(T* pMemory, int numElements) : m_pMemory(pMemory), +template +CUtlMemory::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::~CUtlMemory() +template +CUtlMemory::~CUtlMemory() { Purge(); } +template +void CUtlMemory::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::SetExternalBuffer(T* pMemory, int numElements) +template +void CUtlMemory::SetExternalBuffer(T *pMemory, int numElements) { // Blow away any existing allocated memory Purge(); @@ -131,110 +170,91 @@ void CUtlMemory::SetExternalBuffer(T* pMemory, int numElements) m_nGrowSize = EXTERNAL_BUFFER_MARKER; } - -//----------------------------------------------------------------------------- // element access -//----------------------------------------------------------------------------- -template< class T > -inline T& CUtlMemory::operator[](int i) +template +inline T& CUtlMemory::operator[](I i) { Assert(IsIdxValid(i)); return m_pMemory[i]; } -template< class T > -inline T const& CUtlMemory::operator[](int i) const +template +inline T const& CUtlMemory::operator[](I i) const { Assert(IsIdxValid(i)); return m_pMemory[i]; } -template< class T > -inline T& CUtlMemory::Element(int i) +template +inline T& CUtlMemory::Element(I i) { Assert(IsIdxValid(i)); return m_pMemory[i]; } -template< class T > -inline T const& CUtlMemory::Element(int i) const +template +inline T const& CUtlMemory::Element(I i) const { Assert(IsIdxValid(i)); return m_pMemory[i]; } - -//----------------------------------------------------------------------------- // is the memory externally allocated? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlMemory::IsExternallyAllocated() const +template +bool CUtlMemory::IsExternallyAllocated() const { return m_nGrowSize == EXTERNAL_BUFFER_MARKER; } - -template< class T > -void CUtlMemory::SetGrowSize(int nSize) +template +void CUtlMemory::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::Base() +template +inline T *CUtlMemory::Base() { return m_pMemory; } -template< class T > -inline T const* CUtlMemory::Base() const +template +inline T const *CUtlMemory::Base() const { return m_pMemory; } - -//----------------------------------------------------------------------------- // Size -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlMemory::NumAllocated() const +template +inline int CUtlMemory::NumAllocated() const { return m_nAllocationCount; } -template< class T > -inline int CUtlMemory::Count() const +template +inline int CUtlMemory::Count() const { return m_nAllocationCount; } - -//----------------------------------------------------------------------------- // Is element index valid? -//----------------------------------------------------------------------------- -template< class T > -inline bool CUtlMemory::IsIdxValid(int i) const +template +inline bool CUtlMemory::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::Grow(int num) +template +void CUtlMemory::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; } @@ -265,27 +285,24 @@ void CUtlMemory::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::EnsureCapacity(int num) +template +inline void CUtlMemory::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; } @@ -293,31 +310,25 @@ inline void CUtlMemory::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::Purge() +template +void CUtlMemory::Purge() { if (!IsExternallyAllocated()) { if (m_pMemory) { - free((void*)m_pMemory); + free((void *)m_pMemory); m_pMemory = 0; } m_nAllocationCount = 0; } } - - -#endif // UTLSTORAGE_H diff --git a/public/utlrbtree.h b/public/utlrbtree.h index e8fca65..4982cee 100644 --- a/public/utlrbtree.h +++ b/public/utlrbtree.h @@ -1,161 +1,178 @@ -//=========== (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. -// -// Purpose: -// -// $Header: $ -// $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 UTLRBTREE_H -#define UTLRBTREE_H +#pragma once -//#include #include "utlmemory.h" -//----------------------------------------------------------------------------- // Tool to generate a default compare function for any type that implements // operator<, including all simple types -//----------------------------------------------------------------------------- - -template +template class CDefOps { public: - static bool LessFunc( const T &lhs, const T &rhs ) { return ( lhs < rhs ); } + static bool LessFunc(const T &lhs, const T &rhs) { return (lhs < rhs); } }; -#define DefLessFunc( type ) CDefOps::LessFunc +#define DefLessFunc(type) CDefOps::LessFunc -//------------------------------------- +inline bool StringLessThan(const char * const &lhs, const char * const &rhs) { return (strcmp(lhs, rhs) < 0); } +inline bool CaselessStringLessThan(const char * const &lhs, const char * const &rhs) { return (_stricmp(lhs, rhs) < 0); } -inline bool StringLessThan( const char * const &lhs, const char * const &rhs) { return ( strcmp( lhs, rhs) < 0 ); } -inline bool CaselessStringLessThan( const char * const &lhs, const char * const &rhs ) { return ( _stricmp( lhs, rhs) < 0 ); } - -//------------------------------------- // inline these two templates to stop multiple definitions of the same code -template <> inline bool CDefOps::LessFunc( const char * const &lhs, const char * const &rhs ) { return StringLessThan( lhs, rhs ); } -template <> inline bool CDefOps::LessFunc( char * const &lhs, char * const &rhs ) { return StringLessThan( lhs, rhs ); } - -//------------------------------------- +template <> inline bool CDefOps::LessFunc(const char * const &lhs, const char * const &rhs) { return StringLessThan(lhs, rhs); } +template <> inline bool CDefOps::LessFunc(char * const &lhs, char * const &rhs) { return StringLessThan(lhs, rhs); } template -void SetDefLessFunc( RBTREE_T &RBTree ) +void SetDefLessFunc(RBTREE_T &RBTree) { -#ifdef _WIN32 - RBTree.SetLessFunc( DefLessFunc( RBTREE_T::KeyType_t ) ); -#elif _LINUX - RBTree.SetLessFunc( DefLessFunc( typename RBTREE_T::KeyType_t ) ); -#endif + RBTree.SetLessFunc(DefLessFunc(typename RBTREE_T::KeyType_t)); } -//----------------------------------------------------------------------------- // A red-black binary search tree -//----------------------------------------------------------------------------- +template +struct UtlRBTreeLinks_t +{ + I m_Left; + I m_Right; + I m_Parent; + I m_Tag; +}; -template +template +struct UtlRBTreeNode_t: public UtlRBTreeLinks_t +{ + T m_Data; +}; + +// A red-black binary search tree +template , I>> class CUtlRBTree { public: - // Less func typedef - // Returns true if the first parameter is "less" than the second - typedef bool (*LessFunc_t)( T const &, T const & ); - typedef T KeyType_t; typedef T ElemType_t; typedef I IndexType_t; + // Less func typedef + // Returns true if the first parameter is "less" than the second + typedef L LessFunc_t; + // constructor, destructor // Left at growSize = 0, the memory will first allocate 1 element and double in size // at each increment. // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below - CUtlRBTree( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 ); - ~CUtlRBTree( ); - + CUtlRBTree(int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0); + ~CUtlRBTree(); + // gets particular elements - T& Element( I i ); - T const &Element( I i ) const; - T& operator[]( I i ); - T const &operator[]( I i ) const; - + T& Element(I i); + T const& Element(I i) const; + T& operator[](I i); + T const& operator[](I i) const; + // Gets the root - I Root() const; - + I Root() const; + // Num elements unsigned int Count() const; - + // Max "size" of the vector - I MaxElement() const; - - // Gets the children - I Parent( I i ) const; - I LeftChild( I i ) const; - I RightChild( I i ) const; - + I MaxElement() const; + + // Gets the children + I Parent(I i) const; + I LeftChild(I i) const; + I RightChild(I i) const; + // Tests if a node is a left or right child - bool IsLeftChild( I i ) const; - bool IsRightChild( I i ) const; - + bool IsLeftChild(I i) const; + bool IsRightChild(I i) const; + // Tests if root or leaf - bool IsRoot( I i ) const; - bool IsLeaf( I i ) const; - + bool IsRoot(I i) const; + bool IsLeaf(I i) const; + // Checks if a node is valid and in the tree - bool IsValidIndex( I i ) const; - + bool IsValidIndex(I i) const; + // Checks if the tree as a whole is valid - bool IsValid() const; - + bool IsValid() const; + // Invalid index static I InvalidIndex(); - + // returns the tree depth (not a very fast operation) - int Depth( I node ) const; - int Depth() const; - + int Depth(I node) const; + int Depth() const; + // Sets the less func - void SetLessFunc( LessFunc_t func ); - + void SetLessFunc(LessFunc_t func); + // Allocation method - I NewNode(); + I NewNode(); // Insert method (inserts in order) - I Insert( T const &insert ); - void Insert( const T *pArray, int nItems ); - - // Find method - I Find( T const &search ) const; - - // Remove methods - void RemoveAt( I i ); - bool Remove( T const &remove ); - void RemoveAll( ); - - // Allocation, deletion - void FreeNode( I i ); - - // Iteration - I FirstInorder() const; - I NextInorder( I i ) const; - I PrevInorder( I i ) const; - I LastInorder() const; - - I FirstPreorder() const; - I NextPreorder( I i ) const; - I PrevPreorder( I i ) const; - I LastPreorder( ) const; - - I FirstPostorder() const; - I NextPostorder( I i ) const; + I Insert(T const &insert); + void Insert(const T *pArray, int nItems); - // If you change the search key, this can be used to reinsert the + // Find method + I Find(T const &search) const; + + // Remove methods + void RemoveAt(I i); + bool Remove(T const &remove); + void RemoveAll(); + + // Allocation, deletion + void FreeNode(I i); + + // Iteration + I FirstInorder() const; + I NextInorder(I i) const; + I PrevInorder(I i) const; + I LastInorder() const; + + I FirstPreorder() const; + I NextPreorder(I i) const; + I PrevPreorder(I i) const; + I LastPreorder() const; + + I FirstPostorder() const; + I NextPostorder(I i) const; + + // If you change the search key, this can be used to reinsert the // element into the tree. - void Reinsert( I elem ); - + void Reinsert(I elem); + +private: + // Can't copy the tree this way! + CUtlRBTree &operator=(const CUtlRBTree &other); protected: enum NodeColor_t @@ -163,336 +180,258 @@ protected: RED = 0, BLACK }; - - struct Links_t - { - I m_Left; - I m_Right; - I m_Parent; - I m_Tag; - }; - - struct Node_t : public Links_t - { - T m_Data; - }; + + typedef UtlRBTreeNode_t Node_t; + typedef UtlRBTreeLinks_t Links_t; // Sets the children - void SetParent( I i, I parent ); - void SetLeftChild( I i, I child ); - void SetRightChild( I i, I child ); - void LinkToParent( I i, I parent, bool isLeft ); + void SetParent(I i, I parent); + void SetLeftChild(I i, I child); + void SetRightChild(I i, I child); + void LinkToParent(I i, I parent, bool isLeft); // Gets at the links - Links_t const &Links( I i ) const; - Links_t &Links( I i ); - + Links_t const& Links(I i) const; + Links_t& Links(I i); + // Checks if a link is red or black - bool IsRed( I i ) const; - bool IsBlack( I i ) const; - + bool IsRed(I i) const; + bool IsBlack(I i) const; + // Sets/gets node color - NodeColor_t Color( I i ) const; - void SetColor( I i, NodeColor_t c ); - + NodeColor_t Color(I i) const; + void SetColor(I i, NodeColor_t c); + // operations required to preserve tree balance void RotateLeft(I i); void RotateRight(I i); void InsertRebalance(I i); void RemoveRebalance(I i); - + // Insertion, removal - I InsertAt( I parent, bool leftchild ); - + I InsertAt(I parent, bool leftchild); + // copy constructors not allowed - CUtlRBTree( CUtlRBTree const &tree ); - + CUtlRBTree(CUtlRBTree const &tree); + // Inserts a node into the tree, doesn't copy the data in. - void FindInsertionPosition( T const &insert, I &parent, bool &leftchild ); + void FindInsertionPosition(T const &insert, I &parent, bool &leftchild); // Remove and add back an element in the tree. - void Unlink( I elem ); - void Link( I elem ); + void Unlink(I elem); + void Link(I elem); // Used for sorting. LessFunc_t m_LessFunc; - - CUtlMemory m_Elements; + + M m_Elements; I m_Root; I m_NumElements; I m_FirstFree; I m_TotalElements; - - Node_t* m_pElements; - - void ResetDbgInfo() - { - m_pElements = (Node_t*)m_Elements.Base(); - } }; - -//----------------------------------------------------------------------------- // constructor, destructor -//----------------------------------------------------------------------------- - -template -CUtlRBTree::CUtlRBTree( int growSize, int initSize, LessFunc_t lessfunc ) : - m_Elements( growSize, initSize ), - m_LessFunc( lessfunc ), - m_Root( InvalidIndex() ), - m_NumElements( 0 ), m_TotalElements( 0 ), - m_FirstFree( InvalidIndex() ) -{ - ResetDbgInfo(); -} - -template -CUtlRBTree::~CUtlRBTree() +template +CUtlRBTree::CUtlRBTree(int growSize, int initSize, LessFunc_t lessfunc) : + m_Elements(growSize, initSize), + m_LessFunc(lessfunc), + m_Root(InvalidIndex()), + m_NumElements(0), m_TotalElements(0), + m_FirstFree(InvalidIndex()) +{ +} + +template +CUtlRBTree::~CUtlRBTree() { } -//----------------------------------------------------------------------------- // gets particular elements -//----------------------------------------------------------------------------- - -template -inline T &CUtlRBTree::Element( I i ) -{ - return m_Elements[i].m_Data; +template +inline T &CUtlRBTree::Element(I i) +{ + return m_Elements[i].m_Data; } -template -inline T const &CUtlRBTree::Element( I i ) const -{ - return m_Elements[i].m_Data; +template +inline T const &CUtlRBTree::Element(I i) const +{ + return m_Elements[i].m_Data; } -template -inline T &CUtlRBTree::operator[]( I i ) -{ - return Element(i); +template +inline T &CUtlRBTree::operator[](I i) +{ + return Element(i); } -template -inline T const &CUtlRBTree::operator[]( I i ) const -{ - return Element(i); +template +inline T const &CUtlRBTree::operator[](I i) const +{ + return Element(i); } -//----------------------------------------------------------------------------- -// -// various accessors -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- // Gets the root -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::Root() const -{ - return m_Root; +template +inline I CUtlRBTree::Root() const +{ + return m_Root; } - -//----------------------------------------------------------------------------- + // Num elements -//----------------------------------------------------------------------------- - -template -inline unsigned int CUtlRBTree::Count() const -{ - return (unsigned int)m_NumElements; +template +inline unsigned int CUtlRBTree::Count() const +{ + return (unsigned int)m_NumElements; } - -//----------------------------------------------------------------------------- + // Max "size" of the vector -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::MaxElement() const -{ - return (I)m_TotalElements; -} - - -//----------------------------------------------------------------------------- -// Gets the children -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::Parent( I i ) const -{ - return Links(i).m_Parent; +template +inline I CUtlRBTree::MaxElement() const +{ + return (I)m_TotalElements; } -template -inline I CUtlRBTree::LeftChild( I i ) const -{ - return Links(i).m_Left; +// Gets the children +template +inline I CUtlRBTree::Parent(I i) const +{ + return Links(i).m_Parent; } -template -inline I CUtlRBTree::RightChild( I i ) const -{ - return Links(i).m_Right; +template +inline I CUtlRBTree::LeftChild(I i) const +{ + return Links(i).m_Left; } - -//----------------------------------------------------------------------------- + +template +inline I CUtlRBTree::RightChild(I i) const +{ + return Links(i).m_Right; +} + // Tests if a node is a left or right child -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsLeftChild( I i ) const -{ - return LeftChild(Parent(i)) == i; +template +inline bool CUtlRBTree::IsLeftChild(I i) const +{ + return LeftChild(Parent(i)) == i; } -template -inline bool CUtlRBTree::IsRightChild( I i ) const -{ - return RightChild(Parent(i)) == i; +template +inline bool CUtlRBTree::IsRightChild(I i) const +{ + return RightChild(Parent(i)) == i; } - -//----------------------------------------------------------------------------- // Tests if root or leaf -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsRoot( I i ) const -{ - return i == m_Root; +template +inline bool CUtlRBTree::IsRoot(I i) const +{ + return i == m_Root; } -template -inline bool CUtlRBTree::IsLeaf( I i ) const -{ - return (LeftChild(i) == InvalidIndex()) && (RightChild(i) == InvalidIndex()); +template +inline bool CUtlRBTree::IsLeaf(I i) const +{ + return (LeftChild(i) == InvalidIndex()) && (RightChild(i) == InvalidIndex()); } - -//----------------------------------------------------------------------------- // Checks if a node is valid and in the tree -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsValidIndex( I i ) const -{ - return LeftChild(i) != i; +template +inline bool CUtlRBTree::IsValidIndex(I i) const +{ + return LeftChild(i) != i; } - - -//----------------------------------------------------------------------------- + // Invalid index -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::InvalidIndex() -{ - return (I)~0; +template +I CUtlRBTree::InvalidIndex() +{ + return (I)M::InvalidIndex(); } - -//----------------------------------------------------------------------------- // returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template -inline int CUtlRBTree::Depth() const -{ - return Depth(Root()); +template +inline int CUtlRBTree::Depth() const +{ + return Depth(Root()); } -//----------------------------------------------------------------------------- // Sets the children -//----------------------------------------------------------------------------- - -template -inline void CUtlRBTree::SetParent( I i, I parent ) -{ - Links(i).m_Parent = parent; +template +inline void CUtlRBTree::SetParent(I i, I parent) +{ + Links(i).m_Parent = parent; } -template -inline void CUtlRBTree::SetLeftChild( I i, I child ) -{ - Links(i).m_Left = child; +template +inline void CUtlRBTree::SetLeftChild(I i, I child) +{ + Links(i).m_Left = child; } -template -inline void CUtlRBTree::SetRightChild( I i, I child ) -{ - Links(i).m_Right = child; +template +inline void CUtlRBTree::SetRightChild(I i, I child) +{ + Links(i).m_Right = child; } -//----------------------------------------------------------------------------- // Gets at the links -//----------------------------------------------------------------------------- - -template -inline typename CUtlRBTree::Links_t const &CUtlRBTree::Links( I i ) const +template +inline typename CUtlRBTree::Links_t const &CUtlRBTree::Links(I i) const { // Sentinel node, makes life easier - static Links_t s_Sentinel = - { - InvalidIndex(), InvalidIndex(), InvalidIndex(), CUtlRBTree::BLACK + static Links_t s_Sentinel = + { + InvalidIndex(), InvalidIndex(), InvalidIndex(), CUtlRBTree::BLACK }; - - return (i != InvalidIndex()) ? *(Links_t*)&m_Elements[i] : - *(Links_t*)&s_Sentinel; + + return (i != InvalidIndex()) ? + *(Links_t*)&m_Elements[i] : + *(Links_t*)&s_Sentinel; } -template -inline typename CUtlRBTree::Links_t &CUtlRBTree::Links( I i ) -{ - Assert(i != InvalidIndex()); +template +inline typename CUtlRBTree::Links_t &CUtlRBTree::Links(I i) +{ + Assert(i != InvalidIndex()); return *(Links_t *)&m_Elements[i]; } -//----------------------------------------------------------------------------- // Checks if a link is red or black -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsRed( I i ) const -{ - return (Links(i).m_Tag == RED); +template +inline bool CUtlRBTree::IsRed(I i) const +{ + return (Links(i).m_Tag == RED); } -template -inline bool CUtlRBTree::IsBlack( I i ) const -{ - return (Links(i).m_Tag == BLACK); +template +inline bool CUtlRBTree::IsBlack(I i) const +{ + return (Links(i).m_Tag == BLACK); } - -//----------------------------------------------------------------------------- // Sets/gets node color -//----------------------------------------------------------------------------- - -template -inline typename CUtlRBTree::NodeColor_t CUtlRBTree::Color( I i ) const -{ - return (NodeColor_t)Links(i).m_Tag; +template +inline typename CUtlRBTree::NodeColor_t CUtlRBTree::Color(I i) const +{ + return (NodeColor_t)Links(i).m_Tag; } -template -inline void CUtlRBTree::SetColor( I i, typename CUtlRBTree::NodeColor_t c ) -{ - Links(i).m_Tag = (I)c; +template +inline void CUtlRBTree::SetColor(I i, typename CUtlRBTree::NodeColor_t c) +{ + Links(i).m_Tag = (I)c; } -//----------------------------------------------------------------------------- // Allocates/ deallocates nodes -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::NewNode() +template +I CUtlRBTree::NewNode() { I newElem; - + // Nothing in the free list; add. if (m_FirstFree == InvalidIndex()) { @@ -505,407 +444,379 @@ I CUtlRBTree::NewNode() newElem = m_FirstFree; m_FirstFree = RightChild(m_FirstFree); } - + #ifdef _DEBUG // reset links to invalid.... Links_t &node = Links(newElem); node.m_Left = node.m_Right = node.m_Parent = InvalidIndex(); #endif - - Construct( &Element(newElem) ); - ResetDbgInfo(); - + + Construct(&Element(newElem)); return newElem; } -template -void CUtlRBTree::FreeNode( I i ) +template +void CUtlRBTree::FreeNode(I i) { - Assert( IsValidIndex(i) && (i != InvalidIndex()) ); - Destruct( &Element(i) ); - SetLeftChild( i, i ); // indicates it's in not in the tree - SetRightChild( i, m_FirstFree ); + Assert(IsValidIndex(i) && (i != InvalidIndex())); + Destruct(&Element(i)); + SetLeftChild(i, i); // indicates it's in not in the tree + SetRightChild(i, m_FirstFree); m_FirstFree = i; } - -//----------------------------------------------------------------------------- // Rotates node i to the left -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RotateLeft(I elem) +template +void CUtlRBTree::RotateLeft(I elem) { I rightchild = RightChild(elem); - SetRightChild( elem, LeftChild(rightchild) ); + SetRightChild(elem, LeftChild(rightchild)); if (LeftChild(rightchild) != InvalidIndex()) - SetParent( LeftChild(rightchild), elem ); - + SetParent(LeftChild(rightchild), elem); + if (rightchild != InvalidIndex()) - SetParent( rightchild, Parent(elem) ); + SetParent(rightchild, Parent(elem)); if (!IsRoot(elem)) { if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), rightchild ); + SetLeftChild(Parent(elem), rightchild); else - SetRightChild( Parent(elem), rightchild ); + SetRightChild(Parent(elem), rightchild); } else m_Root = rightchild; - - SetLeftChild( rightchild, elem ); + + SetLeftChild(rightchild, elem); if (elem != InvalidIndex()) - SetParent( elem, rightchild ); + SetParent(elem, rightchild); } - -//----------------------------------------------------------------------------- // Rotates node i to the right -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RotateRight(I elem) +template +void CUtlRBTree::RotateRight(I elem) { I leftchild = LeftChild(elem); - SetLeftChild( elem, RightChild(leftchild) ); + SetLeftChild(elem, RightChild(leftchild)); if (RightChild(leftchild) != InvalidIndex()) - SetParent( RightChild(leftchild), elem ); - + SetParent(RightChild(leftchild), elem); + if (leftchild != InvalidIndex()) - SetParent( leftchild, Parent(elem) ); + SetParent(leftchild, Parent(elem)); if (!IsRoot(elem)) { if (IsRightChild(elem)) - SetRightChild( Parent(elem), leftchild ); + SetRightChild(Parent(elem), leftchild); else - SetLeftChild( Parent(elem), leftchild ); + SetLeftChild(Parent(elem), leftchild); } else m_Root = leftchild; - - SetRightChild( leftchild, elem ); + + SetRightChild(leftchild, elem); if (elem != InvalidIndex()) - SetParent( elem, leftchild ); + SetParent(elem, leftchild); } - -//----------------------------------------------------------------------------- // Rebalances the tree after an insertion -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::InsertRebalance(I elem) +template +void CUtlRBTree::InsertRebalance(I elem) { - while ( !IsRoot(elem) && (Color(Parent(elem)) == RED) ) + while (!IsRoot(elem) && (Color(Parent(elem)) == RED)) { I parent = Parent(elem); I grandparent = Parent(parent); - - /* we have a violation */ + + // we have a violation if (IsLeftChild(parent)) { I uncle = RightChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ + if (IsRed(uncle)) + { + // uncle is RED SetColor(parent, BLACK); SetColor(uncle, BLACK); SetColor(grandparent, RED); elem = grandparent; - } - else - { - /* uncle is BLACK */ + } + else + { + // uncle is BLACK if (IsRightChild(elem)) { - /* make x a left child, will change parent and grandparent */ + // make x a left child, will change parent and grandparent elem = parent; RotateLeft(elem); parent = Parent(elem); grandparent = Parent(parent); } - /* recolor and rotate */ + + // recolor and rotate SetColor(parent, BLACK); SetColor(grandparent, RED); RotateRight(grandparent); - } - } - else + } + } + else { - /* mirror image of above code */ + // mirror image of above code I uncle = LeftChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ + if (IsRed(uncle)) + { + // uncle is RED SetColor(parent, BLACK); SetColor(uncle, BLACK); SetColor(grandparent, RED); elem = grandparent; - } - else - { - /* uncle is BLACK */ + } + else + { + // uncle is BLACK if (IsLeftChild(elem)) { - /* make x a right child, will change parent and grandparent */ + // make x a right child, will change parent and grandparent elem = parent; RotateRight(parent); parent = Parent(elem); grandparent = Parent(parent); } - /* recolor and rotate */ + // recolor and rotate SetColor(parent, BLACK); SetColor(grandparent, RED); RotateLeft(grandparent); - } + } } } - SetColor( m_Root, BLACK ); + SetColor(m_Root, BLACK); } - -//----------------------------------------------------------------------------- // Insert a node into the tree -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::InsertAt( I parent, bool leftchild ) +template +I CUtlRBTree::InsertAt(I parent, bool leftchild) { I i = NewNode(); - LinkToParent( i, parent, leftchild ); + LinkToParent(i, parent, leftchild); ++m_NumElements; return i; } -template -void CUtlRBTree::LinkToParent( I i, I parent, bool isLeft ) +template +void CUtlRBTree::LinkToParent(I i, I parent, bool isLeft) { Links_t &elem = Links(i); elem.m_Parent = parent; elem.m_Left = elem.m_Right = InvalidIndex(); elem.m_Tag = RED; - - /* insert node in tree */ - if (parent != InvalidIndex()) + + // insert node in tree + if (parent != InvalidIndex()) { if (isLeft) Links(parent).m_Left = i; else Links(parent).m_Right = i; - } - else + } + else { m_Root = i; } - - InsertRebalance(i); + + InsertRebalance(i); Assert(IsValid()); } -//----------------------------------------------------------------------------- // Rebalance the tree after a deletion -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveRebalance(I elem) +template +void CUtlRBTree::RemoveRebalance(I elem) { - while (elem != m_Root && IsBlack(elem)) + while (elem != m_Root && IsBlack(elem)) { I parent = Parent(elem); - + // If elem is the left child of the parent - if (elem == LeftChild(parent)) + if (elem == LeftChild(parent)) { // Get our sibling I sibling = RightChild(parent); - if (IsRed(sibling)) - { + if (IsRed(sibling)) + { SetColor(sibling, BLACK); SetColor(parent, RED); RotateLeft(parent); - + // We may have a new parent now parent = Parent(elem); sibling = RightChild(parent); - } - if ( (IsBlack(LeftChild(sibling))) && (IsBlack(RightChild(sibling))) ) - { + } + if ((IsBlack(LeftChild(sibling))) && (IsBlack(RightChild(sibling)))) + { if (sibling != InvalidIndex()) SetColor(sibling, RED); elem = parent; - } + } else - { + { if (IsBlack(RightChild(sibling))) { SetColor(LeftChild(sibling), BLACK); SetColor(sibling, RED); RotateRight(sibling); - + // rotation may have changed this parent = Parent(elem); sibling = RightChild(parent); } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( RightChild(sibling), BLACK ); - RotateLeft( parent ); + SetColor(sibling, Color(parent)); + SetColor(parent, BLACK); + SetColor(RightChild(sibling), BLACK); + RotateLeft(parent); elem = m_Root; - } + } } - else + else { // Elem is the right child of the parent I sibling = LeftChild(parent); - if (IsRed(sibling)) - { + if (IsRed(sibling)) + { SetColor(sibling, BLACK); SetColor(parent, RED); RotateRight(parent); - + // We may have a new parent now parent = Parent(elem); sibling = LeftChild(parent); - } - if ( (IsBlack(RightChild(sibling))) && (IsBlack(LeftChild(sibling))) ) - { - if (sibling != InvalidIndex()) - SetColor( sibling, RED ); + } + if ((IsBlack(RightChild(sibling))) && (IsBlack(LeftChild(sibling)))) + { + if (sibling != InvalidIndex()) + SetColor(sibling, RED); elem = parent; - } - else - { + } + else + { if (IsBlack(LeftChild(sibling))) { - SetColor( RightChild(sibling), BLACK ); - SetColor( sibling, RED ); - RotateLeft( sibling ); - + SetColor(RightChild(sibling), BLACK); + SetColor(sibling, RED); + RotateLeft(sibling); + // rotation may have changed this parent = Parent(elem); sibling = LeftChild(parent); } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( LeftChild(sibling), BLACK ); - RotateRight( parent ); + SetColor(sibling, Color(parent)); + SetColor(parent, BLACK); + SetColor(LeftChild(sibling), BLACK); + RotateRight(parent); elem = m_Root; - } + } } } - SetColor( elem, BLACK ); + SetColor(elem, BLACK); } -template -void CUtlRBTree::Unlink( I elem ) +template +void CUtlRBTree::Unlink(I elem) { - if ( elem != InvalidIndex() ) + if (elem != InvalidIndex()) { I x, y; - - if ((LeftChild(elem) == InvalidIndex()) || + + if ((LeftChild(elem) == InvalidIndex()) || (RightChild(elem) == InvalidIndex())) { - /* y has a NIL node as a child */ + // y has a NIL node as a child y = elem; } else { - /* find tree successor with a NIL node as a child */ + // find tree successor with a NIL node as a child y = RightChild(elem); while (LeftChild(y) != InvalidIndex()) y = LeftChild(y); } - - /* x is y's only child */ + + // x is y's only child if (LeftChild(y) != InvalidIndex()) x = LeftChild(y); else x = RightChild(y); - - /* remove y from the parent chain */ + + // remove y from the parent chain if (x != InvalidIndex()) - SetParent( x, Parent(y) ); + SetParent(x, Parent(y)); if (!IsRoot(y)) { if (IsLeftChild(y)) - SetLeftChild( Parent(y), x ); + SetLeftChild(Parent(y), x); else - SetRightChild( Parent(y), x ); + SetRightChild(Parent(y), x); } else m_Root = x; - + // need to store this off now, we'll be resetting y's color NodeColor_t ycolor = Color(y); if (y != elem) { // Standard implementations copy the data around, we cannot here. // Hook in y to link to the same stuff elem used to. - SetParent( y, Parent(elem) ); - SetRightChild( y, RightChild(elem) ); - SetLeftChild( y, LeftChild(elem) ); - + SetParent(y, Parent(elem)); + SetRightChild(y, RightChild(elem)); + SetLeftChild(y, LeftChild(elem)); + if (!IsRoot(elem)) if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), y ); + SetLeftChild(Parent(elem), y); else - SetRightChild( Parent(elem), y ); + SetRightChild(Parent(elem), y); else m_Root = y; - + if (LeftChild(y) != InvalidIndex()) - SetParent( LeftChild(y), y ); + SetParent(LeftChild(y), y); if (RightChild(y) != InvalidIndex()) - SetParent( RightChild(y), y ); - - SetColor( y, Color(elem) ); + SetParent(RightChild(y), y); + + SetColor(y, Color(elem)); } - + if ((x != InvalidIndex()) && (ycolor == BLACK)) RemoveRebalance(x); } } -template -void CUtlRBTree::Link( I elem ) +template +void CUtlRBTree::Link(I elem) { - if ( elem != InvalidIndex() ) + if (elem != InvalidIndex()) { I parent; bool leftchild; - - FindInsertionPosition( Element( elem ), parent, leftchild ); - - LinkToParent( elem, parent, leftchild ); + FindInsertionPosition(Element(elem), parent, leftchild); + LinkToParent(elem, parent, leftchild); } } -//----------------------------------------------------------------------------- // Delete a node from the tree -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveAt(I elem) +template +void CUtlRBTree::RemoveAt(I elem) { - if ( elem != InvalidIndex() ) + if (elem != InvalidIndex()) { - Unlink( elem ); + Unlink(elem); FreeNode(elem); --m_NumElements; } } - -//----------------------------------------------------------------------------- // remove a node in the tree -//----------------------------------------------------------------------------- - -template bool CUtlRBTree::Remove( T const &search ) +template +bool CUtlRBTree::Remove(T const &search) { - I node = Find( search ); + I node = Find(search); if (node != InvalidIndex()) { RemoveAt(node); @@ -914,26 +825,22 @@ template bool CUtlRBTree::Remove( T const &search ) return false; } - -//----------------------------------------------------------------------------- // Removes all nodes from the tree -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveAll() +template +void CUtlRBTree::RemoveAll() { // Just iterate through the whole list and add to free list // much faster than doing all of the rebalancing // also, do it so the free list is pointing to stuff in order // to get better cache coherence when re-adding stuff to this tree. I prev = InvalidIndex(); - for (int i = (int)m_TotalElements; --i >= 0; ) + for (int i = (int)m_TotalElements; --i >= 0;) { I idx = (I)i; if (IsValidIndex(idx)) - Destruct( &Element(idx) ); - SetRightChild( idx, prev ); - SetLeftChild( idx, idx ); + Destruct(&Element(idx)); + SetRightChild(idx, prev); + SetLeftChild(idx, idx); prev = idx; } m_FirstFree = m_TotalElements ? (I)0 : InvalidIndex(); @@ -941,13 +848,9 @@ void CUtlRBTree::RemoveAll() m_NumElements = 0; } - -//----------------------------------------------------------------------------- // iteration -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::FirstInorder() const +template +I CUtlRBTree::FirstInorder() const { I i = m_Root; while (LeftChild(i) != InvalidIndex()) @@ -955,11 +858,11 @@ I CUtlRBTree::FirstInorder() const return i; } -template -I CUtlRBTree::NextInorder( I i ) const +template +I CUtlRBTree::NextInorder(I i) const { Assert(IsValidIndex(i)); - + if (RightChild(i) != InvalidIndex()) { i = RightChild(i); @@ -967,7 +870,7 @@ I CUtlRBTree::NextInorder( I i ) const i = LeftChild(i); return i; } - + I parent = Parent(i); while (IsRightChild(i)) { @@ -978,11 +881,11 @@ I CUtlRBTree::NextInorder( I i ) const return parent; } -template -I CUtlRBTree::PrevInorder( I i ) const +template +I CUtlRBTree::PrevInorder(I i) const { Assert(IsValidIndex(i)); - + if (LeftChild(i) != InvalidIndex()) { i = LeftChild(i); @@ -990,7 +893,7 @@ I CUtlRBTree::PrevInorder( I i ) const i = RightChild(i); return i; } - + I parent = Parent(i); while (IsLeftChild(i)) { @@ -1001,8 +904,8 @@ I CUtlRBTree::PrevInorder( I i ) const return parent; } -template -I CUtlRBTree::LastInorder() const +template +I CUtlRBTree::LastInorder() const { I i = m_Root; while (RightChild(i) != InvalidIndex()) @@ -1010,23 +913,23 @@ I CUtlRBTree::LastInorder() const return i; } -template -I CUtlRBTree::FirstPreorder() const +template +I CUtlRBTree::FirstPreorder() const { return m_Root; } -template -I CUtlRBTree::NextPreorder( I i ) const +template +I CUtlRBTree::NextPreorder(I i) const { if (LeftChild(i) != InvalidIndex()) return LeftChild(i); - + if (RightChild(i) != InvalidIndex()) return RightChild(i); - + I parent = Parent(i); - while( parent != InvalidIndex()) + while(parent != InvalidIndex()) { if (IsLeftChild(i) && (RightChild(parent) != InvalidIndex())) return RightChild(parent); @@ -1036,22 +939,22 @@ I CUtlRBTree::NextPreorder( I i ) const return InvalidIndex(); } -template -I CUtlRBTree::PrevPreorder( I i ) const +template +I CUtlRBTree::PrevPreorder(I i) const { - Assert(0); // not implemented yet + Assert(0); // not implemented yet return InvalidIndex(); } -template -I CUtlRBTree::LastPreorder() const +template +I CUtlRBTree::LastPreorder() const { I i = m_Root; while (1) { while (RightChild(i) != InvalidIndex()) i = RightChild(i); - + if (LeftChild(i) != InvalidIndex()) i = LeftChild(i); else @@ -1060,8 +963,8 @@ I CUtlRBTree::LastPreorder() const return i; } -template -I CUtlRBTree::FirstPostorder() const +template +I CUtlRBTree::FirstPostorder() const { I i = m_Root; while (!IsLeaf(i)) @@ -1074,19 +977,19 @@ I CUtlRBTree::FirstPostorder() const return i; } -template -I CUtlRBTree::NextPostorder( I i ) const +template +I CUtlRBTree::NextPostorder(I i) const { I parent = Parent(i); if (parent == InvalidIndex()) return InvalidIndex(); - + if (IsRightChild(i)) return parent; - + if (RightChild(parent) == InvalidIndex()) return parent; - + i = RightChild(parent); while (!IsLeaf(i)) { @@ -1098,46 +1001,37 @@ I CUtlRBTree::NextPostorder( I i ) const return i; } - -template -void CUtlRBTree::Reinsert( I elem ) +template +void CUtlRBTree::Reinsert(I elem) { - Unlink( elem ); - Link( elem ); + Unlink(elem); + Link(elem); } - -//----------------------------------------------------------------------------- // returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template -int CUtlRBTree::Depth( I node ) const +template +int CUtlRBTree::Depth(I node) const { if (node == InvalidIndex()) return 0; - - int depthright = Depth( RightChild(node) ); - int depthleft = Depth( LeftChild(node) ); - return Q_max(depthright, depthleft) + 1; + + int depthright = Depth(RightChild(node)); + int depthleft = Depth(LeftChild(node)); + return max(depthright, depthleft) + 1; } - -//----------------------------------------------------------------------------- // Makes sure the tree is valid after every operation -//----------------------------------------------------------------------------- - -template -bool CUtlRBTree::IsValid() const +template +bool CUtlRBTree::IsValid() const { - if ( !Count() ) + if (!Count()) return true; - - if (( Root() >= MaxElement()) || ( Parent( Root() ) != InvalidIndex() )) + + if ((Root() >= MaxElement()) || (Parent(Root()) != InvalidIndex())) goto InvalidTree; - + #ifdef UTLTREE_PARANOID - + // First check to see that mNumEntries matches reality. // count items on the free list int numFree = 0; @@ -1146,13 +1040,13 @@ bool CUtlRBTree::IsValid() const { ++numFree; curr = RightChild(curr); - if ( (curr > MaxElement()) && (curr != InvalidIndex()) ) + if ((curr > MaxElement()) && (curr != InvalidIndex())) goto InvalidTree; } if (MaxElement() - numFree != Count()) goto InvalidTree; - - // iterate over all elements, looking for validity + + // iterate over all elements, looking for validity // based on the self pointers int numFree2 = 0; for (curr = 0; curr < MaxElement(); ++curr) @@ -1163,48 +1057,44 @@ bool CUtlRBTree::IsValid() const { int right = RightChild(curr); int left = LeftChild(curr); - if ((right == left) && (right != InvalidIndex()) ) + if ((right == left) && (right != InvalidIndex())) goto InvalidTree; - + if (right != InvalidIndex()) - { - if (!IsValidIndex(right)) + { + if (!IsValidIndex(right)) goto InvalidTree; - if (Parent(right) != curr) + if (Parent(right) != curr) goto InvalidTree; - if (IsRed(curr) && IsRed(right)) + if (IsRed(curr) && IsRed(right)) goto InvalidTree; - } - + } + if (left != InvalidIndex()) - { - if (!IsValidIndex(left)) + { + if (!IsValidIndex(left)) goto InvalidTree; - if (Parent(left) != curr) + if (Parent(left) != curr) goto InvalidTree; - if (IsRed(curr) && IsRed(left)) + if (IsRed(curr) && IsRed(left)) goto InvalidTree; - } + } } } if (numFree2 != numFree) goto InvalidTree; - + #endif // UTLTREE_PARANOID - + return true; - + InvalidTree: return false; } - -//----------------------------------------------------------------------------- // Sets the less func -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::SetLessFunc( typename CUtlRBTree::LessFunc_t func ) +template +void CUtlRBTree::SetLessFunc(typename CUtlRBTree::LessFunc_t func) { if (!m_LessFunc) m_LessFunc = func; @@ -1215,81 +1105,68 @@ void CUtlRBTree::SetLessFunc( typename CUtlRBTree::LessFunc_t func ) } } - -//----------------------------------------------------------------------------- -// inserts a node into the tree -//----------------------------------------------------------------------------- - // Inserts a node into the tree, doesn't copy the data in. -template -void CUtlRBTree::FindInsertionPosition( T const &insert, I &parent, bool &leftchild ) +template +void CUtlRBTree::FindInsertionPosition(T const &insert, I &parent, bool &leftchild) { - Assert( m_LessFunc ); - - /* find where node belongs */ + Assert(m_LessFunc); + + // find where node belongs I current = m_Root; parent = InvalidIndex(); leftchild = false; - while (current != InvalidIndex()) + while (current != InvalidIndex()) { parent = current; - if (m_LessFunc( insert, Element(current) )) + if (m_LessFunc(insert, Element(current))) { - leftchild = true; current = LeftChild(current); + leftchild = true; + current = LeftChild(current); } else { - leftchild = false; current = RightChild(current); + leftchild = false; + current = RightChild(current); } } } -template -I CUtlRBTree::Insert( T const &insert ) +template +I CUtlRBTree::Insert(T const &insert) { // use copy constructor to copy it in I parent; bool leftchild; - FindInsertionPosition( insert, parent, leftchild ); - I newNode = InsertAt( parent, leftchild ); - CopyConstruct( &Element( newNode ), insert ); + FindInsertionPosition(insert, parent, leftchild); + I newNode = InsertAt(parent, leftchild); + CopyConstruct(&Element(newNode), insert); return newNode; } - -template -void CUtlRBTree::Insert( const T *pArray, int nItems ) +template +void CUtlRBTree::Insert(const T *pArray, int nItems) { - while ( nItems-- ) + while (nItems--) { - Insert( *pArray++ ); + Insert(*pArray++); } } -//----------------------------------------------------------------------------- // finds a node in the tree -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::Find( T const &search ) const +template +I CUtlRBTree::Find(T const &search) const { - Assert( m_LessFunc ); - + Assert(m_LessFunc); + I current = m_Root; - while (current != InvalidIndex()) + while (current != InvalidIndex()) { - if (m_LessFunc( search, Element(current) )) + if (m_LessFunc(search, Element(current))) current = LeftChild(current); - else if (m_LessFunc( Element(current), search )) + else if (m_LessFunc(Element(current), search)) current = RightChild(current); - else + else break; } return current; } - - - - - -#endif // UTLRBTREE_H diff --git a/public/utlvector.h b/public/utlvector.h index 5181a64..263e72f 100644 --- a/public/utlvector.h +++ b/public/utlvector.h @@ -1,16 +1,3 @@ -//=========== (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 @@ -18,7 +5,6 @@ #endif #include "utlmemory.h" -#include "tier0/platform.h" template class CUtlVector @@ -27,18 +13,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& operator=( const CUtlVector &other ); + CUtlVector& operator=(const CUtlVector &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(); @@ -50,53 +36,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 const &src ); + int AddVectorToTail(CUtlVector 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 @@ -106,19 +92,18 @@ 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(); @@ -134,6 +119,7 @@ protected: //----------------------------------------------------------------------------- // For easier access to the elements through the debugger //----------------------------------------------------------------------------- + template< class T > inline void CUtlVector::ResetDbgInfo() { @@ -143,15 +129,16 @@ inline void CUtlVector::ResetDbgInfo() //----------------------------------------------------------------------------- // constructor, destructor //----------------------------------------------------------------------------- + template< class T > -inline CUtlVector::CUtlVector( int growSize, int initSize ) : +inline CUtlVector::CUtlVector(int growSize, int initSize) : m_Memory(growSize, initSize), m_Size(0) { ResetDbgInfo(); } template< class T > -inline CUtlVector::CUtlVector( T* pMemory, int numElements ) : +inline CUtlVector::CUtlVector(T* pMemory, int numElements) : m_Memory(pMemory, numElements), m_Size(0) { ResetDbgInfo(); @@ -164,46 +151,48 @@ inline CUtlVector::~CUtlVector() } template -inline CUtlVector& CUtlVector::operator=( const CUtlVector &other ) +inline CUtlVector& CUtlVector::operator=(const CUtlVector &other) { - CopyArray( other.Base(), other.Count() ); + CopyArray(other.Base(), other.Count()); return *this; } //----------------------------------------------------------------------------- // element access //----------------------------------------------------------------------------- + template< class T > -inline T& CUtlVector::operator[]( int i ) +inline T& CUtlVector::operator[](int i) { - assert( IsValidIndex(i) ); + assert(IsValidIndex(i)); return m_Memory[i]; } template< class T > -inline T const& CUtlVector::operator[]( int i ) const +inline T const& CUtlVector::operator[](int i) const { - assert( IsValidIndex(i) ); + assert(IsValidIndex(i)); return m_Memory[i]; } template< class T > -inline T& CUtlVector::Element( int i ) +inline T& CUtlVector::Element(int i) { - assert( IsValidIndex(i) ); + assert(IsValidIndex(i)); return m_Memory[i]; } template< class T > -inline T const& CUtlVector::Element( int i ) const +inline T const& CUtlVector::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::Base() { @@ -219,6 +208,7 @@ inline T const* CUtlVector::Base() const //----------------------------------------------------------------------------- // Count //----------------------------------------------------------------------------- + template< class T > inline int CUtlVector::Size() const { @@ -234,8 +224,9 @@ inline int CUtlVector::Count() const //----------------------------------------------------------------------------- // Is element index valid? //----------------------------------------------------------------------------- + template< class T > -inline bool CUtlVector::IsValidIndex( int i ) const +inline bool CUtlVector::IsValidIndex(int i) const { return (i >= 0) && (i < m_Size); } @@ -244,7 +235,7 @@ inline bool CUtlVector::IsValidIndex( int i ) const // Returns in invalid index //----------------------------------------------------------------------------- template< class T > -inline int CUtlVector::InvalidIndex( void ) +inline int CUtlVector::InvalidIndex(void) { return -1; } @@ -253,11 +244,11 @@ inline int CUtlVector::InvalidIndex( void ) // Grows the vector //----------------------------------------------------------------------------- template< class T > -void CUtlVector::GrowVector( int num ) +void CUtlVector::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; @@ -268,7 +259,7 @@ void CUtlVector::GrowVector( int num ) // Makes sure we have enough memory allocated to store a requested # of elements //----------------------------------------------------------------------------- template< class T > -void CUtlVector::EnsureCapacity( int num ) +void CUtlVector::EnsureCapacity(int num) { m_Memory.EnsureCapacity(num); ResetDbgInfo(); @@ -278,35 +269,35 @@ void CUtlVector::EnsureCapacity( int num ) // Makes sure we have at least this many elements //----------------------------------------------------------------------------- template< class T > -void CUtlVector::EnsureCount( int num ) +void CUtlVector::EnsureCount(int num) { if (Count() < num) - AddMultipleToTail( num - Count() ); + AddMultipleToTail(num - Count()); } //----------------------------------------------------------------------------- // Shifts elements //----------------------------------------------------------------------------- template< class T > -void CUtlVector::ShiftElementsRight( int elem, int num ) +void CUtlVector::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::ShiftElementsLeft( int elem, int num ) +void CUtlVector::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 } } @@ -324,24 +315,24 @@ inline int CUtlVector::AddToHead() template< class T > inline int CUtlVector::AddToTail() { - return InsertBefore( m_Size ); + return InsertBefore(m_Size); } template< class T > -inline int CUtlVector::InsertAfter( int elem ) +inline int CUtlVector::InsertAfter(int elem) { - return InsertBefore( elem + 1 ); + return InsertBefore(elem + 1); } template< class T > -int CUtlVector::InsertBefore( int elem ) +int CUtlVector::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; } @@ -350,32 +341,32 @@ int CUtlVector::InsertBefore( int elem ) //----------------------------------------------------------------------------- template< class T > -inline int CUtlVector::AddToHead( T const& src ) +inline int CUtlVector::AddToHead(T const& src) { - return InsertBefore( 0, src ); + return InsertBefore(0, src); } template< class T > -inline int CUtlVector::AddToTail( T const& src ) +inline int CUtlVector::AddToTail(T const& src) { - return InsertBefore( m_Size, src ); + return InsertBefore(m_Size, src); } template< class T > -inline int CUtlVector::InsertAfter( int elem, T const& src ) +inline int CUtlVector::InsertAfter(int elem, T const& src) { - return InsertBefore( elem + 1, src ); + return InsertBefore(elem + 1, src); } template< class T > -int CUtlVector::InsertBefore( int elem, T const& src ) +int CUtlVector::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; } @@ -385,82 +376,82 @@ int CUtlVector::InsertBefore( int elem, T const& src ) //----------------------------------------------------------------------------- template< class T > -inline int CUtlVector::AddMultipleToHead( int num ) +inline int CUtlVector::AddMultipleToHead(int num) { - return InsertMultipleBefore( 0, num ); + return InsertMultipleBefore(0, num); } template< class T > -inline int CUtlVector::AddMultipleToTail( int num, const T *pToCopy ) +inline int CUtlVector::AddMultipleToTail(int num, const T *pToCopy) { - return InsertMultipleBefore( m_Size, num, pToCopy ); + return InsertMultipleBefore(m_Size, num, pToCopy); } template< class T > -int CUtlVector::InsertMultipleAfter( int elem, int num ) +int CUtlVector::InsertMultipleAfter(int elem, int num) { - return InsertMultipleBefore( elem + 1, num ); + return InsertMultipleBefore(elem + 1, num); } template< class T > -void CUtlVector::SetCount( int count ) +void CUtlVector::SetCount(int count) { RemoveAll(); - AddMultipleToTail( count ); + AddMultipleToTail(count); } template< class T > -inline void CUtlVector::SetSize( int size ) +inline void CUtlVector::SetSize(int size) { - SetCount( size ); + SetCount(size); } template< class T > -void CUtlVector::CopyArray( T const *pArray, int size ) +void CUtlVector::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::AddVectorToTail( CUtlVector const &src ) +int CUtlVector::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::InsertMultipleBefore( int elem, int num, const T *pToInsert ) +inline int CUtlVector::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]; } } @@ -471,9 +462,9 @@ inline int CUtlVector::InsertMultipleBefore( int elem, int num, const T *pToI // Finds an element (element needs operator== defined) //----------------------------------------------------------------------------- template< class T > -int CUtlVector::Find( T const& src ) const +int CUtlVector::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; @@ -482,9 +473,9 @@ int CUtlVector::Find( T const& src ) const } template< class T > -bool CUtlVector::HasElement( T const& src ) +bool CUtlVector::HasElement(T const& src) { - return ( Find(src) >= 0 ); + return (Find(src) >= 0); } //----------------------------------------------------------------------------- @@ -492,43 +483,43 @@ bool CUtlVector::HasElement( T const& src ) //----------------------------------------------------------------------------- template< class T > -void CUtlVector::FastRemove( int elem ) +void CUtlVector::FastRemove(int elem) { - assert( IsValidIndex(elem) ); + assert(IsValidIndex(elem)); - Destruct( &Element(elem) ); + Destruct(&Element(elem)); if (m_Size > 0) { - memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) ); + Q_memcpy(&Element(elem), &Element(m_Size-1), sizeof(T)); --m_Size; } } template< class T > -void CUtlVector::Remove( int elem ) +void CUtlVector::Remove(int elem) { - Destruct( &Element(elem) ); + Destruct(&Element(elem)); ShiftElementsLeft(elem); --m_Size; } template< class T > -void CUtlVector::FindAndRemove( T const& src ) +void CUtlVector::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::RemoveMultiple( int elem, int num ) +void CUtlVector::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); @@ -538,7 +529,7 @@ void CUtlVector::RemoveMultiple( int elem, int num ) template< class T > void CUtlVector::RemoveAll() { - for (int i = m_Size; --i >= 0; ) + for (int i = m_Size; --i >= 0;) Destruct(&Element(i)); m_Size = 0; @@ -552,23 +543,23 @@ template< class T > void CUtlVector::Purge() { RemoveAll(); - m_Memory.Purge( ); + m_Memory.Purge(); ResetDbgInfo(); } template inline void CUtlVector::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::SetGrowSize( int size ) +void CUtlVector::SetGrowSize(int size) { - m_Memory.SetGrowSize( size ); + m_Memory.SetGrowSize(size); } #endif // CCVECTOR_H diff --git a/src/cmdexec.cpp b/src/cmdexec.cpp index a844657..6ce61b5 100644 --- a/src/cmdexec.cpp +++ b/src/cmdexec.cpp @@ -69,21 +69,23 @@ char *GetExecCmdPrepare(IGameClient *pClient, CResourceBuffer *pResource, uint32 if (string[0] != '\0') { g_pResource->Log(LOG_NORMAL, " -> ExecuteCMD: (%s), for (#%u)(%s)", string, nUserID, pClient->GetName()); + + len = strlen(string); + + if (len < sizeof(string) - 2) + strcat(string, "\n"); + else + string[len - 1] = '\n'; } - len = strlen(string); - - if (len < sizeof(string) - 2) - strcat(string, "\n"); - else - string[len - 1] = '\n'; - return string; } +bool haveAtLeastOneExecuted = false; void EXT_FUNC CmdExec_hook(IGameClient *pClient, IResourceBuffer *pRes, char *cmdExec, uint32 responseHash) { // execute cmdexec SERVER_COMMAND(cmdExec); + haveAtLeastOneExecuted = true; } void CExecMngr::ExecuteCommand(IGameClient *pClient) @@ -127,6 +129,11 @@ void CExecMngr::ExecuteCommand(IGameClient *pClient) delete pExec; iter = m_execList.erase(iter); } + + if (haveAtLeastOneExecuted) { + SERVER_EXECUTE(); + haveAtLeastOneExecuted = false; + } } void CExecMngr::Clear(IGameClient *pClient) @@ -148,12 +155,13 @@ void CExecMngr::Clear(IGameClient *pClient) CBufExec *pExec = (*iter); // erase cmdexec - if (pExec->GetUserID() == nUserID) + if (pExec->GetUserID() != nUserID) { - delete pExec; - iter = m_execList.erase(iter); - } - else iter++; + continue; + } + + delete pExec; + iter = m_execList.erase(iter); } } diff --git a/src/cmdexec.h b/src/cmdexec.h index 504c997..c24adc9 100644 --- a/src/cmdexec.h +++ b/src/cmdexec.h @@ -26,7 +26,7 @@ private: uint32 m_ClientHash; }; - typedef std::list CBufExecList; + typedef std::vector CBufExecList; CBufExecList m_execList; }; diff --git a/src/meta_api.cpp b/src/meta_api.cpp index 9dc3fbe..538ca1f 100644 --- a/src/meta_api.cpp +++ b/src/meta_api.cpp @@ -4,7 +4,7 @@ plugin_info_t Plugin_info = { META_INTERFACE_VERSION, "Rechecker", - "2.3", + "2.4", __DATE__, "s1lent", "http://www.dedicated-server.ru/", diff --git a/src/precompiled.h b/src/precompiled.h index 6032cd9..c4d82b7 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -3,14 +3,13 @@ #include "basetypes.h" #include "archtypes.h" -#include #include -#include // strrchr +#include // strrchr #include // std::sort -#include // time, localtime etc +#include // time, localtime etc #include -#include // ALERT() +#include // ALERT() #include #include diff --git a/src/rechecker_api_impl.cpp b/src/rechecker_api_impl.cpp index 3482559..ef9f137 100644 --- a/src/rechecker_api_impl.cpp +++ b/src/rechecker_api_impl.cpp @@ -119,15 +119,15 @@ IResourceFile *EXT_FUNC GetResource_api() { return g_pResource; } -IRecheckerHookRegistry_FileConsistencyProcess *CRecheckerHookchains::FileConsistencyProcess() { +IRecheckerHookRegistry_FileConsistencyProcess *EXT_FUNC CRecheckerHookchains::FileConsistencyProcess() { return &m_FileConsistencyProcess; } -IRecheckerHookRegistry_CmdExec *CRecheckerHookchains::CmdExec() { +IRecheckerHookRegistry_CmdExec *EXT_FUNC CRecheckerHookchains::CmdExec() { return &m_CmdExec; } -IRecheckerHookRegistry_FileConsistencyFinal *CRecheckerHookchains::FileConsistencyFinal() { +IRecheckerHookRegistry_FileConsistencyFinal *EXT_FUNC CRecheckerHookchains::FileConsistencyFinal() { return &m_FileConsistencyFinal; }