summaryrefslogtreecommitdiff
path: root/mdllib/mdllib_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'mdllib/mdllib_utils.h')
-rw-r--r--mdllib/mdllib_utils.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/mdllib/mdllib_utils.h b/mdllib/mdllib_utils.h
new file mode 100644
index 0000000..cf14629
--- /dev/null
+++ b/mdllib/mdllib_utils.h
@@ -0,0 +1,203 @@
+//========= Copyright 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 )
+
+// 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
+};
+
+
+//
+// CRemoveTracker
+// Class that is tracking removals that are scheduled to happen at given points.
+// Use policy:
+// RemoveBytes / RemoveElements [*] -- schedule removals
+// Finalize -- finalize removal information
+// ComputePointer / ComputeOffset [*] -- compute new pointers/offsets that will happen after removals
+// MemMove -- perform memory moves to apply removals
+//
+class CRemoveTracker
+{
+public:
+ CRemoveTracker() : m_map( DefLessFunc( byte * ) ) {}
+
+ // Schedules a piece of memory for removal
+public:
+ void RemoveBytes( void *pos, int length );
+
+ template< typename T >
+ void RemoveElements( T *ptr, int count = 1 ) { RemoveBytes( ( byte * ) ptr, count * sizeof( T ) ); }
+
+ int GetNumBytesRemoved() const;
+
+ // Finalizes the removal information
+public:
+ 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;
+};
+
+
+//
+// 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 CVarBitVec
+{
+public:
+ void GrowSetBit( int iBit )
+ {
+ if ( iBit >= GetNumBits() )
+ Resize( iBit + 1, false );
+ Set( iBit );
+ }
+
+ bool IsBitSet( int bitNum ) const
+ {
+ return ( bitNum < GetNumBits() ) && CVarBitVec::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