前些日子学习了boost库,发现大牛的真强,一直想在工程中使用boost,不过
由于boost太大,且非常复杂,且在工程中一般指用到一部分,所以我一直不敢在产品中使用,
boost 中我最欣赏的就是bind 函数,另外funtional 也很不错
要是只加载几个文件就能实现这几个功能就好了,
为此,我通过泛型及虚类, 简单的实现了一下,代码非常简陋且很多bind功能没有实现,不过总算在我产品中能使用了,且
使代码非常简洁和优美。
第一版如下:
//
// Funtion 用于封装回调函数及函数对象
//
template<typename _Arg, typename _Result>
class _xxfuntional : public SORBA::Shared
{
public:
virtual _Result _call (_Arg value) = 0;
virtual ~_xxfuntional(){};
};
template<typename _Arg, typename _Result>
class funtion
{
public:
typedef funtion<_Arg,_Result> THIS_TYPE;
typedef SORBA::SmartPtr<_xxfuntional<_Arg,_Result>> FUN_TYPE;
funtion()
{
m_fun = NULL;
}
funtion(const funtion& _fun)
{
m_fun = _fun.m_fun;
}
inline bool isNull()
{
return m_fun == NULL;
}
inline void reset()
{
m_fun = NULL;
}
inline _Result operator() (_Arg value)
{
XDB_ASSERT(m_fun != NULL );
return m_fun->_call(value);
}
template<typename _Ty>
THIS_TYPE& operator = ( _Ty _funtor)
{
m_fun = new _xxfuntional_impl_<_Arg,_Result,_Ty>(_funtor);
return *this;
}
template<typename _Ty>
THIS_TYPE& operator = ( _Ty* _funtor)
{
m_fun = new _xxfuntional_impl_point<_Arg,_Result,_Ty>(_funtor);
return *this;
}
template<typename _Ty>
THIS_TYPE& operator = ( SORBA::SmartPtr<_Ty> _funtor)
{
m_fun = new _xxfuntional_impl_smart_point<_Arg,_Result,_Ty>(_funtor);
return *this;
}
THIS_TYPE& operator = ( THIS_TYPE _fun)
{
m_fun = _fun.m_fun;
return *this;
}
void set(_xxfuntional<_Arg ,_Result>* _funtioanl)
{
m_fun = _funtioanl;
}
private:
FUN_TYPE m_fun;
};
template<typename _Arg, typename _Result ,typename _Ty>
class _xxfuntional_impl_ : public _xxfuntional<_Arg, _Result>
{
public:
_xxfuntional_impl_(_Ty _fun): m_fun(_fun)
{
}
virtual _Result _call(_Arg value)
{
return m_fun(value);
}
virtual ~_xxfuntional_impl_()
{
}
private:
_Ty& m_fun;
};
template<typename _Arg, typename _Result ,typename _Ty>
class _xxfuntional_impl_point : public _xxfuntional<_Arg,_Result>
{
public:
_xxfuntional_impl_point(_Ty* _fun): m_fun(_fun)
{
}
virtual ~_xxfuntional_impl_point()
{
}
virtual _Result _call(_Arg value)
{
XDB_ASSERT( m_fun != NULL);
return (*m_fun)(value);
}
private:
_Ty* m_fun;
};
template<typename _Arg, typename _Result ,typename _Ty>
class _xxfuntional_impl_smart_point : public _xxfuntional<_Arg,_Result>
{
typedef SORBA::SmartPtr<_Ty> _TySmart;
public:
_xxfuntional_impl_smart_point(_TySmart _fun): m_fun(_fun)
{
}
virtual ~_xxfuntional_impl_smart_point()
{
}
virtual _Result _call(_Arg value)
{
XDB_ASSERT( m_fun != NULL);
return (*m_fun)(value);
}
private:
_TySmart m_fun;
};
template<typename _Arg, typename _Result ,typename _Ty>
class _xxfuntional_impl_mem_ref : public _xxfuntional<_Arg,_Result>
{
typedef _Result (_Ty::* Mem_Fun_Point)(_Arg);
public:
explicit _xxfuntional_impl_mem_ref(_Ty* _fun ,Mem_Fun_Point _pm): m_fun(_fun),m_Pm(_pm)
{
}
virtual ~_xxfuntional_impl_mem_ref()
{
}
virtual _Result _call(_Arg value)
{
XDB_ASSERT( m_fun != NULL);
XDB_ASSERT( m_Pm != NULL);
return (((*m_fun).*m_Pm)(value));
}
private:
Mem_Fun_Point m_Pm;
_Ty* m_fun;
};
template<typename _Arg, typename _Result ,typename _Ty>
class _xxfuntional_impl_mem_ref_smart : public _xxfuntional<_Arg,_Result>
{
typedef _Result (_Ty::* Mem_Fun_Point)(_Arg);
typedef SORBA::SmartPtr<_Ty> _TySmart;
public:
explicit _xxfuntional_impl_mem_ref_smart(_TySmart _fun ,Mem_Fun_Point _pm):
m_fun(_fun),m_Pm(_pm)
{
}
virtual ~_xxfuntional_impl_mem_ref_smart()
{
}
virtual _Result _call(_Arg value)
{
XDB_ASSERT( m_fun != NULL);
XDB_ASSERT( m_Pm != NULL);
return (((*m_fun).*m_Pm)(value));
}
private:
Mem_Fun_Point m_Pm;
_TySmart m_fun;
};
template<typename _Arg, typename _Result,typename _Ty >
funtion<_Arg,_Result> bind(_Ty& _fun)
{
funtion<_Arg,_Result> fun;
fun = _fun;
return fun;
}
template<typename _Arg, typename _Result,typename _Ty >
funtion<_Arg,_Result > bind(_Ty* _fun)
{
funtion<_Arg,_Result> fun;
fun = _fun;
return fun;
}
template<typename _Arg, typename _Result,typename _Ty >
funtion<_Arg,_Result> bind(SORBA::SmartPtr<_Ty> _fun)
{
funtion< _Arg, _Result > fun;
fun = _fun;
return fun;
}
template<typename _Arg, typename _Result,typename _Ty >
funtion<_Arg,_Result> bind( _Result (_Ty::*_Pm)( _Arg ),_Ty * _funor)
{
funtion<_Arg,_Result> fun;
fun.set(new _xxfuntional_impl_mem_ref<_Arg,_Result,_Ty>(_funor,_Pm));
return fun;
}
template<typename _Arg, typename _Result,typename _Ty >
funtion<_Arg,_Result> bind(_Result (_Ty::*_Pm)( _Arg ) ,SORBA::SmartPtr<_Ty> _fun)
{
funtion<_Arg,_Result> fun;
fun.set(new _xxfuntional_impl_mem_ref_smart<_Arg,_Result,_Ty>(_fun,_Pm));
return fun;
}
//
下面这个类是用 funtion 实现的 一个消息循环处理类
由于部分代码是公司核心代码,不方便贴出,其根据含义可自行编写。
#define MSGQUE_PUSH_CONTIME (std::pair<bool,bool>( true ,true))
#define MSGQUE_PUSH_BREAK (std::pair<bool,bool>( false ,true))
#define MSGQUE_DROP_CONTIME (std::pair<bool,bool>( true ,false))
#define MSGQUE_DROP_BREAK (std::pair<bool,bool>( false ,false))
#define MSGQUE_RC( ProcContinue, MsgPush) (std::pair<bool,bool>( (ProcContinue) ,(MsgPush)) )
/// <summary>
/// T*类型消息队列
/// </summary>
template<typename T>
class MsgQueue
{
public:
typedef typename T MSG_TYPE;
typedef typename T* MSG_TYPE_REF;
typedef MsgQueue<T> THIS_TYPE;
typedef MsgQueue<T>* THIS_TYPE_REF;
typedef std::pair<bool,bool> PROC_RETURN_TYPE;
typedef typename MSG_TYPE_REF PPOC_ARG_TYPE;
typedef typename THIS_TYPE_REF SHUTDOWN_ARG_TYPE;
typedef typename void SHUTDOWN_RETURN_TYPE;
typedef typename THIS_TYPE_REF CIRCLE_ARG_TYPE;
typedef typename void CIRCLE_RETURN_TYPE;
typedef typename funtion<PPOC_ARG_TYPE ,PROC_RETURN_TYPE> MsgProcFuntion;
typedef typename funtion<SHUTDOWN_ARG_TYPE ,SHUTDOWN_RETURN_TYPE> ShutdownFuntion;
typedef typename funtion<CIRCLE_ARG_TYPE ,CIRCLE_RETURN_TYPE> CircleFuntion;
funtion<PROC_RETURN_TYPE,THIS_TYPE> _fun;
public:
MsgQueue(DWORD timeInterval = 5000,bool MutiMode = true ) : m_mutiMode(MutiMode)
{
m_shutdownFlag = true;
m_timeInterval = timeInterval;
}
virtual ~MsgQueue()
{
shutdown();
}
template<class FUN_TYPE>
bool setShutdownFuntion(FUN_TYPE _fun)
{
m_shutdownFuntion = _fun;
return !m_shutdownFuntion.isNull();
}
template<class FUN_TYPE>
bool setCircleFuntion(FUN_TYPE _fun)
{
m_msgCircleFuntion = _fun;
return !m_msgCircleFuntion.isNull();
}
void reset()
{
m_msgProcFuntion.reset();
m_shutdownFuntion.reset();
m_msgCircleFuntion.reset();
}
template<class ProcFunType>
bool initialize(ProcFunType _proc)
{
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
// 已经初始化过了
if( !m_shutdownFlag )
{
return true;
}
m_shutdownFlag = false;
}//锁退出了
m_msgProcFuntion = _proc;
DWORD ThreadId = 0;
//创建事件
m_msgActiveEvent = ::CreateEvent( NULL,FALSE,FALSE,NULL );
CHECK_NULL_GOTO(m_msgActiveEvent);
// 创建后台处理线程
m_msgThread = BEGIN_THREAD(
NULL,
0,
MsgQueue::msgThreadProc,
this,
0,
&ThreadId );
CHECK_NULL_GOTO( m_msgThread );
return true;
//=========================================================
// 错误处理
//=========================================================
ErrorHandler:
//=========================================================
m_shutdownFlag = true;
// 线程
if( m_msgThread != NULL )
{
SetEvent( m_msgActiveEvent );
::WaitForSingleObject( m_msgThread,INFINITE );
FREE_HANDLE( m_msgThread );
}
// 关闭事件
FREE_HANDLE( m_msgActiveEvent );
//清理回调函数
m_msgProcFuntion.reset();
return false;
}
/// <summary>
/// 激活刷新线程。
/// </summary>
inline void activeMsgProcess()
{
if( m_msgActiveEvent != NULL )
{
::SetEvent( m_msgActiveEvent );
}
}
inline bool hasMsg()
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
return !m_msgPool.empty();
}
inline bool pushMsg(MSG_TYPE_REF msg)
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
//只有运行时才能加入
if( m_shutdownFlag)
{
return false;
}
if (!m_mutiMode)
{
MSG_MAP::iterator mapIter = m_mutiMap.find( msg );
//新消息
if (mapIter == m_mutiMap.end())
{
//设置等待标志
m_mutiMap[ msg ] = true;
}
else
{
//如果正在队列中等待,立即返回,则不用再插入;
if ( mapIter->second)
{
//立即返回
activeMsgProcess();
return true;
}
else //否则,需要设置等待标志
{
mapIter->second = true;
}
}
}
m_msgPool.push(msg);
activeMsgProcess();
return true;
}
inline MSG_TYPE_REF nextMsg()
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
MSG_TYPE_REF msg = m_msgPool.front();
m_msgPool.pop();
if (!m_mutiMode)
{
MSG_MAP::iterator mapIter = m_mutiMap.find( msg );
//如果未MUTI模式,消息队列中的消息一定在MAP中,且等待标志为真
XDB_ASSERT( mapIter!= m_mutiMap.end());
XDB_ASSERT( mapIter->second == true);
//等待标志复位
mapIter->second = false;
}
return msg;
}
inline bool isShutdown()
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
return m_shutdownFlag;
}
inline void shutdown()
{
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
// 已经调用过了
if( m_shutdownFlag )
{
return;
}
}//锁退出了
m_shutdownFlag = true;
// 激活后台线程,让其可以退出
activeMsgProcess();
// 等待后台线程结束
if( m_msgThread != NULL )
{
WaitForSingleObject( m_msgThread,INFINITE );
FREE_HANDLE( m_msgThread );
}
//=========================================================
// 回调
//=========================================================
if (!m_shutdownFuntion.isNull())
{
m_shutdownFuntion(this);
}
// 关闭事件
FREE_HANDLE( m_msgActiveEvent );
//清理回调函数
m_msgProcFuntion.reset();
m_shutdownFuntion.reset();
m_msgCircleFuntion.reset();
}
UINT doProc()
{
XDB_ASSERT( m_msgActiveEvent != NULL );
XDB_ASSERT( m_timeInterval != NULL );
XDB_ASSERT( !m_msgProcFuntion.isNull() );
DWORD dwObj = 0;
XDBStatusCode rc;
while( !m_shutdownFlag )
{
// 等待激活事件或者自动触发
dwObj = WaitForSingleObject( m_msgActiveEvent,m_timeInterval);
if( ( dwObj != WAIT_OBJECT_0 ) &&
( dwObj != WAIT_TIMEOUT ) ) // 出现错误
{
XDB_ASSERT( FALSE );
DEBUG_TRACE_ERROR( WSTR("WaitForSingleObject is failed: %d.%s - %d"),GetLastError(),__WFILENAME__,__LINE__ );
return (UINT)STATUSCODE_ABORTED;
}
// 检查关闭标志
if( m_shutdownFlag )
{
return 0;
}
//处理消息队列
while(hasMsg() && !m_shutdownFlag)
{
MSG_TYPE_REF msg = nextMsg();
PROC_RETURN_TYPE rc = (m_msgProcFuntion)(msg);
如果需要继续处理,再循环
if (rc.second)
{
pushMsg(msg);
}
//是否继续循环
if ( !rc.first)
{
break;
}
}
//如果是非重复消息模式,有可能需要清除无用的消息等待标志
if ( !m_mutiMode )
{
//暂时设定为1000
if (m_mutiMap.size() > 1000)
{
XDBAutoLock<XDBSpinLock> lock(m_msgLock);
MSG_MAP::iterator pos = m_mutiMap.begin();
while ( pos != m_mutiMap.end())
{
pos->second == false ? m_mutiMap.erase(pos++) : ++pos;
}
}
}
if (!m_msgCircleFuntion.isNull())
{
m_msgCircleFuntion( this );
}
}
return 0;
}
private:
static UINT msgThreadProc( void* Param )
{
if( Param == NULL ) return 0;
MsgQueue<T>* pThis = ( MsgQueue<T>* )Param;
UINT rc;
BOOL Success = FALSE;
WCHAR ErrInfo[MAX_TRACE_BUFFER] = { 0 };
WCHAR ErrDesc[MAX_TRACE_BUFFER] = { 0 };
DEBUG_TRACE_ERROR( WSTR("MessageQueue thread %d start."), GetCurrentThreadId() );
// 设置结构化异常转换函数
MAP_SEH_TO_CPP_EXCEPTION();
// 使用异常来保护线程
while( !Success )
{
// 运行真正的线程函数
try
{
rc = pThis->doProc();
Success = TRUE; // 线程正常结束
}
catch( XDBWin32Exception& Win32Ex )
{
// 生成异常报告信息
XDBExceptionReport::XDBHandledExceptionFilter(
XDBExceptionReport::GetReportFileName(),
Win32Ex.ExceptionPointers() );
// 构造错误信息
swprintf( ErrInfo,MAX_TRACE_BUFFER,WSTR("0x%08X"), Win32Ex.ExceptionCode() );
DEBUG_TRACE_ERROR( WSTR("Buffer clean thread %d exit unexpected(%d). %s - %d"),
GetCurrentThreadId(),Win32Ex.ExceptionCode(),__WFILENAME__,__LINE__ );
}
catch( ... )
{
// 构造错误信息
swprintf( ErrInfo, MAX_TRACE_BUFFER,WSTR("Unknown") );
DEBUG_TRACE_ERROR( WSTR("Buffer clean thread %d exit unexpected(unknown exception). %s - %d"),
GetCurrentThreadId(),__WFILENAME__,__LINE__ );
}
// 检查是否发生了异常
if( !Success )
{
rc = STATUSCODE_ABORTED;
// 避免再次抛出异常
try
{
// 构造并输出错误信息
ZeroMemory( ErrDesc,MAX_TRACE_BUFFER );
// 格式化错误信息
XDBFormatString( ErrDesc,MAX_TRACE_BUFFER,IDS_ERR_COMMON_ABNORMAL_EXCEPTION,ErrInfo );
// 记录错误日志
TRACE_ERROR( ErrDesc );
} // inner try block
catch( ... )
{
Success = TRUE; // 终止循环
}
} // 非正常终止
}// WHILE LOOP
//=========================================================
// 释放线程局部存储变量
//FREE_CURRENT_CONTEXT();
//=========================================================
// 线程返回值
DEBUG_TRACE_ERROR( WSTR("MessageQueue thread %d exit."), GetCurrentThreadId() );
return rc;
}
private:
// 关闭标志
bool m_shutdownFlag; // 关闭标志
const bool m_mutiMode; // 是否接受重复消息
typedef std::map<T*,bool> MSG_MAP; // 用于判断重复消息
MSG_MAP m_mutiMap;
// 刷新队列
typedef std::queue<T*> MSG_QUEUE;
// 后台刷新检查线程
HANDLE m_msgThread; // 线程句柄
HANDLE m_msgActiveEvent; // 激活事件
MSG_QUEUE m_msgPool; // 检查队列
XDBSpinLock m_msgLock;
DWORD m_timeInterval;
//自定义回调函数
MsgProcFuntion m_msgProcFuntion;
ShutdownFuntion m_shutdownFuntion;
CircleFuntion m_msgCircleFuntion;
};