Gac代码库分析(2)Event和Func
2012-12-09 21:43 Clingingboy 阅读(453) 评论(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
方法的执行分以下几种
代码实现
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);
}
函数的比较
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);
}
这是一个比较好的做法,不然又要进行标识