//-------------------------------------------------------------------------------------- // File: DXUTMisc.h // // Helper functions for Direct3D programming. // // Copyright (c) Microsoft Corporation. All rights reserved //-------------------------------------------------------------------------------------- #pragma once #ifndef DXUT_MISC_H #define DXUT_MISC_H //-------------------------------------------------------------------------------------- // A growable array //-------------------------------------------------------------------------------------- template< typename TYPE > class CGrowableArray { public: CGrowableArray() { m_pData = NULL; m_nSize = 0; m_nMaxSize = 0; } ~CGrowableArray() { RemoveAll(); } HRESULT SetSize( int nNewMaxSize ); void RemoveAll() { SetSize(0); } protected: TYPE* m_pData; // the actual array of data int m_nSize; // # of elements (upperBound - 1) int m_nMaxSize; // max allocated HRESULT SetSizeInternal( int nNewMaxSize ); // This version doesn't call ctor or dtor. }; //-------------------------------------------------------------------------------------- // Performs timer operations // Use DXUTGetGlobalTimer() to get the global instance //-------------------------------------------------------------------------------------- class CDXUTTimer { public: CDXUTTimer(); void Reset(); // resets the timer void Start(); // starts the timer void Stop(); // stop (or pause) the timer void Advance(); // advance the timer by 0.1 seconds double GetAbsoluteTime(); // get the absolute system time double GetTime(); // get the current time double GetElapsedTime(); // get the time that elapsed between GetElapsedTime() calls bool IsStopped(); // returns true if timer stopped protected: bool m_bUsingQPF; bool m_bTimerStopped; LONGLONG m_llQPFTicksPerSec; LONGLONG m_llStopTime; LONGLONG m_llLastElapsedTime; LONGLONG m_llBaseTime; }; //-------------------------------------------------------------------------------------- // Implementation of CGrowableArray //-------------------------------------------------------------------------------------- // This version doesn't call ctor or dtor. template< typename TYPE > HRESULT CGrowableArray::SetSizeInternal( int nNewMaxSize ) { if( nNewMaxSize < 0 ) { assert( false ); return E_INVALIDARG; } if( nNewMaxSize == 0 ) { // Shrink to 0 size & cleanup if( m_pData ) { free( m_pData ); m_pData = NULL; } m_nMaxSize = 0; m_nSize = 0; } else if( m_pData == NULL || nNewMaxSize > m_nMaxSize ) { // Grow array int nGrowBy = ( m_nMaxSize == 0 ) ? 16 : m_nMaxSize; nNewMaxSize = __max( nNewMaxSize, m_nMaxSize + nGrowBy ); TYPE* pDataNew = (TYPE*) realloc( m_pData, nNewMaxSize * sizeof(TYPE) ); if( pDataNew == NULL ) return E_OUTOFMEMORY; m_pData = pDataNew; m_nMaxSize = nNewMaxSize; } return S_OK; } //-------------------------------------------------------------------------------------- template< typename TYPE > HRESULT CGrowableArray::SetSize( int nNewMaxSize ) { int nOldSize = m_nSize; if( nOldSize > nNewMaxSize ) { // Removing elements. Call dtor. for( int i = nNewMaxSize; i < nOldSize; ++i ) m_pData[i].~TYPE(); } // Adjust buffer. Note that there's no need to check for error // since if it happens, nOldSize == nNewMaxSize will be true.) HRESULT hr = SetSizeInternal( nNewMaxSize ); if( nOldSize < nNewMaxSize ) { // Adding elements. Call ctor. for( int i = nOldSize; i < nNewMaxSize; ++i ) ::new (&m_pData[i]) TYPE; } return hr; } #endif