博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
好多年前写的一个C++事件回调工具
阅读量:6876 次
发布时间:2019-06-26

本文共 10046 字,大约阅读时间需要 33 分钟。

hot3.png

struct IDestroyMessageHandler{    virtual void onDestroyMessage(IDestroyMessageHandler *pNotifier) = 0;    virtual void register(IDestroyMessageHandler *pRelate) = 0;    virtual void unregister(IDestroyMessageHandler *pRelate) = 0;};class CanUseTrigger : public virtual IDestroyMessageHandler,{public:    virtual ~CanUseTrigger()    {        for(std::vector
::iterator it = m_vRelateList.begin();            it != m_vRelateList.end();            it++)        {            (*it)->onDestroyMessage(this);        }    }    virtual void register(IDestroyMessageHandler *pRelate)    {        std::vector
::iterator it =             std::find(m_vRelateList.begin(), m_vRelateList.end(), pRelate);                if (it == m_vRelateList.end())        {            m_vRelateList.push_back(pRelate);        }    }    virtual void unregister(IDestroyMessageHandler *pRelate)    {        m_vRelateList.erase(std::remove(m_vRelateList.begin(), m_vRelateList.end(), pRelate),                            m_vRelateList.end());    }    virtual void onDestroyMessage(IDestroyMessageHandler *pNotifier)    {        IDestroyMessageHandler *pTmp = dynamic_cast
(pNotifier);        if (pTmp)        {            unregister(pTmp);        }    }private:    std::vector
 m_vRelateList;};class TriggerBase : public virtual IDestroyMessageHandler{public:    virtual ~TriggerBase()    {        for (std::vector
::iterator it =  m_vRelationships.begin();             it != m_vRelationships.end();             it++)        {            it->pOther->onDestroyMessage(this);        }    }    virtual void onDestroyMessage(IDestroyMessageHandler *pNotifier)    {        CanUseTrigger *pTmp = dynamic_cast
(pNotifier);        if (!pTmp)        {            return;        }        m_vRelationships.erase(std::remove(m_vRelationships.begin(), m_vRelationships.end(), Relationship(pTmp)),                               m_vRelationships.end());    }        protected:    void regToUser(CanUseTrigger *pUser)    {        std::vector
::iterator itUser            = std::find(m_vRelationships.begin(), m_vRelationships.end(), Relationship(pUser));                    if (m_vRelationships.end() != itUser)        {            ++(itUser->RefCount);        }        else        {            m_vRelationships.push_back(Relationship(pUser));            m_vRelationships[m_vRelationships.size() - 1].RefCount++;            pUser->register(this);        }    }    void unregFormUser(CanUseTrigger *pUser)    {        std::vector
::iterator itUser            = std::find(m_vRelationships.begin(), m_vRelationships.end(), Relationship(pUser));        if (m_vRelationships.end() != itUser)        {            --(itUser->RefCount);            if(itUser->RefCount < 1)            {                m_vRelationships.erase(itUser);                pUser->unregister(this);            }        }    }    struct Relationship    {        CanUseTrigger *pOther;        i32_t RefCount;        Relationship(CanUseTrigger *pUser) : pOther(pUser), RefCount(0){}        Relationship &operator=(const Relationship &rhs)        {            pOther = rhs.pOther;            RefCount = rhs.RefCount;            return *this;        }        bool operator==(const Relationship &rhs)        {            return pOther == rhs.pOther;        }        bool operator==(const CanUseTrigger *rhs)        {            return pOther == rhs;        }    };    template 
    struct Channel1Base    {        typedef struct{} is_member_t;        typedef struct{} is_not_member_t;            virtual ~Channel1Base(){}        virtual void invoke(P p) = 0;        virtual bool equal(Channel1Base

 *pOther) = 0;        virtual bool isOwner(CanUseTrigger *pCandidate) = 0;    };    template 

    struct Channel2Base    {        typedef struct{} is_member_t;        typedef struct{} is_not_member_t;        virtual ~Channel2Base(){}        virtual void invoke(P1 p1, P2 p2) = 0;        virtual bool equal(Channel2Base
 *pOther) = 0;        virtual bool isOwner(CanUseTrigger *pCandidate) = 0;    };    template 
    struct NakedChannel1 : public Channel1Base

    {        typedef Channel1Base

::is_not_member_t member_spec_t;        typedef void (* method_t)(P);        NakedChannel1(method_t pMethod) : m_pMethod(pMethod){}        ~NakedChannel1(){}        virtual void invoke(P p)        {            if (m_pMethod)            {                m_pMethod(p);            }        }        virtual bool equal(Channel1Base

 *pOther)        {            NakedChannel1

 *pTmp = dynamic_cast

 *>(pOther);            if (!pTmp)            {                return false;            }            return m_pMethod == pTmp->m_pMethod;        }        virtual bool isOwner(CanUseTrigger *pCandidate)        {            return false;        }        method_t m_pMethod;    };    template 

    struct MemberChannel1 : public Channel1Base

    {        typedef Channel1Base

::is_member_t member_spec_t;        typedef void (T:: *method_t)(P);        MemberChannel1(T *pUser, method_t pMethod) : m_pOwner(pUser), m_pMethod(pMethod){}        ~MemberChannel1(){}        virtual void invoke(P p)        {            if (m_pOwner && m_pMethod)            {                (m_pOwner->* m_pMethod)(p);            }        }        virtual bool equal(Channel1Base

 *pOther)        {            MemberChannel1

 *pTmp = dynamic_cast
 *>(pOther);            if(!pTmp)            {                return false;            }            return (m_pOwner == pTmp->m_pOwner) && (m_pMethod == pTmp->m_pMethod);        }        virtual bool isOwner(CanUseTrigger *pCandidate)        {            return m_pOwner == pCandidate;        }        T *m_pOwner;        method_t m_pMethod;    };    template 
    struct NakedChannel2 : public Channel2Base
    {        typedef Channel2Base
::is_not_member_t member_spec_t;        typedef void (* method_t)(P1, P2);            NakedChannel2(method_t pMethod) : m_pMethod(pMethod){}        ~NakedChannel2(){}        virtual void invoke(P1 p1, P2 p2)        {            if (m_pMethod)            {                m_pMethod(p1, p2);            }        }        virtual bool equal(Channel2Base
 *pOther)        {            NakedChannel2
 *pTmp = dynamic_cast
 *>(pOther);            if (!pTmp)            {                return false;            }                        return m_pMethod == pTmp->m_pMethod;        }        virtual bool isOwner(CanUseTrigger *pCandidate)        {            return false;        }        method_t m_pMethod;    };        template 
    struct MemberChannel2 : public Channel2Base
    {        typedef Channel2Base
::is_member_t member_spec_t;        typedef void (T:: *method_t)(P1, P2);        MemberChannel2(T *pUser, method_t pMethod) : m_pOwner(pUser), m_pMethod(pMethod){}        ~MemberChannel2(){}        virtual void invoke(P1 p1, P2 p2)        {            if (m_pOwner && m_pMethod)            {                (m_pOwner->* m_pMethod)(p1, p2);            }                    }        virtual bool equal(Channel2Base
 *pOther)        {            MemberChannel2
 *pTmp = dynamic_cast
 *>(pOther);            if (!pTmp)            {                return false;            }            return (m_pOwner == pTmp->m_pOwner) && (m_pMethod == pTmp->m_pMethod);        }        virtual bool isOwner(CanUseTrigger *pCandidate)        {            return m_pOwner == pCandidate;        }                T *m_pOwner;        method_t m_pMethod;    };    private:    std::vector
 m_vRelationships;};template 
