|
|
//====== Copyright � 1996-2007, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef MDLLIB_UTILS_H
#define MDLLIB_UTILS_H
#ifdef _WIN32
#pragma once
#endif
#include "utlmap.h"
#include "utlvector.h"
#include "bitvec.h"
//////////////////////////////////////////////////////////////////////////
//
// Helper macros
//
//////////////////////////////////////////////////////////////////////////
// Declare a pointer and automatically do the cast of initial value to the pointer type
#define DECLARE_PTR( type, name, initval ) type *name = ( type * ) ( initval )
#define DECLARE_UPDATE_PTR( type, name, initval ) name = ( type * ) ( initval )
// Compute a pointer that is offset given number of bytes from the base pointer
#define BYTE_OFF_PTR( initval, offval ) ( ( ( byte * ) ( initval ) ) + ( offval ) )
// Compute difference in bytes between two pointers
#define BYTE_DIFF_PTR( begin, end ) ( ( ( byte * ) ( end ) ) - ( ( byte * ) ( begin ) ) )
// "for {" to iterate children of a studio container
#define ITERATE_CHILDREN( type, name, parent, accessor, count ) \
for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \ type *name = (parent)->accessor( name##_idx );
// "for {" to jointly iterate children of 2 studio containers of same size
#define ITERATE_CHILDREN2( type, type2, name, name2, parent, parent2, accessor, accessor2, count ) \
for ( int name##_idx = 0; name##_idx < (parent)->count; ++ name##_idx ) { \ type *name = (parent)->accessor( name##_idx ); \ type2 *name2 = (parent2)->accessor2( name##_idx );
// "}" to mark the end of iteration block
#define ITERATE_END }
// Get the child of a container by index
#define CHILD_AT( parent, accessor, idx ) ( (parent)->accessor( idx ) )
//
// CLessSimple< T >
// Comparison policy to use "t1 < t2" comparison rule.
//
template < typename T > class CLessSimple { public: bool Less( const T& src1, const T& src2, void *pCtx ) { pCtx; return ( src1 < src2 ); } };
//
// CInsertionTracker
// Class that is tracking insertions that are scheduled to happen at given points.
// Use policy:
// InsertBytes / InsertElements [*] -- schedule insertions
// Finalize -- finalize insertion information
// ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after insertions
// MemMove -- perform memory moves to apply insertions
//
class CInsertionTracker { public: CInsertionTracker() : m_map( DefLessFunc( byte * ) ) {}
// Schedules a piece of memory for insertion
public: void InsertBytes( void *pos, int length );
template< typename T > void InsertElements( T *ptr, int count = 1 ) { InsertBytes( ( byte * ) ptr, count * sizeof( T ) ); }
int GetNumBytesInserted() const;
// Finalizes the insertion information
public: void Finalize();
// Computes where the pointer would point after memory insertion occurs
public: void * ComputePointer( void *ptrNothingInserted ) const; int ComputeOffset( void *ptrBase, int off ) const;
// Perform memory moves, the buffer should be large enough to accommodate inserted bytes
public: void MemMove( void *ptrBase, int &length ) const;
protected: typedef CUtlMap< byte *, int, unsigned int > Map; Map m_map; // pos -> length
};
//
// CMemoryMovingTracker
// Class that is tracking removals that are scheduled to happen at given points.
// Use policy:
// RegisterBytes / RegisterElements[*] -- schedule moving
// Finalize -- finalize moving information
// ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after moving
// MemMove -- perform memory moves to apply
//
class CMemoryMovingTracker { public: enum MemoryMovingPolicy_t { MEMORY_REMOVE, MEMORY_INSERT, MEMORY_MODIFY, }; explicit CMemoryMovingTracker( MemoryMovingPolicy_t ePolicy ) : m_map( DefLessFunc( byte * ) ), m_ePolicy( ePolicy ) {}
// Schedules a piece of memory for removal
public: void RegisterBytes( void *pos, int length ); template< typename T > void RegisterElements( T *ptr, int count = 1 ) { RegisterBytes( ( byte * ) ptr, count * sizeof( T ) ); }
int GetNumBytesRegistered() const;
// Finalizes the removal information
public: void RegisterBaseDelta( void *pOldBase, void *pNewBase ); void Finalize();
// Computes where the pointer would point after memory removal occurs
public: void * ComputePointer( void *ptrNothingRemoved ) const; int ComputeOffset( void *ptrBase, int off ) const;
public: void MemMove( void *ptrBase, int &length ) const;
protected: typedef CUtlMap< byte *, int, unsigned int > Map; Map m_map; // pos -> length
struct Item { Map::IndexType_t idx; byte *ptr; int len; }; Item m_hint; MemoryMovingPolicy_t m_ePolicy; };
//
// CGrowableBitVec
// Serves bit accumulation.
// Provides "GrowSetBit" method to automatically grow to the required size
// and set the given bit.
// Provides safe "IsBitSet" that would return false for missing bits.
//
class CGrowableBitVec : public CLargeVarBitVec { public: void GrowSetBit( int iBit ) { if ( iBit >= GetNumBits() ) Resize( iBit + 1, false ); Set( iBit ); }
bool IsBitSet( int bitNum ) const { return ( bitNum < GetNumBits() ) && CLargeVarBitVec::IsBitSet( bitNum ); } };
//
// CGrowableVector
// Provides zero-initialization for new elements.
//
template < typename T > class CGrowableVector : public CUtlVector < T > { public: T & operator[] ( int idx ) { while ( idx >= Count() ) AddToTail( T() ); return CUtlVector < T >::operator []( idx ); } };
#endif // #ifndef MDLLIB_UTILS_H
|