回滚操作

 
/******************************************************************** 
 file name : Tool.h 
 author  :   Clark/陈泽丹 
 created :   2011-11-30
 工具包:
 参照Loki库提供指令封装和提供回滚操作
*********************************************************************/ 
#pragma once

#define TYPELIST_1(T1) TOOL::Typelist<T1, ::TOOL::NullType>
#define TYPELIST_2(T1, T2) TOOL::Typelist<T1, TYPELIST_1(T2) >

namespace TOOL
{
	class NullType {};
	template <class T, class U>
	struct Typelist
	{
		typedef T Head;
		typedef U Tail;
	};

	namespace Private
	{
		template <class R>
		struct FunctorImplBase
		{
			typedef R ResultType;
			typedef int Parm1;
			typedef int Parm2;
		};

		template <class R, class TList>
		class FunctorImpl;
		template <class R>
		class FunctorImpl<R, NullType>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			virtual R operator()() = 0;
		};
		template <class R, class P1>
		class FunctorImpl<R, TYPELIST_1(P1)>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			typedef P1 Parm1;
			virtual R operator()(Parm1) = 0;
		};
		template <class R, class P1, class P2>
		class FunctorImpl<R, TYPELIST_2(P1, P2)>: public FunctorImplBase<R>
		{
		public:
			typedef R ResultType;
			typedef P1 Parm1;
			typedef P2 Parm2;
			virtual R operator()(Parm1, Parm2) = 0;
		};

		//普通函数和仿函数的对外接口
		template <class Impl, class Fun>
		class FunctorHandler: public Impl
		{
		private:
			typedef typename Impl Base;
			typedef typename Base::ResultType ResultType;
			typedef typename Base::Parm1 Parm1;
			typedef typename Base::Parm2 Parm2;
			Fun m_fun;

		public:
			FunctorHandler(const Fun& fun) : m_fun(fun) {}
			ResultType operator()(){ return m_fun(); }
			ResultType operator()(Parm1 p1){ return m_fun(p1); }
			ResultType operator()(Parm1 p1, Parm2 p2){ return m_fun(p1, p2); }
		};

		//成员函数的对外接口
		template <class Impl, class PointerToObj, class PointerToMemFn>
		class MemFunHandler : public Impl
		{
		private:
			typedef typename Impl Base;
			typedef typename Base::ResultType ResultType;
			typedef typename Base::Parm1 Parm1;
			typedef typename Base::Parm2 Parm2;
			PointerToObj m_pObj;
			PointerToMemFn m_pMemFn;

		public:
			MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn): m_pObj(pObj), m_pMemFn(pMemFn){}
			ResultType operator()(){ return ((*m_pObj).*m_pMemFn)(); }
			ResultType operator()(Parm1 p1){ return ((*m_pObj).*m_pMemFn)(p1); }
			ResultType operator()(Parm1 p1, Parm2 p2){ return ((*m_pObj).*m_pMemFn)(p1, p2); }
		};
	}

	//指令封装
	//将普通函数,仿函数和成员函数的对外接口整合在一起
	template <class R, class TList = NullType>
	class Functor
	{
	private:
		typedef Private::FunctorImpl<R, TList> Impl;
		typedef R ResultType;
		typedef TList ParmList;
		typedef typename Impl::Parm1 Parm1;
		typedef typename Impl::Parm2 Parm2;
		Impl* m_spImpl;
		//不提供拷贝构造
		Functor(const Functor& other){}
		//不提供赋值语句
		Functor& operator=(const Functor& other){}

	public:
		template <class Fun>
		Functor(Fun fun):m_spImpl(NULL)
		{
			m_spImpl = new Private::FunctorHandler<Impl, Fun>(fun);
			if( NULL == m_spImpl){ /*Log语句*/ }
		}
		template <class PtrObj, class MemFn>
		Functor(const PtrObj& p, MemFn memFn):m_spImpl(NULL)
		{
			m_spImpl = new Private::MemFunHandler<Impl, PtrObj, MemFn>(p, memFn);
			if( NULL == m_spImpl){ /*Log语句*/ }
		}
		ResultType operator()(){ return (*m_spImpl)(); }
		ResultType operator()(Parm1 p1){ return (*m_spImpl)(p1); }
		ResultType operator()(Parm1 p1, Parm2 p2){ return (*m_spImpl)(p1, p2); }
	};

	//回滚操作
	//回滚的触发条件:本个体操作已成功执行,但群体操作未成功,导致本个体操作回滚
	template <class R>
	class Rall
	{
	public:
		Rall():cmd(NULL),m_bIsOK(false){}
		~Rall()
		{
			if( NULL != cmd)
			{
				if( !m_bIsOK )
				{ 
					(*cmd)();
				}
				delete cmd;
				cmd = NULL;
			}
		}

		template <class Fun>
		void SetRall(Fun fun)
		{ 
			if( NULL != cmd){ delete cmd; cmd = NULL; }
			cmd = new Functor<R>(fun); 
		}
		template <class PtrObj, class MemFn>
		void SetRall(const PtrObj& p, MemFn memFn)
		{
			if( NULL != cmd){ delete cmd; cmd = NULL; }
			cmd = new Functor<R>(p, memFn);
		}
		void OK(){ m_bIsOK = true; }
	private:
		bool m_bIsOK;
		Functor<R>* cmd;
	};
	/*
	使用:
	TOOL::Rall<void> r2;
	DataBase db;
	if( db.doDB(true)) 
	r2.SetRall(&db,&DataBase::UndoDB);
	else return;

	TOOL::Rall<void> r1;
	if( doFun(true)) 
	r1.SetRall(UndoFun);
	else return;

	r1.OK();
	r2.OK();
	*/

}

你可能感兴趣的:(回滚操作)