#include <Windows.h> #include <deque> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <boost/enable_shared_from_this.hpp> using namespace std; using namespace boost; class Command; class ActiveObjectEngine; typedef shared_ptr<Command> CommandPtr; typedef shared_ptr<ActiveObjectEngine> ActiveObjectEnginePtr; typedef weak_ptr<ActiveObjectEngine> ActiveObjectEngineWeakPtr; double secondsPerTick = 0; class Command : public enable_shared_from_this<Command> { public: virtual void Execute()=0; }; class ActiveObjectEngine { deque<CommandPtr> itsCommands; public: void AddCommand(CommandPtr c) { itsCommands.push_back(c); } void Run() { while (itsCommands.size()>0) { CommandPtr c = itsCommands.front(); c->Execute(); itsCommands.pop_front(); } } }; class SleepCommmand : public Command { CommandPtr wakeupCommand; ActiveObjectEngineWeakPtr engine; double sleepTime; bool started; LARGE_INTEGER lv; double start_time; public: SleepCommmand(double milliseconds, ActiveObjectEngineWeakPtr e, CommandPtr wc) : started(false) { sleepTime = milliseconds; engine = e; wakeupCommand = wc; } virtual void Execute() { QueryPerformanceCounter( &lv ); double current_time = secondsPerTick * lv.QuadPart; if (!started) { started = true; start_time = current_time; ActiveObjectEnginePtr strong_ptr = engine.lock(); if (strong_ptr) strong_ptr->AddCommand(shared_from_this()); } else { double elasped_time = current_time - start_time; if (elasped_time < sleepTime) { ActiveObjectEnginePtr strong_ptr = engine.lock(); if (strong_ptr) strong_ptr->AddCommand(shared_from_this()); Sleep(1); } else { ActiveObjectEnginePtr strong_ptr = engine.lock(); if (strong_ptr) strong_ptr->AddCommand(CommandPtr(wakeupCommand)); } } } }; class WakeupCommand : public Command { bool excuted; public: WakeupCommand() { excuted = false; } virtual void Execute() { LARGE_INTEGER lv; QueryPerformanceCounter( &lv ); double current_time = secondsPerTick * lv.QuadPart; excuted = true; //cout<<"\n*********\nExcuted!\n***********"<<current_time; } }; class DelayedTyper : public Command { public: double itsDelay; char itsChar; static bool stop; static ActiveObjectEnginePtr engine; DelayedTyper(double delay, char c) { itsDelay = delay; itsChar = c; } virtual void Execute() { cout<<itsChar; if (!stop) { DelayAndRepeat(); } } void DelayAndRepeat() { CommandPtr c(new SleepCommmand(itsDelay,engine,shared_from_this())); engine->AddCommand(c); } }; bool DelayedTyper::stop = false; ActiveObjectEnginePtr DelayedTyper::engine(new ActiveObjectEngine); class StopCommand : public Command { public: virtual void Execute() { DelayedTyper::stop = true; } }; int _tmain(int argc, _TCHAR* argv[]) { LARGE_INTEGER lv; QueryPerformanceFrequency( &lv ); secondsPerTick = 1.0 / lv.QuadPart; QueryPerformanceCounter( &lv ); double current_time = secondsPerTick * lv.QuadPart; /// One shot /* shared_ptr<WakeupCommand> wakup(new WakeupCommand()); ActiveObjectEnginePtr e (new ActiveObjectEngine()); shared_ptr<SleepCommmand> c(new SleepCommmand(6,e,wakup)); e->AddCommand(c); cout<<"Start...:"<<current_time; e->Run(); */ // Periodic DelayedTyper::engine->AddCommand(CommandPtr(new DelayedTyper(0.01,'1'))); DelayedTyper::engine->AddCommand(CommandPtr(new DelayedTyper(1,'2'))); DelayedTyper::engine->AddCommand(CommandPtr(new DelayedTyper(3,'3'))); CommandPtr sleep_command(new SleepCommmand(6,DelayedTyper::engine,CommandPtr(new StopCommand))); DelayedTyper::engine->AddCommand(sleep_command); DelayedTyper::engine->Run(); return 0; }