代码改变世界

Gac代码库分析(2)Event和Func

2012-12-09 21:43  Clingingboy  阅读(445)  评论(0编辑  收藏  举报

 

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

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