Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
80aff5e
Add `CUtlStringMap::FindAndRemove` method
Wend4r Feb 23, 2025
292e03c
Removed Plat_FatalErrorFunc from deadlock
boeing666 Mar 2, 2025
d8c5f54
`CUtlStringMap`: remove hash element of symbol table
Wend4r Mar 4, 2025
caa5928
Update `CUtlSymbolTable` & hash staff
Wend4r Mar 6, 2025
bcb8069
Add `CCommandBuffer::SplitCommands` method
Wend4r Mar 9, 2025
c4e277d
Locate `CKeyValues3Table::m_bHasInvalidMemberNames` field
Wend4r Mar 9, 2025
a4982c5
Add `KeyValues3::RenameMember` method
Wend4r Mar 9, 2025
8441bc8
Add `KeyValues3::OverlayKeysFrom` method
Wend4r Mar 9, 2025
c806485
Resolve `UtlSymLargeId_t` differences
Wend4r Mar 11, 2025
c6ac506
Resolve `UtlSymLargeId_t` differences (2)
Wend4r Mar 11, 2025
998f037
Update `CUtlStringMap` constructor
Wend4r Mar 15, 2025
49b6339
Update `CUtlStringMap` access operators
Wend4r Mar 15, 2025
dfc32eb
Uncomment `CUtlStringMap::Count`'s assert
Wend4r Mar 15, 2025
ae85a4e
Remove `CUtlStringMap::First`'s method
Wend4r Mar 15, 2025
6c97622
`CBufferStringN`: replace `uintp` with `size_t`
Wend4r Mar 15, 2025
2b2c447
Update `FOR_EACH_KV3_ARRAY`(`_BACK`) & `FOR_EACH_KV3_TABLE` macros
Wend4r Mar 15, 2025
1c5f015
Add `CKV3MemberHash` definition
Wend4r Mar 15, 2025
3a6ff85
Remove `CUtlStringTokenHashMethod` class
Wend4r Mar 15, 2025
bd0c6b3
Update `CUtlStringToken`'s constructors
Wend4r Mar 15, 2025
892434b
Remove `CUtlSymbol` interate opertators
Wend4r Mar 15, 2025
44e3ddf
Update `UtlSymId_t` operator method
Wend4r Mar 15, 2025
eaf586e
Update `CUtlSymbolTableLargeBaseTreeEntry_t` structure
Wend4r Mar 15, 2025
f6ca035
`CUtlSymbolTableLargeBaseTreeEntry_t`: Rename `Hash` method to `HashV…
Wend4r Mar 15, 2025
37a2d4b
Rename `CUtlSymbol::Hash` to `CUtlSymbol::MakeHash`
Wend4r Mar 15, 2025
5f9f05b
Format kv3 source & make more readable cluster things
Wend4r Mar 15, 2025
cfcd835
Correct kv3(array/table) getting ones
Wend4r Mar 15, 2025
c1ee083
HL2SDK: resolve include conflicts & fix errors
Wend4r Mar 15, 2025
145f2f9
HL2SDK: fix `FOR_EACH_KV3` macro
Wend4r Mar 15, 2025
111a6bf
Fix kv3table & cluster issues
Wend4r Mar 15, 2025
936f277
Fix `KeyValues3::GetCluster` method
Wend4r Mar 15, 2025
5e3b264
Merge branch 'cs2' into hl2sdk-cs2
Wend4r Apr 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion interfaces/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

/* This is totally reverse-engineered code and may be wrong */

#include "interfaces/interfaces.h"
#include "tier0/dbg.h"
#include "interfaces/interfaces.h"

IApplication *g_pApplication;
ICvar *cvar, *g_pCVar;
Expand Down
2 changes: 1 addition & 1 deletion public/entity2/entitykeyvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ inline EntityKeyId_t CEntityKeyValues::GetEntityKeyId( const CEntityKeyValues::I
if ( it.index >= it.keys->GetMemberCount() )
return EntityKeyId_t();

return it.keys->GetMemberNameEx( it.index );
return it.keys->GetKV3MemberName( it.index );
}

inline const char* CEntityKeyValues::GetAttributeName( const CEntityKeyValues::Iterator_t &it ) const
Expand Down
22 changes: 3 additions & 19 deletions public/tier0/dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ PLATFORM_INTERFACE void Msg( const tchar* pMsg, ... );
PLATFORM_INTERFACE void Warning( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void Warning_SpewCallStack( int iMaxCallStackLength, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );

#define Plat_FatalError( ... ) do { Log_Error( LOG_GENERAL, ##__VA_ARGS__ ); Plat_ExitProcess( EXIT_FAILURE ); } while( 0 )
#define Plat_FatalErrorFunc

// This is gone in Source2. Provide helper to roughly mimic Source1 behavior
void Error( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
inline void Error( const tchar* pMsg, ... )
Expand Down Expand Up @@ -312,25 +315,6 @@ PLATFORM_INTERFACE void COM_TimestampedLog( char const *fmt, ... ) FMTFUNCTION(

#endif /* _DEBUG */

//-----------------------------------------------------------------------------
// Macro to assist in asserting constant invariants during compilation

#define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )

#ifdef _DEBUG
template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
{
Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
return static_cast<DEST_POINTER_TYPE>(pSource);
}
#else
#define assert_cast static_cast
#endif

//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:

Expand Down
13 changes: 11 additions & 2 deletions public/tier0/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ class CBufferString;
// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )

#ifdef _DEBUG
template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
{
Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
return static_cast<DEST_POINTER_TYPE>(pSource);
}
#else
#define assert_cast static_cast
#endif

// feature enables
#define NEW_SOFTWARE_LIGHTING
#if !defined( _X360 )
Expand Down Expand Up @@ -1117,8 +1128,6 @@ PLATFORM_INTERFACE void Plat_ExitProcess( int nCode );

PLATFORM_INTERFACE bool Plat_ShouldCollectMiniDumpsForFatalErrors();

PLATFORM_INTERFACE void Plat_FatalErrorFunc( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );

// b/w compatibility
#define Sys_FloatTime Plat_FloatTime

Expand Down
4 changes: 4 additions & 0 deletions public/tier1/CommandBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class CCommandBuffer
// Indicates how long to delay when encoutering a 'wait' command
void SetWaitDelayTime( int nTickDelay );

// Compartmentalizes cfg-like commands.
// nLength can be -1
DLL_CLASS_IMPORT void SplitCommands( const char *pText, int nLength, CUtlVector< CUtlString > &outString );

// Returns a handle to the next command to process
// (useful when inserting commands into the buffer during processing
// of commands to force immediate execution of those commands,
Expand Down
111 changes: 101 additions & 10 deletions public/tier1/UtlStringMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,31 @@

#ifndef UTLSTRINGMAP_H
#define UTLSTRINGMAP_H

#ifdef _WIN32
#pragma once
#endif

#include "utlsymbol.h"

#define FOR_EACH_STRING_MAP( mapName, iter ) \
for ( auto iter = (mapName).First(); iter < (mapName).GetNumStrings() && iter != (mapName).InvalidIndex(); iter = (mapName).Next( iter ) )

template <class T>
class CUtlStringMap
{
public:
CUtlStringMap( bool caseInsensitive = true, int initsize = 32 ) :
m_SymbolTable( 0, 32, caseInsensitive ),
m_Vector( initsize )
m_Vector( initsize ),
m_SymbolTable( 0, 32, caseInsensitive )
{
}

// Get data by the string itself:
T& operator[]( const char *pString )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString );
int index = ( int )( UtlSymId_t )symbol;
int index = ( int )symbol;
if( m_Vector.Count() <= index )
{
m_Vector.EnsureCount( index + 1 );
Expand All @@ -35,44 +39,119 @@ class CUtlStringMap
}

// Get data by the string's symbol table ID - only used to retrieve a pre-existing symbol, not create a new one!
T& operator[]( UtlSymId_t n )
T& operator[]( CUtlSymbol n )
{
Assert( n <= m_Vector.Count() );
return m_Vector[n];
}

const T& operator[]( UtlSymId_t n ) const
const T& operator[]( CUtlSymbol n ) const
{
Assert( n <= m_Vector.Count() );
return m_Vector[n];
}

unsigned int Count() const
{
// Assert( m_Vector.Count() == m_SymbolTable.GetNumStrings() );
return m_Vector.Count();
}

bool Defined( const char *pString ) const
{
return m_SymbolTable.Find( pString ).IsValid();
}

UtlSymId_t Find( const char *pString ) const
CUtlSymbol Find( const char *pString ) const
{
return m_SymbolTable.Find( pString );
}

UtlSymId_t AddString( const char *pString, bool* created = NULL )
CUtlSymbol AddString( const char *pString, bool* created = NULL )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString, created );
int index = ( int )( UtlSymId_t )symbol;
int index = ( int )symbol;
if( m_Vector.Count() <= index )
{
m_Vector.EnsureCount( index + 1 );
}
return symbol;
}

static UtlSymId_t InvalidIndex()
/// Add a string to the map and also insert an item at
/// its location in the same operation. Returns the
/// newly created index (or the one that was just
/// overwritten, if pString already existed.)
CUtlSymbol Insert( const char *pString, const T &item )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString ); // implicit coercion
if ( m_Vector.Count() > symbol )
{
// this string is already in the dictionary.

}
else if ( m_Vector.Count() == symbol )
{
// this is the expected case when we've added one more to the tail.
m_Vector.AddToTail( item );
}
else // ( m_Vector.Count() < symbol )
{
// this is a strange shouldn't-happen case.
AssertMsg( false, "CUtlStringMap insert unexpected entries." );
m_Vector.EnsureCount( symbol + 1 );
m_Vector[symbol] = item;
}
return symbol;
}
Comment on lines +86 to +107
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no real need in such a method as utlstringmap expects you to do insertions directly by a key, example:

stringmap[newkey] = newvalue;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed to add a new string key & insert it into the expanded utlvector.
CUtlStringMap's operators are desiged for getting/setting an existing key.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are tho, how else would you expect new entries to be added there? You can test yourself these with adding new keys. This code in particular handles that

T& operator[]( const char *pString )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString );
int index = ( int )symbol;
if( m_Vector.Count() <= index )
{
m_Vector.EnsureCount( index + 1 );
}
return m_Vector[index];
}


bool FindAndRemove( const char *pString )
{
CUtlSymbol symbol = m_SymbolTable.Find( pString );

if ( !symbol.IsValid() )
{
return false;
}

Destruct( &m_Vector[ symbol ] );
m_Vector[ symbol ] = {};
m_SymbolTable.Remove( symbol );

return true;
}
Comment on lines +109 to +123
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the comment in CUtlSymbolTable::Remove, this is also becomes invalid so please revert that one as well

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for gsplugins. Are you sure?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replied in the CUtlSymbolTable::Remove comment


/// iterate, not in any particular order.
CUtlSymbol First() const
{
if ( Count() > 0 )
{
return 0;
}
else
{
return InvalidIndex();
}
}

static CUtlSymbol InvalidIndex()
{
return {};
}

// iterators (for uniformity with other map types)
inline CUtlSymbol Head() const
{
return UTL_INVAL_SYMBOL;
return m_SymbolTable.GetNumStrings() > 0 ? CUtlSymbol( 0 ) : InvalidIndex();
}

inline CUtlSymbol Next( const CUtlSymbol &i ) const
{
CUtlSymbol n = i+1;
return n < m_SymbolTable.GetNumStrings() ? n : InvalidIndex();
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as First method, doesn't make much sense here. Especially given that Head returns an index and not a value which is what usually expected to be returned by such methods, but returning a value wouldn't make much sense either so I'd say to revert these as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for iteration by FOR_EACH_STRING_MAP

Copy link
Member

@GAMMACASE GAMMACASE Mar 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well you would need to correct that to be CUtlVector alike, again this method is a bit pointless to have, which does just ++ instead of Next, and starts from 0 instead of Head

int GetNumStrings( void ) const
{
return m_SymbolTable.GetNumStrings();
Expand Down Expand Up @@ -109,4 +188,16 @@ class CUtlStringMap
CUtlSymbolTable m_SymbolTable;
};


template< class T >
class CUtlStringMapAutoPurge : public CUtlStringMap < T >
{
public:
~CUtlStringMapAutoPurge( void )
{
this->PurgeAndDeleteElements();
}

};

#endif // UTLSTRINGMAP_H
24 changes: 9 additions & 15 deletions public/tier1/bufferstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class CBufferString
m_nAllocatedSize( (bAllowHeapAllocation * ALLOW_HEAP_ALLOCATION) | STACK_ALLOCATED_MARKER | (nAllocatedSize + sizeof( m_szString )) ),
m_pString( nullptr )
{
Assert( nAllocatedSize > 8 );
}

public:
Expand Down Expand Up @@ -122,11 +121,11 @@ class CBufferString
bool IsAllocationEmpty() const { return AllocatedNum() == 0; }

protected:
char *Base() { return IsStackAllocated() ? m_szString : (!IsAllocationEmpty() ? m_pString : nullptr); }
char *Base() { return IsStackAllocated() ? m_szString : m_pString; }
const char *Base() const { return const_cast<CBufferString *>( this )->Base(); }

public:
const char *Get() const { auto base = Base(); return base ? base : StringFuncs<char>::EmptyString(); }
const char *Get() const { return IsStackAllocated() ? m_szString : (IsAllocationEmpty() ? StringFuncs<char>::EmptyString() : m_pString); }

void Clear()
{
Expand Down Expand Up @@ -269,8 +268,8 @@ class CBufferString
DLL_CLASS_IMPORT const char *StripExtension();
DLL_CLASS_IMPORT const char *StripTrailingSlash();

DLL_CLASS_IMPORT void ToLowerFast(int nStart);
DLL_CLASS_IMPORT void ToUpperFast(int nStart);
DLL_CLASS_IMPORT void ToLowerFast(int nStart = 0);
DLL_CLASS_IMPORT void ToUpperFast(int nStart = 0);

DLL_CLASS_IMPORT const char *Trim(const char *pTrimChars = "\t\r\n ");
DLL_CLASS_IMPORT const char *TrimHead(const char *pTrimChars = "\t\r\n ");
Expand All @@ -292,19 +291,14 @@ class CBufferString
};
};

template<size_t SIZE>
template< uintp SIZE = 128 > // Most commonly used.
class CBufferStringN : public CBufferString
{
public:
static const size_t DATA_SIZE = ALIGN_VALUE( SIZE - sizeof( char[8] ), 8 );
static const uintp DATA_SIZE = ALIGN_VALUE( SIZE - sizeof( char[8] ), 8 );

CBufferStringN( bool bAllowHeapAllocation = true ) : CBufferString( DATA_SIZE, bAllowHeapAllocation ), m_FixedData{} {}
CBufferStringN( const char *pString, bool bAllowHeapAllocation = true ) : CBufferStringN( bAllowHeapAllocation )
{
Insert( 0, pString );
}

~CBufferStringN() { PurgeN(); }
CBufferStringN( bool bAllowHeapAllocation = true ) : CBufferString( DATA_SIZE, bAllowHeapAllocation ) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why have you removed m_FixedData initialization?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A destructor is definitely not needed, Purge from the inherited CBufferString is used like-in the engine

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be updated in CBufferString(N) sketches

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why github is showing also the destructor part etc, but all I'm asking here is constructor related, you've removed m_FixedData member initialization from it, thus is why I ask why? I'm not sure what is sketches stuff you are talking about, if you can, please, elaborate more.

CBufferStringN( const char *pString, int nLen = -1, bool bAllowHeapAllocation = true ) : CBufferStringN( bAllowHeapAllocation ) { Insert( 0, pString, nLen ); }

// Should be preferred over CBufferString::Purge as it preserves stack space correctly
void PurgeN() { Purge( DATA_SIZE ); }
Expand All @@ -314,7 +308,7 @@ class CBufferStringN : public CBufferString
};

// AMNOTE: CBufferStringN name is preferred to be used, altho CBufferStringGrowable is left as a small bcompat
template <size_t SIZE>
template< uintp SIZE >
using CBufferStringGrowable = CBufferStringN<SIZE>;

#endif /* BUFFERSTRING_H */
Loading