ShsTimer.h
#define g_Timer CShsTimer::GetInstance()
/*
#include "ShsTimer.h" //1. 헤더 선언
void main()
{
g_Timer.StartFrequency(1); //2. 시작점 정하기
Sleep(1000);
g_Timer.EndFrequency(1); //3. 종료점 정하기
__int64 n64Time = g_Timer.GetTime(1); //4. 시간 값 리턴 받기
TRACE( "%I64d\n", n64Time ); //5. 결과 값은 1000이 출력 됨
}
※ Sleep(1000); 대신 수행 시간을 알고싶은 코드를 넣으면 됩니다.
void main()
{
g_Timer.Start(3000, 1); // 3초 후 CheckFired에서 true를 리턴하도록 세팅합니다.
for(;;)
{
if( g_Timer.CheckFired(1) ) // 3초 후 true를 리턴합니다.
{
TRACE( "return" );
return;
}
}
}
void main()
{
for(;;)
{
if( g_Timer.SleepEx(1000, 1) ) // 1초 마다 "1"을 출력합니다. Sleep과 동일
{
TRACE( "1" );
}
}
}
※ 주의
- 인덱스 인자를 줄 때 한 묶음 이외에는 사용해서는 안됩니다. SetTimer의 EventID와 동일한 개념입니다.
*/
struct tFrequencyInfo
{
tFrequencyInfo():m_n64SetTime(0)
{
}
LARGE_INTEGER m_start;
LARGE_INTEGER m_end;
__int64 m_n64SetTime;
};
class CShsTimer
{
private:
CShsTimer();
LARGE_INTEGER m_f;
bool m_bCanNotBeUsed; // true면 현재 컴퓨터에서는 사용 불가
map<int, tFrequencyInfo> m_mapFrequencyInfo;
public:
static CShsTimer& GetInstance();
void StartFrequency( int _nIndex ); // 시간을 측정 할 시작 점 지정
void EndFrequency( int _nIndex ); // 시간을 측정 할 종료 점 지정
__int64 GetTime( int _nIndex ); // Start과 End을 지정 후 걸린 시간을 ms단위로 리턴
void Start(__int64 _n64SetTime, int _nIndex ); // 얼마간의 시간을 흐른뒤에 CheckFired 에서 true를 리턴 할지 설정 해줌 ms단위(1000 == 1초)
bool CheckFired( int _nIndex ); // Start으로 세팅 한 시간이 흐를 때 까지 false를 리턴하다가, 세팅한 시간이 되면 true를 계속 리턴
bool SleepEx(__int64 _n64SetTime, int _nIndex); // Sleep()과 동일 한데 false를 리턴하고, 시간 흐르면 true 리턴
// _n64SetTime 세팅 한 시간이 흐르기 전에는 false 리턴, _n64SetTime만큼 시간이 흐르면 딱 한번 true 리턴하고, 처음과 똑같이 반복
};
ShsTimer.cpp
nclude "stdafx.h"
#include "ShsTimer.h"
CShsTimer& CShsTimer::GetInstance()
{
static CShsTimer Instance;
return Instance;
}
CShsTimer::CShsTimer()
{
// 고해상도 타이머의 주파수를 얻는다.
QueryPerformanceFrequency(&m_f);
if( 0 == m_f.QuadPart )
m_bCanNotBeUsed = true;
else
m_bCanNotBeUsed = false;
}
void CShsTimer::StartFrequency( int _nIndex )
{
if( m_bCanNotBeUsed )
return;
// 시작 시점의 CPU 클럭수를 얻는다.
QueryPerformanceCounter(&m_mapFrequencyInfo[_nIndex].m_start);
}
void CShsTimer::EndFrequency( int _nIndex )
{
if( m_bCanNotBeUsed )
return;
// 끝 시점의 클럭수를 얻는다.
QueryPerformanceCounter(&m_mapFrequencyInfo[_nIndex].m_end);
}
__int64 CShsTimer::GetTime( int _nIndex )
{
if( m_bCanNotBeUsed )
return 0;
// 끝 시점의 CPU 클럭수에서 시작 시점의 클럭수를 뺀 후 주파수를 1000으로 나눈 값을 나눈다.
// 1초 기준의 주파수를 1000 으로 나누었기 때문에 1밀리초 동안 발생하는 진동수로 나눈 셈이다.
__int64 ms_interval = (m_mapFrequencyInfo[_nIndex].m_end.QuadPart - m_mapFrequencyInfo[_nIndex].m_start.QuadPart)/(m_f.QuadPart/1000);
return ms_interval;
}
void CShsTimer::Start( __int64 _n64SetTime, int _nIndex )
{
if( m_bCanNotBeUsed )
return;
m_mapFrequencyInfo[_nIndex].m_n64SetTime = _n64SetTime;
StartFrequency(_nIndex);
}
bool CShsTimer::CheckFired( int _nIndex )
{
if( m_bCanNotBeUsed )
return false;
EndFrequency(_nIndex);
if ( GetTime(_nIndex) > m_mapFrequencyInfo[_nIndex].m_n64SetTime )
return true;
return false;
}
bool CShsTimer::SleepEx( __int64 _n64SetTime, int _nIndex )
{
if( m_bCanNotBeUsed )
return false;
if( 0 == m_mapFrequencyInfo[_nIndex].m_n64SetTime )
{
Start(_n64SetTime, _nIndex);
return false;
}
if( CheckFired(_nIndex) )
{
StartFrequency(_nIndex);
return true;
}
return false;
}