diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/smooth_average.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'public/smooth_average.h')
| -rw-r--r-- | public/smooth_average.h | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/public/smooth_average.h b/public/smooth_average.h new file mode 100644 index 0000000..25f694b --- /dev/null +++ b/public/smooth_average.h @@ -0,0 +1,222 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SMOOTH_AVERAGE_H +#define SMOOTH_AVERAGE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "utldict.h" + + + +// Use this macro around any value, and it'll queue up the results given to it nTimes and +// provide a running average. +#define SMOOTH_AVERAGE( value, nCount ) CalcSmoothAverage( value, nCount, __FILE__, __LINE__ ) + + +// Same as their counterpart functions but they return more info in a CTimingInfo structure. +#define SMOOTH_AVERAGE_STRUCT( value, nCount ) CalcSmoothAverage_Struct( value, nCount, __FILE__, __LINE__ ) +#define SUM_OVER_TIME_INTERVAL_STRUCT( value, nSeconds ) SumOverTimeInterval_Struct( value, nSeconds, __FILE__, __LINE__ ) + + +template< class T > +class CTimingInfo +{ +public: + T m_AverageValue; // Note: this will be the SUM of the values if using SUM_OVER_TIME_INTERVAL. + + // The high and low points for m_AverageValue over the time interval. + T m_HighAverage; + T m_LowAverage; + + // The high and low points for the value itself over the time interval. + T m_HighValue; + T m_LowValue; +}; + + +template< class T > +class CAveragesInfo +{ +public: + class CEntry + { + public: + T m_Average; + T m_Value; + }; + +public: + CUtlVector< CEntry > m_Values; + int m_iCurValue; +}; + + +template< class T > +class CAveragesInfo_TimeBased +{ +public: + class CEntry + { + public: + CCycleCount m_Time; // When this sample was taken. + T m_Value; + T m_Average; + }; + + CUtlVector<CEntry> m_Values; +}; + + +#if 0 +template< class T > +inline CTimingInfo< T > CalcSmoothAverage_Struct( const T &value, int nTimes, const char *pFilename, int iLine ) +{ + // Find an entry at this file and line. + char fullStr[1024]; + Q_snprintf( fullStr, sizeof( fullStr ), "%s_%i", pFilename, iLine ); + + int index = s_SmoothAverages.Find( fullStr ); + CAveragesInfo<T> *pInfo; + if ( index == s_SmoothAverages.InvalidIndex() ) + { + pInfo = new CAveragesInfo<T>; + index = s_SmoothAverages.Insert( fullStr, pInfo ); + } + else + { + pInfo = (CAveragesInfo<T>*)s_SmoothAverages[index]; + } + + // Add the new value. + int newValueIndex; + CAveragesInfo< T >::CEntry entry; + entry.m_Value = value; + if ( pInfo->m_Values.Count() < nTimes ) + { + newValueIndex = pInfo->m_Values.AddToTail( entry ); + pInfo->m_iCurValue = 0; + } + else + { + newValueIndex = pInfo->m_iCurValue; + pInfo->m_Values[pInfo->m_iCurValue] = entry; + pInfo->m_iCurValue = (pInfo->m_iCurValue+1) % pInfo->m_Values.Count(); + } + + CTimingInfo< T > info; + info.m_AverageValue = pInfo->m_Values[0].m_Value; + + info.m_HighAverage = pInfo->m_Values[0].m_Average; + info.m_LowAverage = pInfo->m_Values[0].m_Average; + + info.m_HighValue = pInfo->m_Values[0].m_Value; + info.m_LowValue = pInfo->m_Values[0].m_Value; + + for ( int i=1; i < pInfo->m_Values.Count(); i++ ) + { + if ( i != newValueIndex ) + { + info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + } + + info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + + info.m_AverageValue += pInfo->m_Values[i].m_Value; + } + + info.m_AverageValue /= pInfo->m_Values.Count(); + pInfo->m_Values[newValueIndex].m_Average = info.m_AverageValue; + return info; +} +#endif + +template< class T > +inline T CalcSmoothAverage( const T &value, int nTimes, const char *pFilename, int iLine ) +{ + CTimingInfo< T > info = CalcSmoothAverage_Struct( value, nTimes, pFilename, iLine ); + return info.m_AverageValue; +}; + + +template< class T > +inline CTimingInfo< T > SumOverTimeInterval_Struct( const T &value, float nSeconds, const char *pFilename, int iLine ) +{ + static CUtlDict< CAveragesInfo_TimeBased< T >*, int > s_SmoothAverages; + + char fullStr[1024]; + Q_snprintf( fullStr, sizeof( fullStr ), "%s_%i", pFilename, iLine ); + + int index = s_SmoothAverages.Find( fullStr ); + CAveragesInfo_TimeBased<T> *pInfo; + if ( index == s_SmoothAverages.InvalidIndex() ) + { + pInfo = new CAveragesInfo_TimeBased<T>; + index = s_SmoothAverages.Insert( fullStr, pInfo ); + } + else + { + pInfo = s_SmoothAverages[index]; + } + + // Get the current time now. + CCycleCount curTime; + curTime.Sample(); + + // Get rid of old samples. + while ( pInfo->m_Values.Count() > 0 && (curTime.GetSeconds() - pInfo->m_Values[0].m_Time.GetSeconds()) > nSeconds ) + pInfo->m_Values.Remove( 0 ); + + // Add on the new sample. + typename CAveragesInfo_TimeBased< T >::CEntry newEntry; + newEntry.m_Time = curTime; + newEntry.m_Value = value; + int newValueIndex = pInfo->m_Values.AddToTail( newEntry ); + + CTimingInfo< T > info; + info.m_AverageValue = pInfo->m_Values[0].m_Value; + + info.m_HighAverage = pInfo->m_Values[0].m_Average; + info.m_LowAverage = pInfo->m_Values[0].m_Average; + + info.m_HighValue = pInfo->m_Values[0].m_Value; + info.m_LowValue = pInfo->m_Values[0].m_Value; + + for ( int i=1; i < pInfo->m_Values.Count(); i++ ) + { + if ( i != newValueIndex ) + { + info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + } + + info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + + info.m_AverageValue += pInfo->m_Values[i].m_Value; + } + + info.m_AverageValue /= pInfo->m_Values.Count(); + pInfo->m_Values[newValueIndex].m_Average = info.m_AverageValue; + return info; +} + + +template< class T > +inline CTimingInfo< T > SumOverTimeInterval( const T &value, float nSeconds, const char *pFilename, int iLine ) +{ + CTimingInfo< T > info = SumOverTimeInterval_Struct( value, nSeconds, pFilename, iLine ); + return info.m_AverageValue; +} + + +#endif // SMOOTH_AVERAGE_H + |