224 lines
5.6 KiB
C++
224 lines
5.6 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) Microsoft Corporation, 1998.
|
|
//
|
|
// temparr.hpp
|
|
//
|
|
// Template class used by Direct3D RefDev for stateset and so on.
|
|
//
|
|
// The following error codes should be defined before included this file:
|
|
// DDERR_OUTOFMEMORY
|
|
// D3D_OK
|
|
// DDERR_INVALIDPARAMS
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _TEMPLARR_HPP
|
|
#define _TEMPLARR_HPP
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// Template for growable arrays
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
template <class ARRAY_ELEMENT>
|
|
class GArrayT
|
|
{
|
|
public:
|
|
GArrayT()
|
|
{
|
|
m_pArray = NULL;
|
|
m_dwArraySize = 0;
|
|
m_dwGrowSize = 8;
|
|
}
|
|
|
|
~GArrayT()
|
|
{
|
|
char tmp[256];
|
|
wsprintf( tmp, "m_dwArraySize = %d, m_pArray = %08x\n", m_dwArraySize,
|
|
m_pArray );
|
|
_ASSERT( !((m_dwArraySize == 0)^(m_pArray == NULL)), tmp );
|
|
if( m_pArray ) delete[] m_pArray;
|
|
}
|
|
|
|
virtual void SetGrowSize( DWORD dwGrowSize)
|
|
{
|
|
m_dwGrowSize = dwGrowSize;
|
|
}
|
|
|
|
virtual HRESULT Grow( DWORD dwIndex )
|
|
{
|
|
if( dwIndex < m_dwArraySize ) return S_OK;
|
|
DWORD dwNewArraySize = (dwIndex/m_dwGrowSize + 1) * m_dwGrowSize;
|
|
ARRAY_ELEMENT *pNewArray = AllocArray( dwNewArraySize );
|
|
if( pNewArray == NULL ) return DDERR_OUTOFMEMORY;
|
|
|
|
for( DWORD i = 0; i<m_dwArraySize; i++ )
|
|
pNewArray[i] = m_pArray[i];
|
|
|
|
delete[] m_pArray;
|
|
m_pArray = pNewArray;
|
|
m_dwArraySize = dwNewArraySize;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT Grow( DWORD dwIndex, BOOL* pRealloc )
|
|
{
|
|
if( dwIndex < m_dwArraySize )
|
|
{
|
|
if( pRealloc ) *pRealloc = FALSE;
|
|
return S_OK;
|
|
}
|
|
if( pRealloc ) *pRealloc = TRUE;
|
|
|
|
DWORD dwNewArraySize = m_dwArraySize;
|
|
while( dwNewArraySize <= dwIndex ) dwNewArraySize += m_dwGrowSize;
|
|
ARRAY_ELEMENT *pNewArray = AllocArray( dwNewArraySize );
|
|
if( pNewArray == NULL ) return DDERR_OUTOFMEMORY;
|
|
|
|
for( DWORD i = 0; i<m_dwArraySize; i++ )
|
|
pNewArray[i] = m_pArray[i];
|
|
|
|
delete[] m_pArray;
|
|
m_pArray = pNewArray;
|
|
m_dwArraySize = dwNewArraySize;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual ARRAY_ELEMENT *AllocArray( DWORD dwSize ) const
|
|
{
|
|
return new ARRAY_ELEMENT[dwSize];
|
|
}
|
|
|
|
virtual ARRAY_ELEMENT& operator []( DWORD dwIndex ) const
|
|
{
|
|
char tmp[256];
|
|
wsprintf( tmp, "dwIndex = %d, m_dwArraySize = %d\n", dwIndex,
|
|
m_dwArraySize );
|
|
_ASSERT(dwIndex < m_dwArraySize, tmp);
|
|
return m_pArray[dwIndex];
|
|
}
|
|
|
|
virtual BOOL IsValidIndex( DWORD dwIndex ) const
|
|
{
|
|
return (dwIndex < m_dwArraySize);
|
|
}
|
|
|
|
virtual DWORD GetSize() const
|
|
{
|
|
return m_dwArraySize;
|
|
}
|
|
|
|
virtual DWORD GetGrowSize() const
|
|
{
|
|
return m_dwGrowSize;
|
|
}
|
|
|
|
protected:
|
|
ARRAY_ELEMENT *m_pArray;
|
|
DWORD m_dwArraySize;
|
|
DWORD m_dwGrowSize;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// A more powerful template for a growable array
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
template <class T> class TemplArray
|
|
{
|
|
public:
|
|
TemplArray( void );
|
|
~TemplArray( void );
|
|
|
|
// It is the user of this operator who makes sure 0<=iIndex<m_dwArraySize.
|
|
T& operator []( int iIndex );
|
|
|
|
HRESULT CheckAndGrow( DWORD iIndex, DWORD dwGrowDelta = 16 );
|
|
HRESULT CheckRange ( DWORD iIndex );
|
|
|
|
// The user needs to make sure 0<=m_dwCurrent<m_dwArraySize.
|
|
inline T CurrentItem(void) { return m_pArray[m_dwCurrent];};
|
|
inline void SetCurrentItem(T item) { m_pArray[m_dwCurrent] = item;};
|
|
inline DWORD CurrentIndex(void) { return m_dwCurrent;};
|
|
inline void SetCurrentIndex(DWORD dwIdx) {m_dwCurrent = dwIdx;};
|
|
|
|
inline DWORD ArraySize(void) { return m_dwArraySize;};
|
|
|
|
private:
|
|
T *m_pArray;
|
|
DWORD m_dwArraySize;
|
|
// Index to the current item or the size of data stored in the array
|
|
DWORD m_dwCurrent;
|
|
};
|
|
|
|
|
|
template <class T>
|
|
TemplArray< T >::TemplArray( void )
|
|
{
|
|
m_pArray = NULL;
|
|
m_dwArraySize = 0;
|
|
m_dwCurrent = 0;
|
|
}
|
|
|
|
template <class T>
|
|
TemplArray< T >::~TemplArray( void )
|
|
{
|
|
if (m_pArray != NULL)
|
|
delete m_pArray;
|
|
m_dwArraySize = 0;
|
|
}
|
|
|
|
template <class T> T&
|
|
TemplArray< T >::operator[]( int iIndex )
|
|
{
|
|
return m_pArray[iIndex];
|
|
}
|
|
|
|
template <class T> HRESULT
|
|
TemplArray< T >::CheckAndGrow( DWORD iIndex, DWORD dwGrowDelta )
|
|
{
|
|
if (iIndex >= m_dwArraySize)
|
|
{
|
|
DWORD dwNewArraySize = m_dwArraySize + dwGrowDelta;
|
|
while (iIndex >= dwNewArraySize)
|
|
dwNewArraySize += dwGrowDelta;
|
|
|
|
T *pTmpArray = new T[dwNewArraySize];
|
|
if (pTmpArray == NULL)
|
|
return DDERR_OUTOFMEMORY;
|
|
memset(pTmpArray, 0, sizeof(T) * dwNewArraySize);
|
|
|
|
if (m_pArray != NULL)
|
|
{
|
|
_ASSERT(m_dwArraySize != 0,
|
|
"CheckAndGrow: Array size cannot be NULL" );
|
|
|
|
// Copy existing stuff into new array
|
|
memcpy(pTmpArray, m_pArray, m_dwArraySize * sizeof(T));
|
|
|
|
// Free up existing array
|
|
delete [] m_pArray;
|
|
}
|
|
|
|
|
|
// Assign new array
|
|
m_pArray = pTmpArray;
|
|
m_dwArraySize = dwNewArraySize;
|
|
}
|
|
return D3D_OK;
|
|
}
|
|
|
|
template <class T> HRESULT
|
|
TemplArray< T >::CheckRange( DWORD iIndex )
|
|
{
|
|
if (iIndex >= m_dwArraySize)
|
|
{
|
|
return DDERR_INVALIDPARAMS;
|
|
}
|
|
return D3D_OK;
|
|
}
|
|
|
|
#endif _TEMPLARR_HPP
|