diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/public/tier1/utlhandletable.h | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/public/tier1/utlhandletable.h')
| -rw-r--r-- | sp/src/public/tier1/utlhandletable.h | 1172 |
1 files changed, 586 insertions, 586 deletions
diff --git a/sp/src/public/tier1/utlhandletable.h b/sp/src/public/tier1/utlhandletable.h index 5d9c46fc..22f54357 100644 --- a/sp/src/public/tier1/utlhandletable.h +++ b/sp/src/public/tier1/utlhandletable.h @@ -1,586 +1,586 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#ifndef UTLHANDLETABLE_H
-#define UTLHANDLETABLE_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include "tier1/utlvector.h"
-#include "tier1/utlqueue.h"
-
-
-//-----------------------------------------------------------------------------
-// Handles are 32 bits. Invalid handles are all 1s
-//-----------------------------------------------------------------------------
-typedef unsigned int UtlHandle_t;
-#define UTLHANDLE_INVALID ((UtlHandle_t)~0)
-
-
-//-----------------------------------------------------------------------------
-// Purpose: This is a table used to allocate handles
-// HandleBits specifies the max # of simultaneously allocated handles.
-// An extra bit is used for the validity state
-// The rest of the 32 bits are used for a serial number
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-class CUtlHandleTable
-{
-public:
- CUtlHandleTable();
-
- // Allocate, deallocate handles
- UtlHandle_t AddHandle();
- void RemoveHandle( UtlHandle_t h );
-
- // Set/get handle values
- void SetHandle( UtlHandle_t h, T *pData );
- T *GetHandle( UtlHandle_t h ) const;
- T *GetHandle( UtlHandle_t h, bool checkValidity ) const;
-
- // Is a handle valid?
- bool IsHandleValid( UtlHandle_t h ) const;
-
- // Iterate over handles; they may not be valid
- unsigned int GetValidHandleCount() const;
- unsigned int GetHandleCount() const;
- UtlHandle_t GetHandleFromIndex( int i ) const;
- int GetIndexFromHandle( UtlHandle_t h ) const;
-
- void MarkHandleInvalid( UtlHandle_t h );
- void MarkHandleValid( UtlHandle_t h );
-
-private:
- struct HandleType_t
- {
- HandleType_t( unsigned int i, unsigned int s ) : nIndex( i ), nSerial( s )
- {
- Assert( i < ( 1 << HandleBits ) );
- Assert( s < ( 1 << ( 31 - HandleBits ) ) );
- }
- unsigned int nIndex : HandleBits;
- unsigned int nSerial : 31 - HandleBits;
- };
-
- struct EntryType_t
- {
- EntryType_t() : m_nSerial( 0 ), nInvalid( 0 ), m_pData( 0 ) {}
- unsigned int m_nSerial : 31;
- unsigned int nInvalid : 1;
- T *m_pData;
- };
-
- static unsigned int GetSerialNumber( UtlHandle_t handle );
- static unsigned int GetListIndex( UtlHandle_t handle );
- static UtlHandle_t CreateHandle( unsigned int nSerial, unsigned int nIndex );
- const EntryType_t *GetEntry( UtlHandle_t handle, bool checkValidity ) const;
-
- unsigned int m_nValidHandles;
- CUtlVector< EntryType_t > m_list;
- CUtlQueue< int > m_unused;
-};
-
-
-//-----------------------------------------------------------------------------
-// Constructor, destructor
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-CUtlHandleTable<T, HandleBits>::CUtlHandleTable() : m_nValidHandles( 0 )
-{
-}
-
-
-//-----------------------------------------------------------------------------
-// Allocate, deallocate handles
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-UtlHandle_t CUtlHandleTable<T, HandleBits>::AddHandle()
-{
- unsigned int nIndex = ( m_unused.Count() > 0 ) ? m_unused.RemoveAtHead() : m_list.AddToTail();
-
- EntryType_t &entry = m_list[ nIndex ];
- entry.nInvalid = 0;
- entry.m_pData = NULL;
-
- ++m_nValidHandles;
-
- return CreateHandle( entry.m_nSerial, nIndex );
-}
-
-template< class T, int HandleBits >
-void CUtlHandleTable<T, HandleBits>::RemoveHandle( UtlHandle_t handle )
-{
- unsigned int nIndex = GetListIndex( handle );
- Assert( nIndex < ( unsigned int )m_list.Count() );
- if ( nIndex >= ( unsigned int )m_list.Count() )
- return;
-
- EntryType_t &entry = m_list[ nIndex ];
- ++entry.m_nSerial; // mark old serial# invalid
- if ( !entry.nInvalid )
- {
- entry.nInvalid = 1;
- --m_nValidHandles;
- }
- entry.m_pData = NULL;
-
-
- // If a handle has been used this many times, then we need to take it out of service, otherwise if the
- // serial # wraps around we'll possibly revalidate old handles and they'll start to point at the wrong objects. Unlikely, but possible.
- bool bStopUsing = ( entry.m_nSerial >= ( (1 << ( 31 - HandleBits ) ) - 1 ) );
- if ( !bStopUsing )
- {
- m_unused.Insert( nIndex );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Set/get handle values
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-void CUtlHandleTable<T, HandleBits>::SetHandle( UtlHandle_t handle, T *pData )
-{
- EntryType_t *entry = const_cast< EntryType_t* >( GetEntry( handle, false ) );
- Assert( entry );
- if ( entry == NULL )
- return;
-
- // Validate the handle
- if ( entry->nInvalid )
- {
- ++m_nValidHandles;
- entry->nInvalid = 0;
- }
- entry->m_pData = pData;
-}
-
-template< class T, int HandleBits >
-T *CUtlHandleTable<T, HandleBits>::GetHandle( UtlHandle_t handle ) const
-{
- const EntryType_t *entry = GetEntry( handle, true );
- return entry ? entry->m_pData : NULL;
-}
-
-template< class T, int HandleBits >
-T *CUtlHandleTable<T, HandleBits>::GetHandle( UtlHandle_t handle, bool checkValidity ) const
-{
- const EntryType_t *entry = GetEntry( handle, checkValidity );
- return entry ? entry->m_pData : NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Is a handle valid?
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-bool CUtlHandleTable<T, HandleBits>::IsHandleValid( UtlHandle_t handle ) const
-{
- if ( handle == UTLHANDLE_INVALID )
- return false;
-
- unsigned int nIndex = GetListIndex( handle );
- AssertOnce( nIndex < ( unsigned int )m_list.Count() );
- if ( nIndex >= ( unsigned int )m_list.Count() )
- return false;
-
- const EntryType_t &entry = m_list[ nIndex ];
- if ( entry.m_nSerial != GetSerialNumber( handle ) )
- return false;
-
- if ( 1 == entry.nInvalid )
- return false;
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Current max handle
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-unsigned int CUtlHandleTable<T, HandleBits>::GetValidHandleCount() const
-{
- return m_nValidHandles;
-}
-
-template< class T, int HandleBits >
-unsigned int CUtlHandleTable<T, HandleBits>::GetHandleCount() const
-{
- return m_list.Count();
-}
-
-template< class T, int HandleBits >
-UtlHandle_t CUtlHandleTable<T, HandleBits>::GetHandleFromIndex( int i ) const
-{
- if ( m_list[i].m_pData )
- return CreateHandle( m_list[i].m_nSerial, i );
- return UTLHANDLE_INVALID;
-}
-
-template< class T, int HandleBits >
-int CUtlHandleTable<T, HandleBits>::GetIndexFromHandle( UtlHandle_t h ) const
-{
- if ( h == UTLHANDLE_INVALID )
- return -1;
-
- return GetListIndex( h );
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Cracking handles into indices + serial numbers
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-unsigned int CUtlHandleTable<T, HandleBits>::GetSerialNumber( UtlHandle_t handle )
-{
- return ( ( HandleType_t* )&handle )->nSerial;
-}
-
-template< class T, int HandleBits >
-unsigned int CUtlHandleTable<T, HandleBits>::GetListIndex( UtlHandle_t handle )
-{
- return ( ( HandleType_t* )&handle )->nIndex;
-}
-
-template< class T, int HandleBits >
-UtlHandle_t CUtlHandleTable<T, HandleBits>::CreateHandle( unsigned int nSerial, unsigned int nIndex )
-{
- HandleType_t h( nIndex, nSerial );
- return *( UtlHandle_t* )&h;
-}
-
-
-//-----------------------------------------------------------------------------
-// Looks up a entry by handle
-//-----------------------------------------------------------------------------
-template< class T, int HandleBits >
-const typename CUtlHandleTable<T, HandleBits>::EntryType_t *CUtlHandleTable<T, HandleBits>::GetEntry( UtlHandle_t handle, bool checkValidity ) const
-{
- if ( handle == UTLHANDLE_INVALID )
- return NULL;
-
- unsigned int nIndex = GetListIndex( handle );
- Assert( nIndex < ( unsigned int )m_list.Count() );
- if ( nIndex >= ( unsigned int )m_list.Count() )
- return NULL;
-
- const EntryType_t &entry = m_list[ nIndex ];
- if ( entry.m_nSerial != GetSerialNumber( handle ) )
- return NULL;
-
- if ( checkValidity &&
- ( 1 == entry.nInvalid ) )
- return NULL;
-
- return &entry;
-}
-
-template< class T, int HandleBits >
-void CUtlHandleTable<T, HandleBits>::MarkHandleInvalid( UtlHandle_t handle )
-{
- if ( handle == UTLHANDLE_INVALID )
- return;
-
- unsigned int nIndex = GetListIndex( handle );
- Assert( nIndex < ( unsigned int )m_list.Count() );
- if ( nIndex >= ( unsigned int )m_list.Count() )
- return;
-
- EntryType_t &entry = m_list[ nIndex ];
- if ( entry.m_nSerial != GetSerialNumber( handle ) )
- return;
-
- if ( !entry.nInvalid )
- {
- --m_nValidHandles;
- entry.nInvalid = 1;
- }
-}
-
-template< class T, int HandleBits >
-void CUtlHandleTable<T, HandleBits>::MarkHandleValid( UtlHandle_t handle )
-{
- if ( handle == UTLHANDLE_INVALID )
- return;
-
- unsigned int nIndex = GetListIndex( handle );
- Assert( nIndex < ( unsigned int )m_list.Count() );
- if ( nIndex >= ( unsigned int )m_list.Count() )
- return;
-
- EntryType_t &entry = m_list[ nIndex ];
- if ( entry.m_nSerial != GetSerialNumber( handle ) )
- return;
-
- if ( entry.nInvalid )
- {
- ++m_nValidHandles;
- entry.nInvalid = 0;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Handle wrapper. Assumes 2 things
-// 1) That class T has a non-static method called GetHandle which returns a UtlHandle_t
-// 2) That class T has a static method called GetPtrFromHandle which returns a T* given a UtlHandle_t
-// 3) That class T has a static method called IsHandleValid which accepts a UtlHandle_t
-//-----------------------------------------------------------------------------
-template< class T >
-class CUtlHandle
-{
-public:
- // Constructors
- CUtlHandle();
- explicit CUtlHandle( T *pObject );
- CUtlHandle( UtlHandle_t h );
- CUtlHandle( const CUtlHandle<T> &h );
-
- // Assignment
- void Set( T *pObject );
- void Set( UtlHandle_t h );
- const CUtlHandle<T> &operator=( UtlHandle_t h );
- const CUtlHandle<T> &operator=( T *pObject );
-
- // Retrieval
- T *Get();
- const T* Get() const;
-
- // Is the handle valid?
- bool IsValid() const;
-
- // Casting
- operator T*();
- operator UtlHandle_t();
- operator bool();
- T* operator->();
- const T* operator->() const;
-
- // Equality
- bool operator==( CUtlHandle<T> h ) const;
- bool operator==( T *pObject ) const;
- bool operator==( UtlHandle_t h ) const;
- bool operator!=( CUtlHandle<T> h ) const;
- bool operator!=( T *pObject ) const;
- bool operator!=( UtlHandle_t h ) const;
-
-private:
- UtlHandle_t m_handle;
-};
-
-
-//-----------------------------------------------------------------------------
-// Constructors
-//-----------------------------------------------------------------------------
-template< class T >
-CUtlHandle<T>::CUtlHandle() : m_handle( UTLHANDLE_INVALID )
-{
-}
-
-template< class T >
-CUtlHandle<T>::CUtlHandle( T *pObject )
-{
- Set( pObject );
-}
-
-template< class T >
-CUtlHandle<T>::CUtlHandle( UtlHandle_t h )
-{
- m_handle = h;
-}
-
-template< class T >
-CUtlHandle<T>::CUtlHandle( const CUtlHandle<T> &h )
-{
- m_handle = h.m_handle;
-}
-
-
-//-----------------------------------------------------------------------------
-// Assignment
-//-----------------------------------------------------------------------------
-template< class T >
-void CUtlHandle<T>::Set( T *pObject )
-{
- // Assumes T has a member function GetHandle
- m_handle = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID;
-}
-
-template< class T >
-void CUtlHandle<T>::Set( UtlHandle_t h )
-{
- m_handle = h;
-}
-
-template< class T >
-const CUtlHandle<T> &CUtlHandle<T>::operator=( UtlHandle_t h )
-{
- Set( h );
- return *this;
-}
-
-template< class T >
-const CUtlHandle<T> &CUtlHandle<T>::operator=( T *pObject )
-{
- Set( pObject );
- return *this;
-}
-
-
-//-----------------------------------------------------------------------------
-// Is the handle valid?
-//-----------------------------------------------------------------------------
-template< class T >
-bool CUtlHandle<T>::IsValid() const
-{
- // Assumes T has a static member function IsHandleValid
- return T::IsHandleValid( m_handle );
-}
-
-
-//-----------------------------------------------------------------------------
-// Retrieval
-//-----------------------------------------------------------------------------
-template< class T >
-T *CUtlHandle<T>::Get()
-{
- // Assumes T has a static member function GetPtrFromHandle
- return T::GetPtrFromHandle( m_handle );
-}
-
-template< class T >
-const T* CUtlHandle<T>::Get() const
-{
- // Assumes T has a static member function GetPtrFromHandle
- return T::GetPtrFromHandle( m_handle );
-}
-
-
-//-----------------------------------------------------------------------------
-// Casting
-//-----------------------------------------------------------------------------
-template< class T >
-CUtlHandle<T>::operator T*()
-{
- return Get();
-}
-
-template< class T >
-CUtlHandle<T>::operator UtlHandle_t()
-{
- return m_handle;
-}
-
-template< class T >
-T* CUtlHandle<T>::operator->()
-{
- return Get();
-}
-
-template< class T >
-const T* CUtlHandle<T>::operator->() const
-{
- return Get();
-}
-
-template< class T >
-CUtlHandle<T>::operator bool()
-{
- return m_handle != UTLHANDLE_INVALID;
-}
-
-
-//-----------------------------------------------------------------------------
-// Equality
-//-----------------------------------------------------------------------------
-template< class T >
-bool CUtlHandle<T>::operator==( CUtlHandle<T> h ) const
-{
- return m_handle == h.m_handle;
-}
-
-template< class T >
-bool CUtlHandle<T>::operator==( T *pObject ) const
-{
- UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID;
- return m_handle == h;
-}
-
-template< class T >
-bool CUtlHandle<T>::operator==( UtlHandle_t h ) const
-{
- return m_handle == h;
-}
-
-template< class T >
-bool CUtlHandle<T>::operator!=( CUtlHandle<T> h ) const
-{
- return m_handle != h.m_handle;
-}
-
-template< class T >
-bool CUtlHandle<T>::operator!=( T *pObject ) const
-{
- UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID;
- return m_handle != h;
-}
-
-template< class T >
-bool CUtlHandle<T>::operator!=( UtlHandle_t h ) const
-{
- return m_handle != h;
-}
-
-
-//-----------------------------------------------------------------------------
-// Add this macro to a class definition to hook in handles for it!
-//-----------------------------------------------------------------------------
-#define DECLARE_HANDLES( _className, _handleBitCount ) \
- public: \
- UtlHandle_t GetHandle() \
- { \
- return m_Handle; \
- } \
- static _className* GetPtrFromHandle( UtlHandle_t h ) \
- { \
- return m_HandleTable.GetHandle( h ); \
- } \
- static bool IsHandleValid( UtlHandle_t h ) \
- { \
- return m_HandleTable.IsHandleValid( h ); \
- } \
- private: \
- UtlHandle_t m_Handle; \
- static CUtlHandleTable< _className, _handleBitCount > m_HandleTable
-
-
-//-----------------------------------------------------------------------------
-// Add this macro to a .cpp file to hook in handles for it!
-//-----------------------------------------------------------------------------
-#define IMPLEMENT_HANDLES( _className, _handleBitCount ) \
- CUtlHandleTable< _className, _handleBitCount > _className::m_HandleTable;
-
-
-//-----------------------------------------------------------------------------
-// Add these macro to the class constructor + destructor
-//-----------------------------------------------------------------------------
-#define CONSTRUCT_HANDLE( ) \
- m_Handle = m_HandleTable.AddHandle(); \
- m_HandleTable.SetHandle( m_Handle, this )
-
-#define DESTRUCT_HANDLE() \
- m_HandleTable.RemoveHandle( m_Handle ); \
- m_Handle = UTLHANDLE_INVALID
-
-
-
-#endif // UTLHANDLETABLE_H
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef UTLHANDLETABLE_H +#define UTLHANDLETABLE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/utlvector.h" +#include "tier1/utlqueue.h" + + +//----------------------------------------------------------------------------- +// Handles are 32 bits. Invalid handles are all 1s +//----------------------------------------------------------------------------- +typedef unsigned int UtlHandle_t; +#define UTLHANDLE_INVALID ((UtlHandle_t)~0) + + +//----------------------------------------------------------------------------- +// Purpose: This is a table used to allocate handles +// HandleBits specifies the max # of simultaneously allocated handles. +// An extra bit is used for the validity state +// The rest of the 32 bits are used for a serial number +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +class CUtlHandleTable +{ +public: + CUtlHandleTable(); + + // Allocate, deallocate handles + UtlHandle_t AddHandle(); + void RemoveHandle( UtlHandle_t h ); + + // Set/get handle values + void SetHandle( UtlHandle_t h, T *pData ); + T *GetHandle( UtlHandle_t h ) const; + T *GetHandle( UtlHandle_t h, bool checkValidity ) const; + + // Is a handle valid? + bool IsHandleValid( UtlHandle_t h ) const; + + // Iterate over handles; they may not be valid + unsigned int GetValidHandleCount() const; + unsigned int GetHandleCount() const; + UtlHandle_t GetHandleFromIndex( int i ) const; + int GetIndexFromHandle( UtlHandle_t h ) const; + + void MarkHandleInvalid( UtlHandle_t h ); + void MarkHandleValid( UtlHandle_t h ); + +private: + struct HandleType_t + { + HandleType_t( unsigned int i, unsigned int s ) : nIndex( i ), nSerial( s ) + { + Assert( i < ( 1 << HandleBits ) ); + Assert( s < ( 1 << ( 31 - HandleBits ) ) ); + } + unsigned int nIndex : HandleBits; + unsigned int nSerial : 31 - HandleBits; + }; + + struct EntryType_t + { + EntryType_t() : m_nSerial( 0 ), nInvalid( 0 ), m_pData( 0 ) {} + unsigned int m_nSerial : 31; + unsigned int nInvalid : 1; + T *m_pData; + }; + + static unsigned int GetSerialNumber( UtlHandle_t handle ); + static unsigned int GetListIndex( UtlHandle_t handle ); + static UtlHandle_t CreateHandle( unsigned int nSerial, unsigned int nIndex ); + const EntryType_t *GetEntry( UtlHandle_t handle, bool checkValidity ) const; + + unsigned int m_nValidHandles; + CUtlVector< EntryType_t > m_list; + CUtlQueue< int > m_unused; +}; + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +CUtlHandleTable<T, HandleBits>::CUtlHandleTable() : m_nValidHandles( 0 ) +{ +} + + +//----------------------------------------------------------------------------- +// Allocate, deallocate handles +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable<T, HandleBits>::AddHandle() +{ + unsigned int nIndex = ( m_unused.Count() > 0 ) ? m_unused.RemoveAtHead() : m_list.AddToTail(); + + EntryType_t &entry = m_list[ nIndex ]; + entry.nInvalid = 0; + entry.m_pData = NULL; + + ++m_nValidHandles; + + return CreateHandle( entry.m_nSerial, nIndex ); +} + +template< class T, int HandleBits > +void CUtlHandleTable<T, HandleBits>::RemoveHandle( UtlHandle_t handle ) +{ + unsigned int nIndex = GetListIndex( handle ); + Assert( nIndex < ( unsigned int )m_list.Count() ); + if ( nIndex >= ( unsigned int )m_list.Count() ) + return; + + EntryType_t &entry = m_list[ nIndex ]; + ++entry.m_nSerial; // mark old serial# invalid + if ( !entry.nInvalid ) + { + entry.nInvalid = 1; + --m_nValidHandles; + } + entry.m_pData = NULL; + + + // If a handle has been used this many times, then we need to take it out of service, otherwise if the + // serial # wraps around we'll possibly revalidate old handles and they'll start to point at the wrong objects. Unlikely, but possible. + bool bStopUsing = ( entry.m_nSerial >= ( (1 << ( 31 - HandleBits ) ) - 1 ) ); + if ( !bStopUsing ) + { + m_unused.Insert( nIndex ); + } +} + + +//----------------------------------------------------------------------------- +// Set/get handle values +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +void CUtlHandleTable<T, HandleBits>::SetHandle( UtlHandle_t handle, T *pData ) +{ + EntryType_t *entry = const_cast< EntryType_t* >( GetEntry( handle, false ) ); + Assert( entry ); + if ( entry == NULL ) + return; + + // Validate the handle + if ( entry->nInvalid ) + { + ++m_nValidHandles; + entry->nInvalid = 0; + } + entry->m_pData = pData; +} + +template< class T, int HandleBits > +T *CUtlHandleTable<T, HandleBits>::GetHandle( UtlHandle_t handle ) const +{ + const EntryType_t *entry = GetEntry( handle, true ); + return entry ? entry->m_pData : NULL; +} + +template< class T, int HandleBits > +T *CUtlHandleTable<T, HandleBits>::GetHandle( UtlHandle_t handle, bool checkValidity ) const +{ + const EntryType_t *entry = GetEntry( handle, checkValidity ); + return entry ? entry->m_pData : NULL; +} + + +//----------------------------------------------------------------------------- +// Is a handle valid? +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +bool CUtlHandleTable<T, HandleBits>::IsHandleValid( UtlHandle_t handle ) const +{ + if ( handle == UTLHANDLE_INVALID ) + return false; + + unsigned int nIndex = GetListIndex( handle ); + AssertOnce( nIndex < ( unsigned int )m_list.Count() ); + if ( nIndex >= ( unsigned int )m_list.Count() ) + return false; + + const EntryType_t &entry = m_list[ nIndex ]; + if ( entry.m_nSerial != GetSerialNumber( handle ) ) + return false; + + if ( 1 == entry.nInvalid ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// Current max handle +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +unsigned int CUtlHandleTable<T, HandleBits>::GetValidHandleCount() const +{ + return m_nValidHandles; +} + +template< class T, int HandleBits > +unsigned int CUtlHandleTable<T, HandleBits>::GetHandleCount() const +{ + return m_list.Count(); +} + +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable<T, HandleBits>::GetHandleFromIndex( int i ) const +{ + if ( m_list[i].m_pData ) + return CreateHandle( m_list[i].m_nSerial, i ); + return UTLHANDLE_INVALID; +} + +template< class T, int HandleBits > +int CUtlHandleTable<T, HandleBits>::GetIndexFromHandle( UtlHandle_t h ) const +{ + if ( h == UTLHANDLE_INVALID ) + return -1; + + return GetListIndex( h ); +} + + + +//----------------------------------------------------------------------------- +// Cracking handles into indices + serial numbers +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +unsigned int CUtlHandleTable<T, HandleBits>::GetSerialNumber( UtlHandle_t handle ) +{ + return ( ( HandleType_t* )&handle )->nSerial; +} + +template< class T, int HandleBits > +unsigned int CUtlHandleTable<T, HandleBits>::GetListIndex( UtlHandle_t handle ) +{ + return ( ( HandleType_t* )&handle )->nIndex; +} + +template< class T, int HandleBits > +UtlHandle_t CUtlHandleTable<T, HandleBits>::CreateHandle( unsigned int nSerial, unsigned int nIndex ) +{ + HandleType_t h( nIndex, nSerial ); + return *( UtlHandle_t* )&h; +} + + +//----------------------------------------------------------------------------- +// Looks up a entry by handle +//----------------------------------------------------------------------------- +template< class T, int HandleBits > +const typename CUtlHandleTable<T, HandleBits>::EntryType_t *CUtlHandleTable<T, HandleBits>::GetEntry( UtlHandle_t handle, bool checkValidity ) const +{ + if ( handle == UTLHANDLE_INVALID ) + return NULL; + + unsigned int nIndex = GetListIndex( handle ); + Assert( nIndex < ( unsigned int )m_list.Count() ); + if ( nIndex >= ( unsigned int )m_list.Count() ) + return NULL; + + const EntryType_t &entry = m_list[ nIndex ]; + if ( entry.m_nSerial != GetSerialNumber( handle ) ) + return NULL; + + if ( checkValidity && + ( 1 == entry.nInvalid ) ) + return NULL; + + return &entry; +} + +template< class T, int HandleBits > +void CUtlHandleTable<T, HandleBits>::MarkHandleInvalid( UtlHandle_t handle ) +{ + if ( handle == UTLHANDLE_INVALID ) + return; + + unsigned int nIndex = GetListIndex( handle ); + Assert( nIndex < ( unsigned int )m_list.Count() ); + if ( nIndex >= ( unsigned int )m_list.Count() ) + return; + + EntryType_t &entry = m_list[ nIndex ]; + if ( entry.m_nSerial != GetSerialNumber( handle ) ) + return; + + if ( !entry.nInvalid ) + { + --m_nValidHandles; + entry.nInvalid = 1; + } +} + +template< class T, int HandleBits > +void CUtlHandleTable<T, HandleBits>::MarkHandleValid( UtlHandle_t handle ) +{ + if ( handle == UTLHANDLE_INVALID ) + return; + + unsigned int nIndex = GetListIndex( handle ); + Assert( nIndex < ( unsigned int )m_list.Count() ); + if ( nIndex >= ( unsigned int )m_list.Count() ) + return; + + EntryType_t &entry = m_list[ nIndex ]; + if ( entry.m_nSerial != GetSerialNumber( handle ) ) + return; + + if ( entry.nInvalid ) + { + ++m_nValidHandles; + entry.nInvalid = 0; + } +} + + +//----------------------------------------------------------------------------- +// Handle wrapper. Assumes 2 things +// 1) That class T has a non-static method called GetHandle which returns a UtlHandle_t +// 2) That class T has a static method called GetPtrFromHandle which returns a T* given a UtlHandle_t +// 3) That class T has a static method called IsHandleValid which accepts a UtlHandle_t +//----------------------------------------------------------------------------- +template< class T > +class CUtlHandle +{ +public: + // Constructors + CUtlHandle(); + explicit CUtlHandle( T *pObject ); + CUtlHandle( UtlHandle_t h ); + CUtlHandle( const CUtlHandle<T> &h ); + + // Assignment + void Set( T *pObject ); + void Set( UtlHandle_t h ); + const CUtlHandle<T> &operator=( UtlHandle_t h ); + const CUtlHandle<T> &operator=( T *pObject ); + + // Retrieval + T *Get(); + const T* Get() const; + + // Is the handle valid? + bool IsValid() const; + + // Casting + operator T*(); + operator UtlHandle_t(); + operator bool(); + T* operator->(); + const T* operator->() const; + + // Equality + bool operator==( CUtlHandle<T> h ) const; + bool operator==( T *pObject ) const; + bool operator==( UtlHandle_t h ) const; + bool operator!=( CUtlHandle<T> h ) const; + bool operator!=( T *pObject ) const; + bool operator!=( UtlHandle_t h ) const; + +private: + UtlHandle_t m_handle; +}; + + +//----------------------------------------------------------------------------- +// Constructors +//----------------------------------------------------------------------------- +template< class T > +CUtlHandle<T>::CUtlHandle() : m_handle( UTLHANDLE_INVALID ) +{ +} + +template< class T > +CUtlHandle<T>::CUtlHandle( T *pObject ) +{ + Set( pObject ); +} + +template< class T > +CUtlHandle<T>::CUtlHandle( UtlHandle_t h ) +{ + m_handle = h; +} + +template< class T > +CUtlHandle<T>::CUtlHandle( const CUtlHandle<T> &h ) +{ + m_handle = h.m_handle; +} + + +//----------------------------------------------------------------------------- +// Assignment +//----------------------------------------------------------------------------- +template< class T > +void CUtlHandle<T>::Set( T *pObject ) +{ + // Assumes T has a member function GetHandle + m_handle = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; +} + +template< class T > +void CUtlHandle<T>::Set( UtlHandle_t h ) +{ + m_handle = h; +} + +template< class T > +const CUtlHandle<T> &CUtlHandle<T>::operator=( UtlHandle_t h ) +{ + Set( h ); + return *this; +} + +template< class T > +const CUtlHandle<T> &CUtlHandle<T>::operator=( T *pObject ) +{ + Set( pObject ); + return *this; +} + + +//----------------------------------------------------------------------------- +// Is the handle valid? +//----------------------------------------------------------------------------- +template< class T > +bool CUtlHandle<T>::IsValid() const +{ + // Assumes T has a static member function IsHandleValid + return T::IsHandleValid( m_handle ); +} + + +//----------------------------------------------------------------------------- +// Retrieval +//----------------------------------------------------------------------------- +template< class T > +T *CUtlHandle<T>::Get() +{ + // Assumes T has a static member function GetPtrFromHandle + return T::GetPtrFromHandle( m_handle ); +} + +template< class T > +const T* CUtlHandle<T>::Get() const +{ + // Assumes T has a static member function GetPtrFromHandle + return T::GetPtrFromHandle( m_handle ); +} + + +//----------------------------------------------------------------------------- +// Casting +//----------------------------------------------------------------------------- +template< class T > +CUtlHandle<T>::operator T*() +{ + return Get(); +} + +template< class T > +CUtlHandle<T>::operator UtlHandle_t() +{ + return m_handle; +} + +template< class T > +T* CUtlHandle<T>::operator->() +{ + return Get(); +} + +template< class T > +const T* CUtlHandle<T>::operator->() const +{ + return Get(); +} + +template< class T > +CUtlHandle<T>::operator bool() +{ + return m_handle != UTLHANDLE_INVALID; +} + + +//----------------------------------------------------------------------------- +// Equality +//----------------------------------------------------------------------------- +template< class T > +bool CUtlHandle<T>::operator==( CUtlHandle<T> h ) const +{ + return m_handle == h.m_handle; +} + +template< class T > +bool CUtlHandle<T>::operator==( T *pObject ) const +{ + UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; + return m_handle == h; +} + +template< class T > +bool CUtlHandle<T>::operator==( UtlHandle_t h ) const +{ + return m_handle == h; +} + +template< class T > +bool CUtlHandle<T>::operator!=( CUtlHandle<T> h ) const +{ + return m_handle != h.m_handle; +} + +template< class T > +bool CUtlHandle<T>::operator!=( T *pObject ) const +{ + UtlHandle_t h = pObject ? pObject->GetHandle() : UTLHANDLE_INVALID; + return m_handle != h; +} + +template< class T > +bool CUtlHandle<T>::operator!=( UtlHandle_t h ) const +{ + return m_handle != h; +} + + +//----------------------------------------------------------------------------- +// Add this macro to a class definition to hook in handles for it! +//----------------------------------------------------------------------------- +#define DECLARE_HANDLES( _className, _handleBitCount ) \ + public: \ + UtlHandle_t GetHandle() \ + { \ + return m_Handle; \ + } \ + static _className* GetPtrFromHandle( UtlHandle_t h ) \ + { \ + return m_HandleTable.GetHandle( h ); \ + } \ + static bool IsHandleValid( UtlHandle_t h ) \ + { \ + return m_HandleTable.IsHandleValid( h ); \ + } \ + private: \ + UtlHandle_t m_Handle; \ + static CUtlHandleTable< _className, _handleBitCount > m_HandleTable + + +//----------------------------------------------------------------------------- +// Add this macro to a .cpp file to hook in handles for it! +//----------------------------------------------------------------------------- +#define IMPLEMENT_HANDLES( _className, _handleBitCount ) \ + CUtlHandleTable< _className, _handleBitCount > _className::m_HandleTable; + + +//----------------------------------------------------------------------------- +// Add these macro to the class constructor + destructor +//----------------------------------------------------------------------------- +#define CONSTRUCT_HANDLE( ) \ + m_Handle = m_HandleTable.AddHandle(); \ + m_HandleTable.SetHandle( m_Handle, this ) + +#define DESTRUCT_HANDLE() \ + m_HandleTable.RemoveHandle( m_Handle ); \ + m_Handle = UTLHANDLE_INVALID + + + +#endif // UTLHANDLETABLE_H + |