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);
    }
    

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

  • 相关阅读:
    20145216 史婧瑶《信息安全系统设计基础》第一周学习总结
    20145216史婧瑶《信息安全系统设计基础》第0周学习总结
    20145216《java程序设计》课程总结
    20145216史婧瑶《Java程序设计》第10周学习总结
    20145216史婧瑶《Java程序设计》第五次实验报告
    20145216史婧瑶《Java程序设计》第四次实验报告
    20145216史婧瑶《Java程序设计》第9周学习总结
    20145216史婧瑶《Java程序设计》第三次实验报告
    20145216史婧瑶《Java程序设计》第8周学习总结
    20145220韩旭飞第五周博客
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2810462.html
Copyright © 2011-2022 走看看