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 /utils/tfstats/timeindexedlist.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/tfstats/timeindexedlist.h')
| -rw-r--r-- | utils/tfstats/timeindexedlist.h | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/utils/tfstats/timeindexedlist.h b/utils/tfstats/timeindexedlist.h new file mode 100644 index 0000000..ec28ad6 --- /dev/null +++ b/utils/tfstats/timeindexedlist.h @@ -0,0 +1,346 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Interface AND implementation of CTimeIndexedList +// +// $Workfile: $ +// $Date: $ +// +//------------------------------------------------------------------------------------------------------ +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#ifndef TIMEINDEXEDLIST_H +#define TIMEINDEXEDLIST_H +#ifdef WIN32 +#pragma once +#endif +#include <list> +#include "TFStatsApplication.h" +#include "util.h" +//------------------------------------------------------------------------------------------------------ +// Purpose: CTimedIndexedList is a list of elements indexed by time_t's. +// the elements of the list are meant to represent a state that endures over time +// and when it is switched to another state, that is represented by an element in this +// list with the value of the new state at index t, where t is the time that the switch +// occured. +// in TFStats, this is used for player names and player classes +//------------------------------------------------------------------------------------------------------ +template <class T> +class CTimeIndexedList +{ +public: + static time_t PENDING; + typedef struct{T data;time_t start; time_t end;} listtype; + typedef std::list<listtype>::iterator iterator; + typedef std::map<T,time_t>::iterator accumulatorIterator; + typedef std::map<T,time_t> accumulator; + typedef std::list<listtype> timelist; + + timelist theList; + time_t endTime; + bool anythingAtTime(time_t); + T atTime(time_t,T errorvalue=T()); + T favourite(T errorvalue=T()); + CTimeIndexedList(); + void add(time_t a,T b); + bool contains(const T& t); + + accumulator accumulate(); + + time_t howLong(const T& t); + iterator begin(); + iterator end(); + int size(); + int numDifferent(); + + void cut(time_t t); + void remove(T b); +}; +template <class T> +time_t CTimeIndexedList<T>::PENDING=-1; + +template <class T> +CTimeIndexedList<T>::CTimeIndexedList() +{ + + endTime=0; + +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTimeIndexedList<T>::accumulate +// Purpose: +// Output: CTimeIndexedList<T>::accumulator +//------------------------------------------------------------------------------------------------------ +template<class T> +CTimeIndexedList<T>::accumulator CTimeIndexedList<T>::accumulate() +{ + CTimeIndexedList<T>::accumulator accum; //maps from a value of T, to the time that value was played + +/* + //iterate through for debugging purposes + { + + CTimeIndexedList<T>::iterator it=theList.begin(); + for (it;it!=theList.end();++it) + { + CTimeIndexedList<T>::listtype lt=*it; + } + } +*/ + CTimeIndexedList<T>::iterator it=theList.begin(); + for (it;it!=theList.end();++it) + { + time_t start=it->start; + time_t end=it->end; + T& bucket=it->data; + if (end==PENDING) + { + end=endTime; + if (end==0) + { + g_pApp->fatalError("Time flow error, make sure your log file\n"); + } + } + accum[bucket]+=(end-start); + } + + return accum; +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTimeIndexedList<T>::add +// Purpose: +// Input: a - +// b - +//------------------------------------------------------------------------------------------------------ +template<class T> +void CTimeIndexedList<T>::add(time_t a,T b) +{ + bool lastIsB=false; + bool firstElement=false; + listtype insertme; + insertme.data=b; + insertme.start=a; + insertme.end=PENDING; + + if (!theList.empty()) + { + //find the last element and fix up its end-time (if it's pending) + CTimeIndexedList<T>::iterator last=theList.end(); + last--; + listtype lt=*last; + + if (last->end==PENDING && last->data!=b) + last->end=insertme.start; + } + + //add the new element! + theList.push_back(insertme); + + if (a > endTime) + endTime=a; + + + +} +//------------------------------------------------------------------------------------------------------ +// Function: CTimeIndexedList::atTime +// Purpose: returns the element whose time index is the closest to and less than or +// equal to the queried time +// Input: tm - the time that is being queried +// Output: T, the element +//------------------------------------------------------------------------------------------------------ +template <class T> +T CTimeIndexedList<T>::atTime(time_t tm,T errorvalue) +{ + CTimeIndexedList<T>::iterator it; + if (theList.empty()) + return errorvalue; + + //nothing exists here! + if (tm < theList.begin()->start) + return errorvalue; + + for (it=theList.begin();it!=theList.end();++it) + { + time_t mark=it->start; + time_t markend=it->end; + + if (tm >= mark && tm < markend) + return it->data; + if (tm >= mark && markend == PENDING) + return it->data; + } + + return errorvalue; +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTimeIndexedList::favourite +// Purpose: returns the element that spans the most time +// Output: T, the element +//------------------------------------------------------------------------------------------------------ +template <class T> +T CTimeIndexedList<T>::favourite(T errorvalue) +{ + if (theList.empty()) + return errorvalue; + + CTimeIndexedList<T>::accumulator accum=accumulate(); + + //now scan that intermediate map, and determine the element with the longest duration + CTimeIndexedList<T>::accumulatorIterator accumiter=accum.begin(); + + time_t maxtime=0; + CTimeIndexedList<T>::accumulatorIterator fave=accumiter; + + T t= fave->first; + for (accumiter;accumiter!=accum.end();++accumiter) + { + t= fave->first; + time_t clicksPlayed=accumiter->second; + + if (clicksPlayed> maxtime) + { + maxtime=clicksPlayed; + fave=accumiter; + } + } + + T ttt= fave->first; + + return ttt; +} + +//------------------------------------------------------------------------------------------------------ +// Function: CTimeIndexedList::contains +// Purpose: returns true if the element is in the list +// Input: t, the element value that we're querying +// Output: Returns true if the element was in the list +//------------------------------------------------------------------------------------------------------ +template <class T> +bool CTimeIndexedList<T>::contains(const T& t) +{ + CTimeIndexedList<T>::iterator it=theList.begin(); + for (it=theList.begin();it!=theList.end();++it) + { + if (it->data==t) + return true; + } + return false; +} + +template <class T> +time_t CTimeIndexedList<T>::howLong(const T& t) +{ + if (theList.begin()==theList.end()) + return 0; + + CTimeIndexedList<T>::accumulator accum=accumulate(); //maps from a value of T, to the time that value was played + + return accum[t]; +} + +template <class T> +CTimeIndexedList<T>::iterator CTimeIndexedList<T>::begin() +{ + return theList.begin(); +} + +template <class T> +CTimeIndexedList<T>::iterator CTimeIndexedList<T>::end() +{ + return theList.end(); +} + +template <class T> +int CTimeIndexedList<T>::size() +{ + return theList.size(); +} + + +template <class T> +int CTimeIndexedList<T>::numDifferent() +{ + if (theList.begin()==theList.end()) + return 0; + + //maps from a value of T, to the time that value was played + CTimeIndexedList<T>::accumulator accum=accumulate(); + + return accum.size(); +} + + +template<class T> +void CTimeIndexedList<T>::cut(time_t t) +{ + if (t > endTime) + endTime=t; + if (!theList.empty()) + { + //find the last element and fix up its end-time (if it's pending) + CTimeIndexedList<T>::iterator last=theList.end(); + last--; + + if (last->end==PENDING) + last->end=t; + } +} + + +template<class T> +void CTimeIndexedList<T>::remove(T b) +{ + CTimeIndexedList<T>::iterator it=theList.begin(); + + while(it!=theList.end()) + { + if (it->data==b) + it=theList.erase(it); + else + ++it; + } +} + + + + +template <class T> +bool CTimeIndexedList<T>::anythingAtTime(time_t tm) +{ +/* + //iterate through for debugging purposes + { + + CTimeIndexedList<T>::iterator it=theList.begin(); + for (it;it!=theList.end();++it) + { + CTimeIndexedList<T>::listtype lt=*it; + } + } + */ + CTimeIndexedList<T>::iterator it; + if (theList.empty()) + return false; + + //nothing exists here! + if (tm < theList.begin()->start) + return false; + + for (it=theList.begin();it!=theList.end();++it) + { + time_t mark=it->start; + time_t markend=it->end; + + if (tm >= mark && tm < markend) + return true; + } + + return false; +} + +#endif // TIMEINDEXEDLIST_H
\ No newline at end of file |