#include "stdafx.h"
#include "MFCThread.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;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
void MSleep( long lTime, bool bProcessMsg )
{
LARGE_INTEGER litmp;
LONGLONG QPart1, QPart2;
double dfMinus, dfFreq, dfTim, dfSpec;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
dfSpec = 0.000001*lTime;
do
{
if ( bProcessMsg == true )
{
MSG msg;
PeekMessage(&msg,NULL,0,0,PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;
}while(dfTim<dfSpec);
}
double secondsPerTick = 0;
class Command;
class ActiveObjectEngine;
typedef shared_ptr<Command> CommandPtr;
typedef shared_ptr<ActiveObjectEngine> ActiveObjectEnginePtr;
typedef weak_ptr<ActiveObjectEngine> ActiveObjectEngineWeakPtr;
class Command : public enable_shared_from_this<Command>
{
public:
virtual void Execute()=0;
};
class ActiveObjectEngine : public CWinThread
{
public: // Member functions
ActiveObjectEngine(AFX_THREADPROC pfnThreadProc);
static UINT ThreadFunc(LPVOID param);
void AddCommand(CommandPtr c)
{
itsCommands.push_back(c);
}
public:
deque<CommandPtr> itsCommands;
private: // The "real" startup function
virtual void Go();
};
ActiveObjectEngine::ActiveObjectEngine(AFX_THREADPROC pfnThreadProc)
: CWinThread(pfnThreadProc, NULL) // Undocumented constructor
{
m_bAutoDelete = FALSE;
// Set the pointer to the class to be the startup value.
// m_pThreadParams is undocumented,
// but there is no work-around.
m_pThreadParams = this;
}
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());
MSleep(50,true);
}
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(ActiveObjectEngine::ThreadFunc));
class StopCommand : public Command
{
public:
virtual void Execute()
{
DelayedTyper::stop = true;
}
};
int main()
{
LARGE_INTEGER lv;
QueryPerformanceFrequency( &lv );
secondsPerTick = 1.0 / lv.QuadPart;
QueryPerformanceCounter( &lv );
double current_time = secondsPerTick * lv.QuadPart;
DelayedTyper::engine->AddCommand(CommandPtr(new DelayedTyper(0.1,'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->CreateThread();
// shared_ptr<ActiveObjectEngine> pThreads(new ActiveObjectEngine( ActiveObjectEngine::ThreadFunc ));
// VERIFY( pThreads->CreateThread());
printf("Thread launched\n");
WaitForSingleObject(DelayedTyper::engine->m_hThread, INFINITE);
return 0;
}
// static
UINT ActiveObjectEngine::ThreadFunc(LPVOID n)
{
ActiveObjectEngine* pThread = (ActiveObjectEngine*)n;
pThread->Go();
return 0;
}
void ActiveObjectEngine::Go()
{
while (itsCommands.size()>0)
{
CommandPtr c = itsCommands.front();
c->Execute();
itsCommands.pop_front();
}
}