回调类 及 绑定器的简单实现

前些日子学习了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;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值