class Trigger1 : public TriggerBase{public:    ~Trigger1()    {        for (std::vector
 *>::iterator it =  m_vChannels.begin();            it != m_vChannels.end();            it++)        {            delete (*it);        }    }    virtual void onDestroyMessage(IDestroyMessageHandler *pNotifier)    {        CanUseTrigger *pTmp = dynamic_cast
(pNotifier);        if (!pTmp)        {            return;        }        for (std::vector
 *>::iterator it =  m_vChannels.begin();             it != m_vChannels.end();             )        {            CanUseTrigger *pTmp = dynamic_cast
(pNotifier);            if (pTmp && (*it)->isOwner(pTmp))            {                it = m_vChannels.erase(it);            }            else            {                ++it;            }        }        TriggerBase::onDestroyMessage(pNotifier);    }    void fire(Param p)    {        for (std::vector
 *>::iterator it =  m_vChannels.begin();             it != m_vChannels.end();             it++)        {            (*it)->invoke(p);        }    }    void add(void (* pMethod)(Param))    {        Channel1Base
 *pChannel = new NakedChannel1
(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(pChannel))            {                break;            }                    }        if (it != m_vChannels.end())        {            m_vChannels.push_back(pChannel);        }    }    template 
    void add(TUser *pUser, void (TUser:: *pMethod)(Param))    {        //assert(dynamic_cast
(pUser));                Channel1Base
 *pChannel = new MemberChannel1
