野百合也有春天

导航

Active Object MFC多线程版本

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




posted on 2010-12-22 08:10  flydream  阅读(316)  评论(0编辑  收藏  举报