16,548
社区成员




// 这个是delegate的基类
class delegate_root {
}
template <...>
class delegate0 : delegate_root { // 0个参数函数的委托
}
template <...>
class delegate1 : delegate_root { // 1个参数函数的委托
}
template <...>
class delegate2 : delegate_root { // 2个参数函数的委托
}
//使用的时候是这样
class A {
void funA(int x, int y) {
}
void funB(int x, int y) {
}
}
A a;
delegate2<void, int, int> d1(&a, &A::funA); //void是指 函数返回类型是void, 2个int是指委托函数有2个int参数
d1(100, 200); //delegate2重载了()操作符,这样就相当于调用 a.funA(100, 200)
delegate0<void, int, int> d2(&a, &A::funB); //同上, 又定义一个委托
// 所以想用一个vector容器来存放这些委托对象,由于delegate_root 是所有委托的基类,所以
vector<delegate_root*> vec;
// 这样问题就来了,delegate_root 必须有一个虚拟的 operator()
class delegate_root {
virtual operator() {
}
}
//但为了支持不同类型和个数的参数, 该函数必须是模板的,然后写上9遍..
class delegate_root {
template <> // 没参数的
virtual operator()() {
}
template <typename A1> // 一个参数的
virtual operator()(A1 a1) {
}
template <typename A1, typename A2> // 2个参数的
virtual operator()(A1 a1, A2 a2) {
}
}
class FunSet {
private:
public:
vector<delegate_root*> v;
typedef vector<delegate_root*>::iterator _it;
void add(delegate_root* d) {
v.push_back(d);
}
void call(){
for(_it it = v.begin(); it != v.end(); it++) {
(*(*it))();
}
}
template <typename A1, typename A2>
void call(A1 a1, A2 a2){
for(_it it = v.begin(); it != v.end(); it++) {
(*((delegate2<bool, A1, A2>*)(*it)))(a1, a2); //这里强制转换成delegate2<bool, A1, A2> ...
}
}
};
class FunSet {// 用来存放各种委托
private:
public:
vector<delegate_root*> v;
typedef vector<delegate_root*>::iterator _it;
void add(delegate_root* d) {
v.push_back(d);
}
void call(){ // 0参数的
for(_it it = v.begin(); it != v.end(); it++) {
(*(*it))();
}
}
template <typename A1, typename A2>
void call(A1 a1, A2 a2){ // 2参数的
for(_it it = v.begin(); it != v.end(); it++) {
(*(*it))(a1, a2);
}
}
};
class Observable {
typedef map<int, FunSet>::iterator ob_it;
private:
public:
map<int, FunSet> m_obs;
void addListener(int msgType, delegate_root* d) {
ob_it it = m_obs.find(msgType); // 找当前msgType是否已有FunSet
if(it == m_obs.end()) {
m_obs[msgType] = FunSet(); //没有的话 创建一个
}
m_obs[msgType].add(d); //然后把 d 添加进去
}
bool fireEvent(int msgType) { // 0参数的广播
FunSet fs = (*(m_obs.find(msgType))).second;
fs.call();
}
template <typename A1, typename A2>
bool fireEvent(int msgType, A1 a1, A2 a2) { // 2参数的广播
FunSet fs = (*(m_obs.find(msgType))).second;
fs.call(a1, a2);
return true;
}
};
//用起来就比较方便了
class A {
public:
bool hello() { // 0参数的方法
cout << "hello" << endl;
return true;
}
bool resize(int x, int y) { // 2参数的方法
cout << "resize: x=" << x << ", y=" << y << endl;
return true;
}
};
#define REFRESH 1
#define RESIZE 2
int main() {
typedef delegate0<bool> WinHelloListener;
typedef delegate2<bool, int, int> WinResizeListener;
Observable window;
A a;
window.addListener(REFRESH, new WinHelloListener(&a, &A::hello));
window.fireEvent(REFRESH);// 这里能正确调用 A::hello ,因为无参数,所以不需要模板化,只需要函数是虚拟的就可以了
window.addListener(RESIZE, new WinResizeListener(&a, &A::resize));
window.fireEvent(RESIZE, 1, 2); // 但这里调用的却是 delegate_root::operator(x,y), 因为有参数,所以该函数需要模板化, 但这就不能是虚函数了,导致了子类delegate2 的operator(x,y)不能覆盖基类delegate_root的operator(x,y)
return 0;
}
template <class RetType>
class delegate0 : delegate_root {
typedef RetType (delegate0::*fp)(PARAMS);
public:
fp m_fp;
delegate0(xxx) {
m_fp = delegate0::();//在delegate0的构造函数里把指针指向这个类的 operator()
}
}
class delegate_root {
template<class RetType, class A1, class A2>
RetType call(a1, a2) { // 用一个call函数来调用指针指向的函数
m_fp(a1, a2); // 但这里的m_fp 该怎么声明呢?
}
}
// delegate.h
#pragma once
/*
* 以下宏用于预定义委托类的准备
*/
//#define pre_comma
#define comma ,
#define _V0(v)
#define _V1(v) v(p1)
#define _V2(v) v(p1) comma v(p2)
#define _V3(v) v(p1) comma v(p2) comma v(p3)
#define _V4(v) v(p1) comma v(p2) comma v(p3) comma v(p4)
#define _V5(v) v(p1) comma v(p2) comma v(p3) comma v(p4) comma v(p5)
#define _V6(v) v(p1) comma v(p2) comma v(p3) comma v(p4) comma v(p5) comma v(p6)
#define _V7(v) v(p1) comma v(p2) comma v(p3) comma v(p4) comma v(p5) comma v(p6) comma v(p7)
#define _V8(v) v(p1) comma v(p2) comma v(p3) comma v(p4) comma v(p5) comma v(p6) comma v(p7) comma v(p8)
#define _V9(v) v(p1) comma v(p2) comma v(p3) comma v(p4) comma v(p5) comma v(p6) comma v(p7) comma v(p8) comma v(p9)
#define _VN(para_cnt, v) _V##para_cnt(v)
#define semicolon ;
#define _VV0(v)
#define _VV1(v) v(p1)
#define _VV2(v) v(p1) semicolon v(p2)
#define _VV3(v) v(p1) semicolon v(p2) semicolon v(p3)
#define _VV4(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4)
#define _VV5(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4) semicolon v(p5)
#define _VV6(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4) semicolon v(p5) semicolon v(p6)
#define _VV7(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4) semicolon v(p5) semicolon v(p6) semicolon v(p7)
#define _VV8(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4) semicolon v(p5) semicolon v(p6) semicolon v(p7) semicolon v(p8)
#define _VV9(v) v(p1) semicolon v(p2) semicolon v(p3) semicolon v(p4) semicolon v(p5) semicolon v(p6) semicolon v(p7) semicolon v(p8) semicolon v(p9)
#define _VVN(para_cnt, v) _VV##para_cnt(v)
#define _templist(para) typename para
#define _paralist(para) para
#define _paravarlist(para) para _##para
#define _savelist(para) para saved_##para
#define _savetolist(para) saved_##para = _##para
#define _restorelist(para) pThis->saved_##para
#define _callbacklist(para) va_arg(pThis->_vas, para)
#define DeclareDelegate(para_cnt) \
template<class T, typename retT _isZero _VN(para_cnt, _templist)> \
class Delegate##para_cnt \
{ \
typedef retT (T::*FnType)(_VN(para_cnt, _paralist)); \
typedef Delegate##para_cnt<T, retT _isZero _VN(para_cnt, _paralist)> theClass; \
public: \
T* _this; \
Raptor::Thread* _thread; \
FnType _fn; \
_VVN(para_cnt, _savelist); \
retT _ret; \
\
Delegate##para_cnt( FnType fn) : _fn(fn), _thread(0), _this(0) {} \
Delegate##para_cnt( FnType fn, Raptor::Thread* thread, T* obj) : _fn(fn), _thread(thread), _this(obj) {} \
\
retT operator()(Raptor::Thread* thread, T* obj _isZero _VN(para_cnt, _paravarlist)) \
{ \
if (obj==NULL || thread==NULL) return (retT)0; \
_this = obj; \
/*va_start(_vas, obj);*/ \
_VVN(para_cnt, _savetolist); \
thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
return _ret; \
} \
retT operator()(_VN(para_cnt, _paravarlist)) \
{ \
if (_this==NULL || _thread==NULL) return (retT)0; \
_VVN(para_cnt, _savetolist); \
_thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
return _ret; \
} \
static LONG _callback(LPVOID data) \
{ \
theClass * pThis = (theClass*)data; \
pThis->_ret = (pThis->_this->*pThis->_fn)(_VN(para_cnt, _restorelist)/*_VN(para_cnt, _callbacklist)*/); \
return 0; \
} \
}; \
template<typename retT _isZero _VN(para_cnt, _templist)> \
class DelegateApi##para_cnt \
{ \
typedef retT (WINAPI *FnType)(_VN(para_cnt, _paralist)); \
typedef DelegateApi##para_cnt<retT _isZero _VN(para_cnt, _paralist)> theClass; \
public: \
Raptor::Thread* _thread; \
FnType _fn; \
_VVN(para_cnt, _savelist); \
retT _ret; \
\
DelegateApi##para_cnt(FnType fn) : _fn(fn), _thread(0) {} \
DelegateApi##para_cnt(FnType fn, Raptor::Thread* thread) : _fn(fn), _thread(thread) {} \
\
retT operator()(Raptor::Thread* thread _isZero _VN(para_cnt, _paravarlist)) \
{ \
if (thread==NULL) return (retT)0; \
_VVN(para_cnt, _savetolist); \
thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
return _ret; \
} \
retT operator()( _VN(para_cnt, _paravarlist)) \
{ \
if (_thread==NULL) return (retT)0; \
_VVN(para_cnt, _savetolist); \
_thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
return _ret; \
} \
static LONG _callback(LPVOID data) \
{ \
theClass * pThis = (theClass*)data; \
pThis->_ret = pThis->_fn(_VN(para_cnt, _restorelist)); \
return 0; \
} \
}; \
/* 以下是返回类型为void时的特化模板 */ \
template<class T _isZero _VN(para_cnt, _templist)> \
class Delegate##para_cnt<T,void _isZero _VN(para_cnt, _templist)> \
{ \
typedef void (T::*FnType)(_VN(para_cnt, _paralist)); \
typedef Delegate##para_cnt<T, void _isZero _VN(para_cnt, _paralist)> theClass; \
public: \
Raptor::Thread* _thread; \
T* _this; \
FnType _fn; \
_VVN(para_cnt, _savelist); \
\
Delegate##para_cnt( FnType fn) : _fn(fn), _thread(0), _this(0) {} \
Delegate##para_cnt( FnType fn, Raptor::Thread* thread, T* obj) : _fn(fn), _thread(thread), _this(obj) {} \
\
void operator()(Raptor::Thread* thread, T* obj _isZero _VN(para_cnt, _paravarlist)) \
{ \
if (obj==NULL || thread==NULL) return; \
_this = obj; \
_VVN(para_cnt, _savetolist); \
thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
} \
void operator()( _VN(para_cnt, _paravarlist)) \
{ \
if (_this==NULL || _thread==NULL) return; \
_VVN(para_cnt, _savetolist); \
_thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
} \
static LONG _callback(LPVOID data) \
{ \
theClass * pThis = (theClass*)data; \
(pThis->_this->*pThis->_fn)(_VN(para_cnt, _restorelist)/*_VN(para_cnt, _callbacklist)*/); \
return 0; \
} \
}; \
template< _VN(para_cnt, _templist)> \
class DelegateApi##para_cnt<void _isZero _VN(para_cnt, _templist)> \
{ \
typedef void (WINAPI *FnType)(_VN(para_cnt, _paralist)); \
typedef DelegateApi##para_cnt<void _isZero _VN(para_cnt, _paralist)> theClass; \
public: \
Raptor::Thread* _thread; \
FnType _fn; \
_VVN(para_cnt, _savelist); \
\
DelegateApi##para_cnt(FnType fn) : _fn(fn), _thread(0) {} \
DelegateApi##para_cnt(FnType fn, Raptor::Thread* thread) : _fn(fn), _thread(thread) {} \
\
void operator()(Raptor::Thread* thread _isZero _VN(para_cnt, _paravarlist)) \
{ \
if (thread==NULL) return; \
_VVN(para_cnt, _savetolist); \
thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
} \
void operator()( _VN(para_cnt, _paravarlist)) \
{ \
if (_thread==NULL) return ; \
_VVN(para_cnt, _savetolist); \
_thread->AddTaskAndWait(ThreadTask::New(_callback, this)); \
} \
static LONG _callback(LPVOID data) \
{ \
theClass * pThis = (theClass*)data; \
pThis->_fn(_VN(para_cnt, _restorelist)); \
return 0; \
} \
};
//////////////////////////////////////////////////////////////////////////
// 委托类准备结束
//////////////////////////////////////////////////////////////////////////
#define Main_Thread() Raptor::Thread::MainThread()
#define HWND2Thread(hwnd) Raptor::Thread::FromHandle(hwnd)
//////////////////////////////////////////////////////////////////////////
/*
* 以下宏为ATL::CWindow的方法委托工具
*/
#define Dele_CWindow_DestroyWindow (Raptor::Delegate0<ATL::CWindow,BOOL>(&ATL::CWindow::DestroyWindow))
#define Dele_CWindow_SetFocus (Raptor::Delegate0<ATL::CWindow,HWND>(&ATL::CWindow::SetFocus))
// ATL::CWindow 委托工具宏结束
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/*
* 以下宏为 Window API 的函数委托工具
*/
#define DeleApi_SetFocus (Raptor::DelegateApi1<HWND,HWND>(&::SetFocus))
#define DeleApi_ShowWindow (Raptor::DelegateApi2<BOOL,HWND,int>(&::ShowWindow))
#define DeleApi_DestroyWindow (Raptor::DelegateApi1<BOOL,HWND>(&::DestroyWindow))
#define DeleApi_SetWindowPos (Raptor::DelegateApi7<BOOL,HWND,HWND,int,int,int,int,UINT>(&::SetWindowPos))
// API 委托结束
//////////////////////////////////////////////////////////////////////////
// class Delegate0<T, retT> and DelegateApi0<retT>
#define _isZero
DeclareDelegate(0)
#undef _isZero
// class Delegate1<T, retT, p1> and DelegateApi1<retT, p1>
#define _isZero ,
DeclareDelegate(1)
// class Delegate2<T, retT, p1, p2> and DelegateApi2<retT, p1, p2>
DeclareDelegate(2)
// class Delegate3<...> and DelegateApi3<...>
DeclareDelegate(3)
// class Delegate4<...> and DelegateApi4<...>
DeclareDelegate(4)
// class Delegate5<...> and DelegateApi5<...>
DeclareDelegate(5)
// class Delegate6<...> and DelegateApi6<...>
DeclareDelegate(6)
// class Delegate7<...> and DelegateApi7<...>
DeclareDelegate(7)
// class Delegate8<...> and DelegateApi8<...>
DeclareDelegate(8)
// class Delegate9<...> and DelegateApi9<...>
DeclareDelegate(9)