zoukankan      html  css  js  c++  java
  • Gac代码库分析(2)Event和Func

    一.Event

    1.Event一般都是Func的封装,即Func的集合执行.

    以2个参数的为例

    template< typename T0,typename T1>
    class Event<void(T0,T1)> : public Object, private NotCopyable
    {
    protected:
        collections::SortedList<Func<void(T0,T1)>>    functions;
    public:
        void Add(const Func<void(T0,T1)>& handler)
        {
            functions.Add(handler);
        }
     
        void Remove(const Func<void(T0,T1)>& handler)
        {
            functions.Remove(handler);
        }
     
        template<typename C>
        void Add(C* sender, void(C::*function)(T0,T1))
        {
            functions.Add(Func<void(T0,T1)>(sender, function));
        }
     
        template<typename C>
        void Remove(C* sender, void(C::*function)(T0,T1))
        {
            functions.Remove(Func<void(T0,T1)>(sender, function));
        }
     
        void operator()(T0 p0,T1 p1)const
        {
            for(vint i=0;i<functions.Count();i++)
            {
                functions.Get(i)(p0,p1);
            }
        }
    };
    

    重点则在于Func

    二.Func

    方法的执行分以下几种

    image

    代码实现

        static const vint BinarySize = sizeof(void*)*8;
    protected:
        class Invoker : public Object
        {
        public:
            virtual R Invoke(T0 p0,T1 p1)=0;
            virtual void RetriveBinary(char* binary)=0;
        };
        class StaticInvoker : public Invoker
        {
        protected:
            R(*function)(T0,T1);
        public:
            StaticInvoker(R(*_function)(T0,T1))
                :function(_function)
            {
            }
            virtual R Invoke(T0 p0,T1 p1)
            {
                return function(p0,p1);
            }
            virtual void RetriveBinary(char* binary)
            {
                BinaryRetriver<R(*)(T0,T1), BinarySize> retriver;
                memset(retriver.binary, 0, BinarySize);
                retriver.t=function;
                memcpy(binary, retriver.binary, BinarySize);
            }
        };
        template<typename C>
        class MemberInvoker : public Invoker
        {
        protected:
            C*            sender;
            R(C::*function)(T0,T1);
            struct Content
            {
                C*            sender;
                R(C::*function)(T0,T1);
            };
        public:
            MemberInvoker(C* _sender, R(C::*_function)(T0,T1))
                :sender(_sender)
                ,function(_function)
            {
            }
            virtual R Invoke(T0 p0,T1 p1)
            {
                return (sender->*function)(p0,p1);
            }
            virtual void RetriveBinary(char* binary)
            {
                BinaryRetriver<Content, BinarySize> retriver;
                memset(retriver.binary, 0, BinarySize);
                retriver.t.sender=sender;
                retriver.t.function=function;
                memcpy(binary, retriver.binary, BinarySize);
            }
        };
        template<typename C>
        class PointerInvoker : public Invoker
        {
        protected:
            C*            function;
        public:
            PointerInvoker(C* _function)
                :function(_function)
            {
            }
            virtual R Invoke(T0 p0,T1 p1)
            {
                return function->operator()(p0,p1);
            }
            virtual void RetriveBinary(char* binary)
            {
                BinaryRetriver<C*, BinarySize> retriver;
                memset(retriver.binary, 0, BinarySize);
                retriver.t=function;
                memcpy(binary, retriver.binary, BinarySize);
            }
        };
        template<typename C>
        class SmartPointerInvoker : public Invoker
        {
        protected:
            Ptr<C>        function;
        public:
            SmartPointerInvoker(const Ptr<C>& _function)
                :function(_function)
            {
            }
            virtual R Invoke(T0 p0,T1 p1)
            {
                return function->operator()(p0,p1);
            }
            virtual void RetriveBinary(char* binary)
            {
                BinaryRetriver<C*, BinarySize> retriver;
                memset(retriver.binary, 0, BinarySize);
                retriver.t=function.Obj();
                memcpy(binary, retriver.binary, BinarySize);
            }
        };
        template<typename C>
        class ObjectInvoker : public Invoker
        {
        protected:
            C            function;
        public:
            ObjectInvoker(const C& _function)
                :function(_function)
            {
            }
            virtual R Invoke(T0 p0,T1 p1)
            {
                return function(p0,p1);
            }
            virtual void RetriveBinary(char* binary)
            {
                BinaryRetriver<void*, BinarySize> retriver;
                memset(retriver.binary, 0, BinarySize);
                retriver.t=this;
                memcpy(binary, retriver.binary, BinarySize);
            }
        };
    

    然后以各种构造函数传入

    protected:
        Ptr<Invoker>            invoker;
    public:
        typedef R FunctionType(T0,T1);
        typedef R ResultType;
        Func()
        {
        }
        Func(R(*function)(T0,T1))
        {
            invoker=new StaticInvoker(function);
        }
        template<typename C>
        Func(C* sender, R(C::*function)(T0,T1))
        {
            invoker=new MemberInvoker<C>(sender, function);
        }
        template<typename C>
        Func(C* function)
        {
            invoker=new PointerInvoker<C>(function);
        }
        template<typename C>
        Func(const Ptr<C>& function)
        {
            invoker=new SmartPointerInvoker<C>(function);
        }
        template<typename C>
        Func(const C& function)
        {
            invoker=new ObjectInvoker<C>(function);
        }
        R operator()(T0 p0,T1 p1)const
        {
            return invoker->Invoke(p0,p1);
        }
    

    函数的比较

    image

    bool operator==(const Func<R(T0,T1)>& function)const
    {
        char a[BinarySize];
        char b[BinarySize];
        invoker->RetriveBinary(a);
        function.invoker->RetriveBinary(b);
        return memcmp(a, b, BinarySize)==0;
    }
    

    这时候RetriveBinary接口就发挥作用了,填充Invoker的成员函数来进行比较,

    virtual void RetriveBinary(char* binary)
    {
        BinaryRetriver<Content, BinarySize> retriver;
        memset(retriver.binary, 0, BinarySize);
        retriver.t.sender=sender;
        retriver.t.function=function;
        memcpy(binary, retriver.binary, BinarySize);
    }
    

    这是一个比较好的做法,不然又要进行标识

  • 相关阅读:
    mysql索引类型normal,unique,full text的区别
    php中模糊查询并关联三个select框
    JQuery实现获取多个input输入框的值,并存放在一个数组中
    Chrome 浏览器跨域和安全访问问题 使用 chrome的命令行标记:disable-web-security 参数联调线上数据
    sqlserver 出现 因为文件组 'PRIMARY' 已满 的解决办法 有可能是磁盘剩余空间不足 导致的
    asp.net 分析器错误消息: 文件.aspx.cs”不存在错误
    SQLSERVER排查CPU占用高的情况
    SQL Server Cpu 100% 的常见原因及优化
    Getting Started with OWIN and Katana(Console 代替iis 制作 web服务的简单方案)
    Base64 报错 的解决办法 (Base-64 字符数组或字符串的长度无效。, 输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符,或者填充字符间包含非法字符。)
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2810462.html
Copyright © 2011-2022 走看看