(pUser, pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(pChannel))            {                break;            }                    }        if (it == m_vChannels.end())        {            m_vChannels.push_back(pChannel);            regToUser(pUser);        }    }        void dec(void (* pMethod)(Param))    {        NakedChannel1
 TempChannel(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(&TempChannel))            {                break;            }                    }        if (it != m_vChannels.end())        {            m_vChannels.erase(it);        }    }    template 
    void dec(TUser *pUser, void (TUser:: *pMethod)(Param))    {        std::assert(dynamic_cast
(pUser));                MemberChannel1
 TempChannel(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(&TempChannel))            {                break;            }                    }        if (it != m_vChannels.end())        {            m_vChannels.erase(it);                    }    }private:    std::vector
 *> m_vChannels;};template 
class Trigger2 : public TriggerBase{public:    ~Trigger2()    {        for (std::vector
 *>::iterator it =  m_vChannels.begin();            it != m_vChannels.end();            it++)        {            delete (*it);        }    }    virtual void onDestroyMessage(IDestroyMessageHandler *pNotifier)    {        CanUseTrigger *pTmp = dynamic_cast
(pNotifier);        if (!pTmp)        {            return;        }        for (std::vector
 *>::iterator it =  m_vChannels.begin();             it != m_vChannels.end();             )        {            CanUseTrigger *pTmp = dynamic_cast
(pNotifier);            if (pTmp && (*it)->isOwner(pTmp))            {                it = m_vChannels.erase(it);            }            else            {                ++it;            }        }        TriggerBase::onDestroyMessage(pNotifier);    }    void fire(Param1 p1, Param2 p2)    {        for (std::vector
 *>::iterator it                 =  m_vChannels.begin();             it != m_vChannels.end();             it++)        {            (*it)->invoke(p1, p2);        }    }    void add(void (* pMethod)(Param1, Param2))    {        Channel2Base
 *pChannel            = new NakedChannel2
(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(pChannel))            {                break;            }                    }        if (it == m_vChannels.end())        {            m_vChannels.push_back(pChannel);        }    }    template 
    void add(TUser *pUser, void (TUser:: *pMethod)(Param1, Param2))    {        //std::assert(dynamic_cast
(pUser));                Channel2Base
 *pChannel            = new MemberChannel2
(pUser, pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(pChannel))            {                break;            }                    }        if (it == m_vChannels.end())        {            m_vChannels.push_back(pChannel);            regToUser(pUser);        }    }        void dec(void (* pMethod)(Param1, Param2))    {        NakedChannel2
 TempChannel(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(&TempChannel))            {                break;            }                    }        if (it != m_vChannels.end())        {            m_vChannels.erase(it);        }    }    template 
    void dec(TUser *pUser, void (TUser:: *pMethod)(Param1, Param2))    {        std::assert(dynamic_cast
(pUser));        MemberChannel2
 TempChannel(pMethod);        std::vector
 *>::iterator it = m_vChannels.begin();                for (; it != m_vChannels.end(); it++)        {            if ((*it)->equal(&TempChannel))            {                break;            }                    }        if (it != m_vChannels.end())        {            m_vChannels.erase(it);                    }    }private:    std::vector
 *> m_vChannels;};

转载于:https://my.oschina.net/legendlee/blog/390035

你可能感兴趣的文章
Swift如何给应用添加3D Touch菜单
查看>>
05_Node js 文件管理模块 fs
查看>>
关于python中可迭代对象和迭代器的一些理解
查看>>
界面无小事(五):自定义TextView
查看>>
ES6读书笔记(三)
查看>>
视频播放器全屏旋转方案
查看>>
根据调试工具看Vue源码之生命周期(一)
查看>>
RxJS教程
查看>>
在高并发环境下Reids做缓存踩坑记录
查看>>
通俗易懂--岭回归(L2)、lasso回归(L1)、ElasticNet讲解(算法+案例)
查看>>
Word类报表实例 - 质量检测报告
查看>>
Java进阶篇设计模式之二 ----- 工厂模式
查看>>
2018以太坊编程语言solidity最佳IDE
查看>>
hey,你的CommonJS规范
查看>>
定位?
查看>>
《工具癖》从Github下载开源电子书
查看>>
让Vue的v-for支持迭代器遍历
查看>>
微服务架构基础之API网关
查看>>
下载速度
查看>>
传统电视or互联网电视,智能电视领域谁才是虎狼之师
查看>>