Files
2022-10-26 12:25:11 +08:00

228 lines
5.2 KiB
C++

#ifndef __TIMER_H__
#define __TIMER_H__
//=======================================================================================================================
/// Timer 클래스
/**
@history
- 2005.2.28 : [taiyo] Timer based time 으로 바꾸었다!
- 2007.7.19 : [taiyo] ITimer, SimpleTimer 구현, 추후 Timer를 ITimer를 상속받게 처리할것임
*/
//=======================================================================================================================
#pragma once
namespace util
{
class ITimer
{
public:
ITimer(){}
virtual ~ITimer(){}
virtual void Clear() {}
virtual void Reset( DWORD dwIntervalTime = 0 ) {}
virtual void SetTimer( DWORD dwIntervalTime ) {}
// manual mode
virtual bool IsExpired( bool bReset = true ) { return false; }
// auto mode
virtual bool IsExpiredAuto( bool bReset = true ){ return false; }
virtual DWORD GetExpireTime() { return 0; }
virtual DWORD GetIntervalTime() { return 0; }
virtual DWORD GetRemainedime() { return 0; }
virtual DWORD GetProcessTime() { return 0; }
virtual void IncreasingExpireTime( DWORD dwAddExpireTime ) {}
// range : [0, 1]
virtual float GetProgressRatio() { return 0.f; }
};
class SimpleTimer : public ITimer
{
public:
SimpleTimer():m_dwExpireTime(0){}
virtual ~SimpleTimer(){}
virtual void Clear()
{
m_dwExpireTime=0;
}
virtual void Reset( DWORD dwIntervalTime )
{
m_dwExpireTime = GetTickCount() + dwIntervalTime;
}
virtual void SetTimer( DWORD dwIntervalTime )
{
Reset( dwIntervalTime );
}
// only manual mode
virtual bool IsExpired( bool bReset = false/*not used*/ )
{
bReset;
if( m_dwExpireTime && GetTickCount() >= m_dwExpireTime )
{
m_dwExpireTime=0;
return true;
}
else
return false;
}
virtual DWORD GetExpireTime() { return m_dwExpireTime; }
virtual DWORD GetRemainedTime()
{
DWORD dwRemainedTime = 0;
if( m_dwExpireTime > (dwRemainedTime=GetTickCount()) )
return ( m_dwExpireTime- dwRemainedTime );
else
return 0;
}
virtual void IncreasingExpireTime( DWORD dwAddExpireTime )
{
m_dwExpireTime += dwAddExpireTime;
}
private:
DWORD m_dwExpireTime;
};
class Timer
{
public:
Timer():m_dwExpireTime(0), m_dwBaseIntervalTime(0), m_bCheckTime(false), m_iBonusIntervalTime(0), m_startTime(GetTickCount()) {}
~Timer(){}
public:
inline void Clear()
{
m_dwExpireTime=m_dwBaseIntervalTime=0;
m_bCheckTime=false;
m_iBonusIntervalTime = 0;
}
inline void SetTimer( DWORD dwIntervalTime )
{
m_dwBaseIntervalTime = dwIntervalTime;
m_iBonusIntervalTime = 0;
Reset();
}
inline DWORD GetBaseIntervalTime() { return m_dwBaseIntervalTime; }
inline DWORD GetIntervalTime()
{
int iIntervalTime = max( 0, (int)m_dwBaseIntervalTime + m_iBonusIntervalTime );
return iIntervalTime;
}
inline void SetBonusIntervalTime( int iBonusIntervalTime ) { m_iBonusIntervalTime = iBonusIntervalTime; }
// m_dwBaseIntervalTime 시간 간격을 그대로 유지하고 다시 타이머를 돌린다.
inline void Reset(/*m_dwBaseIntervalTime*/)
{
m_dwExpireTime = GetTickCount() + GetIntervalTime();
EnableCheckTime();
}
// 타이머를 resume
inline VOID EnableCheckTime()
{
m_bCheckTime = true;
}
// 타이머를 중지한다.
inline VOID DisableCheckTime()
{
m_bCheckTime = false;
}
inline VOID IncreasingExpireTime( DWORD dwAddExpireTime )
{
m_dwExpireTime += dwAddExpireTime;
}
// 만료타임이 되기까지의 현재 진행률
float GetProgressRatio()
{
int iProcessTime = GetTickCount() - (m_dwExpireTime - GetIntervalTime());
return min( 1.0f, (float)iProcessTime / GetIntervalTime() );
}
// 완료되기 까지 남은 시간 ( 단위 ms )
inline DWORD GetRemainedTime()
{
DWORD dwRemainedTime = 0;
if( m_bCheckTime && m_dwExpireTime > (dwRemainedTime=GetTickCount()) )
return (m_dwExpireTime-dwRemainedTime);
else
return 0;
}
// 타이머 시작후 진행된 시간
inline DWORD GetProcessTotalTime()
{
return GetTickCount() - m_startTime;
}
// 만료시간 전까지의 진행된 시간
inline DWORD GetProcessTime()
{
int iProcessTime = GetTickCount() - (m_dwExpireTime - GetIntervalTime());
if( iProcessTime >= 0 )
return iProcessTime;
else
return 0;
}
// problem : 이 함수를 가끔 호출할 경우 IsExpired() == TRUE가 되는 경우가 생긴다.
// 왜나면 1 Tick이라도 오차가 생기지 않기 위해 IsExpired()호출한 시간을 적용하지 않는다.
// Therefore, 이럴경우 IsExpired() == TRUE된 후에 Reset()를 한번 호출해 준다!
inline BOOL IsExpired( BOOL bReset=TRUE )
{
DWORD dwCurTime;
if( m_bCheckTime && ( dwCurTime = GetTickCount() ) >= m_dwExpireTime )
{
if( bReset )
{
m_dwExpireTime = dwCurTime + m_dwBaseIntervalTime;
}
return TRUE;
}
else
return FALSE;
}
// 한번만 타이머를 돌리기 위해
inline BOOL IsExpiredManual( BOOL bReset=TRUE )
{
DWORD dwCurTime;
if( m_bCheckTime && ( dwCurTime = GetTickCount() ) >= m_dwExpireTime )
{
if( bReset )
{
m_dwExpireTime = dwCurTime + m_dwBaseIntervalTime;
}
DisableCheckTime();
return TRUE;
}
else
return FALSE;
}
void InitCoolTime(DWORD dwExpireTime=0)
{
m_dwExpireTime = dwExpireTime;
}
inline DWORD GetExpireTime() { return m_dwExpireTime; }
private:
DWORD m_startTime;
DWORD m_dwExpireTime;
DWORD m_dwBaseIntervalTime;
bool m_bCheckTime;
int m_iBonusIntervalTime;
};
}//End of namespace util
#endif //__TIMER_H__