基于 boost::statechart 模板库的一个秒表计时器
源代码如下:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/transition.hpp>
using namespace std;
namespace sc = boost::statechart;
namespace boost_learning
{
namespace fsm
{
class IElapsedTime
{
public:
virtual double ElapsedTime() const = 0;
};
class EvStartStop : public sc::event<EvStartStop> {};
class EvReset : public sc::event<EvReset> {};
class Active;
// 状态机定义
class StopWatch : public sc::state_machine<StopWatch
, Active> // 初始状态
{
public:
double ElapsedTime() const
{
return state_cast<const IElapsedTime &>().ElapsedTime();
}
};
class Stopped; // 作为Active根状态下的初始子状态,需提前声明
// 根Active状态定义
class Active : public sc::simple_state<Active
, StopWatch // 作为状态机StopWatch的所属状态
, Stopped> // 初始子状态
{
public:
typedef sc::transition< EvReset, Active > reactions;
Active() : elapsedTime_(0.0)
{
}
double ElapsedTime() const {return elapsedTime_;}
double & ElapsedTime() {return elapsedTime_;}
private :
double elapsedTime_ ;
};
// Running状态定义
class Running : public IElapsedTime, public sc::simple_state<Running
, Active> // 父状态
{
public:
typedef sc::transition< EvStartStop, Stopped > reactions;
Running() : startTime_(std::time(0))
{
}
~Running()
{
context<Active>().ElapsedTime() +=
std::difftime(std::time( 0 ), startTime_);
}
virtual double ElapsedTime() const
{
return context<Active>().ElapsedTime() +
std::difftime(std::time( 0 ), startTime_);
}
private :
std:: time_t startTime_;
};
// Stopped状态定义
class Stopped : public IElapsedTime, public sc::simple_state<Stopped
, Active> // 父状态
{
public:
typedef sc::transition< EvStartStop, Running > reactions;
virtual double ElapsedTime() const
{
return context<Active>().ElapsedTime();
}
};
}
}
int _tmain(int argc, _TCHAR* argv[])
{
using namespace boost_learning::fsm;
StopWatch myWatch;
myWatch.initiate();
std::cout << "初始化: " << myWatch.ElapsedTime() << ", 按Enter键开始计时!" << endl;
cin.get();
do
{
std::cout << "本次计时从 " << myWatch.ElapsedTime() << " 开始,按Enter键停止... " << endl;
myWatch.process_event(EvStartStop());
cin.get();
myWatch.process_event(EvStartStop());
std::cout << "计时停止: 共计 " << myWatch.ElapsedTime() << " 秒, 按Enter键继续,Q键退出!" << endl;
} while(cin.get() != 'q');
myWatch.process_event(EvReset());
std::cout << "==== 计时器已被重置,按Enter键退出 ====" << endl;
cin.get();
cin.get();
return 0;
}
示例结果输出:
初始化: 0, 按Enter键开始计时!
本次计时从 0 开始,按Enter键停止...
计时停止: 共计 5 秒, 按Enter键继续,Q键退出!
本次计时从 5 开始,按Enter键停止...
计时停止: 共计 8 秒, 按Enter键继续,Q键退出!
本次计时从 8 开始,按Enter键停止...
计时停止: 共计 16 秒, 按Enter键继续,Q键退出!
q
==== 计时器已被重置,按Enter键退出 ====