#pragma once
//==============================================================================================
// FileName _timer.h
// Completion Level 2 ( 0 : beginning, 1 : basic, 2 : moderate, 3 : complete )
// Date 2016.10.05
/// Since 2016.08.30
//------------------------------+---------------------------------------------------------------
#include <boost/functional.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread.hpp>
#include "_application.h"
//------------------------------+---------------------------------------------------------------
#define MEMBER_ON_TIME( c, m ) std::bind( &c::m, this, _1 )
class TIMER : public COMPONENT
{
using ON_TIME = std::function< xx( TIMER* ) >;
boost::asio::io_service& ios;
boost::asio::deadline_timer timer;
u32 interval;
ox repeat;
ox active = false;
xx async_start()
{
timer.expires_from_now( boost::posix_time::millisec( interval ) );
timer.async_wait(
boost::bind( &TIMER::handler, this, boost::asio::placeholders::error )
);
}
xx handler( const boost::system::error_code& error )
{
event_login();
if( error != boost::asio::error::operation_aborted )
{
if( repeat && active )
async_start();
if( on_time )
on_time( this );
}
}
xx destroy()
{
stop();
}
public:
CRE TIMER(
const u32 interval = 1000, const ON_TIME on_time = nil,
const ox auto_play = true, const ox repeat = true )
: ios( APPLICATION.ios() )
, timer( ios )
, interval( interval )
, on_time( on_time )
, repeat( repeat )
, COMPONENT( APPLICATION.container() )
{
if( auto_play )
play();
}
KIL ~TIMER()
{
stop();
}
ox is_active()
{
return active;
}
ON_TIME on_time;
xx play()
{
stop();
active = true;
ios.reset();
async_start();
boost::thread( boost::bind( &boost::asio::io_service::run, &ios ) );
}
xx stop()
{
if( active )
{
timer.cancel();
active = false;
}
}
xx set_interval( u32 milli_seconds )
{
interval = milli_seconds;
if( active )
{
stop();
play();
}
}
oo left()
{
return (i32)timer.expires_from_now().total_milliseconds();
}
i32 tag;
};
//==============================================================================================
끝~
사용은 이런식.
int main()
{
{
oo f = []( TIMER* timer )
{
printf( "[X : %d] %s ( ] msec left ) ",
(int)timer, timer->tag, date_time_string( now() ).c_str(), timer->left() );
};
( new TIMER( 1000, f ) )->tag = 1;
( new TIMER( 1000, f ) )->tag = 2;
TIMER a( 1000, f );
a.tag = 3;
a.stop();
ssleep(1);
a.play();
ssleep(2);
{
TIMER b( 1000, f );
b.tag = 4;
ssleep( 2 );
}
ssleep( 2 );
}
getchar();
APPLICATION.close();
return 0;
}
주의할점은 쓰레드 관리하기 귀찮아서 VC++ thread 를 쓴게 아니라 boost::thread 를 쓰고 있다는 점.
주기적 실행을 간편하게 지원한다. 그래도 1ms 이내의 오차는 있을 수 있음
풀 소스코드가 필요하면 cafe.daum.net/codeinside 의 NIL frame work 참고.