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