#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;
}