类定义:CSignalSlot
=======================================================================
1 // SignalSlot.h: interface for the CSignalSlot class. 2 // 3 // 4 5 #if !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_) 6 #define AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_ 7 8 #include <Afxtempl.h> 9 #include "MemberFuncPointer.h" 10 #include "_ss_signal_item.h" 11 #include "ss_type_def.h" 12 13 #if _MSC_VER > 1000 14 #pragma once 15 #endif // _MSC_VER > 1000 16 17 //blog.csdn.net/hairetz/article/details/4153252 //成员函数指针文章 18 //http://www.docin.com/p-862983384.html //QT信号操机制研究 19 20 //-------------------------------------------------------------------------------------------- 21 22 /* 23 宏定义1: 信号槽类注册 24 说明: 信号槽(接收方)类定义需要使用该宏声明 25 在类定义最开始位置声明,结尾不需要冒号。例子如下所示: 26 class CTest 27 { 28 SS_REGISTER(CTest) 29 public: 30 ... 31 } 32 33 参数: ClassName 为类名称 34 宏展开: 定义了一个公有静态函数: 35 SS_STATIC_SLOT: 函数名称 36 pSelf: 类对象指针 37 slot_F: 槽函数ID (成员函数指针转换得到) 38 pSrc: 信号发送方输入参数void通用指针 39 pDes: 返回参数内存指针(由调用方提供) 40 */ 41 #define SS_REGISTER(ClassName) \ 42 public: static int _SS_STATIC_SLOT_(void *pSelf,CMemberFuncPointer slot_F,void *pSrc,void *pDes)\ 43 {\ 44 int(ClassName::*SLOTFUNC)(void*pSrc,void*pDes=NULL);\ 45 slot_F.Get(&SLOTFUNC);\ 46 int res = (((ClassName*)(pSelf))->*SLOTFUNC)(pSrc,pDes);\ 47 return res;\ 48 } 49 50 // 宏定义2: 信号函数定义 51 #define SS_SIGNAL(ClassName,FuncName) \ 52 int FuncName(void*pSrc,void*pDes=NULL)\ 53 {\ 54 int(ClassName::*SLOTFUNC)(void*,void*)=&ClassName::FuncName;\ 55 CMemberFuncPointer MFP;\ 56 MFP.Set(&SLOTFUNC,sizeof(SLOTFUNC));\ 57 return CSignalSlot::SignalSS(this,MFP,pSrc,pDes);\ 58 } 59 60 61 // 宏定义3: 连接功能函数 62 #define SS_CONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \ 63 {\ 64 int(signalClassName::*SIGNAL_PF)(void*,void*) = &signalClassName::signalFunc;\ 65 int(slotClassName::*SLOT_PF)(void*,void*) = &slotClassName::slotFunc;\ 66 CMemberFuncPointer signal_F(&SIGNAL_PF,sizeof(SIGNAL_PF));\ 67 CMemberFuncPointer slot_F(&SLOT_PF,sizeof(SLOT_PF));\ 68 *res = CSignalSlot::ConnectSS(signalSelf,signal_F,slotSelf,slot_F,slotClassName::_SS_STATIC_SLOT_);\ 69 } 70 71 // 宏定义4: 断开功能连接 72 #define SS_DISCONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \ 73 {\ 74 int(signalClassName::*SIGNAL_PF)(void*,void*) = &signalClassName::signalFunc;\ 75 int(slotClassName::*SLOT_PF)(void*,void*) = &slotClassName::slotFunc;\ 76 CMemberFuncPointer signal_F(&SIGNAL_PF,sizeof(SIGNAL_PF));\ 77 CMemberFuncPointer slot_F(&SLOT_PF,sizeof(SLOT_PF));\ 78 *res = CSignalSlot::DisConnectSS(signalSelf,signal_F,slotSelf,slot_F);\ 79 } 80 81 //------------------------------------------------------------------------------------------------------------------------------ 82 83 class CSignalSlot 84 { 85 public: 86 static int DisConnectSS(void* signal_pSelf,CMemberFuncPointer signal_F,void* slot_pSelf,CMemberFuncPointer slot_F); 87 static int CloseSS(void *signal_pSelf,void*slot_pSelf); 88 static int SignalSS(void *signal_pSelf,CMemberFuncPointer signal_F,void *pSrc,void *pDes=NULL); 89 static int ConnectSS(void* signal_pSelf,CMemberFuncPointer &signal_F,void* slot_pSelf,CMemberFuncPointer &slot_F,SS_STAIC_SLOTFUNC slot_pFunc); 90 CSignalSlot(); 91 virtual ~CSignalSlot(); 92 private: 93 static void CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray); 94 static CArray<SSItem,SSItem>m_SSArray; 95 static int m_loopback; 96 97 static CArray<C_ss_signal_item*,C_ss_signal_item*>m_CsiArray; 98 }; 99 100 #endif // !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_)
1 // SignalSlot.cpp: implementation of the CSignalSlot class. 2 // 3 // 4 5 #include "stdafx.h" 6 #include "SignalSlot.h" 7 8 #ifdef _DEBUG 9 #undef THIS_FILE 10 static char THIS_FILE[]=__FILE__; 11 #define new DEBUG_NEW 12 #endif 13 14 // 15 // Construction/Destruction 16 // 17 CArray<SSItem,SSItem> CSignalSlot::m_SSArray; 18 int CSignalSlot::m_loopback = 0; 19 CArray<C_ss_signal_item*,C_ss_signal_item*>CSignalSlot::m_CsiArray; 20 21 CSignalSlot::CSignalSlot() 22 { 23 24 } 25 26 CSignalSlot::~CSignalSlot() 27 { 28 29 } 30 31 // 信号|槽连接: <signal对象+成员函数ID,slot对象+成员函数>作为一个连接项 32 // 返回值:1:成功 0:已存在该连接项 -1:添加失败 33 int CSignalSlot::ConnectSS(void* signal_pSelf,CMemberFuncPointer &signal_F,void* slot_pSelf,CMemberFuncPointer &slot_F,SS_STAIC_SLOTFUNC slot_pFunc) 34 { 35 int len = CSignalSlot::m_CsiArray.GetSize(); 36 C_ss_signal_item *pTemp = NULL; 37 for(int i=0;i<len;i++) 38 { 39 pTemp = CSignalSlot::m_CsiArray.GetAt(i); 40 if(pTemp->Get_signalSelf()==signal_pSelf) 41 { 42 return pTemp->Add(signal_F,slot_pSelf,slot_F,slot_pFunc); 43 } 44 } 45 46 pTemp = new C_ss_signal_item; 47 pTemp->Set_signalSelf(signal_pSelf); 48 49 if(1==pTemp->Add(signal_F,slot_pSelf,slot_F,slot_pFunc)) 50 { 51 CSignalSlot::m_CsiArray.Add(pTemp); 52 return 1; 53 } 54 55 delete pTemp; 56 return -1; 57 } 58 59 // 返回值: 调用槽的执行数目(每调用一个槽函数,返回值加1) 60 int CSignalSlot::SignalSS(void *signal_pSelf,CMemberFuncPointer signal_F,void *pSrc, void *pDes) 61 { 62 int res = 0; 63 int len = CSignalSlot::m_CsiArray.GetSize(); 64 C_ss_signal_item *p_signal_item; 65 for(int i=0;i<len;i++) 66 { 67 p_signal_item = CSignalSlot::m_CsiArray.GetAt(i); 68 if(p_signal_item->Get_signalSelf()==signal_pSelf) 69 { 70 res = p_signal_item->Signal(signal_F,pSrc,pDes); 71 return res; 72 } 73 } 74 75 return res; 76 } 77 78 // 关闭删除对象连接(单向) 79 // 返回值:>0 成功 0 已不存在该连接 -1 删除失败 80 int CSignalSlot::CloseSS(void *signal_pSelf, void *slot_pSelf) 81 { 82 int len = CSignalSlot::m_SSArray.GetSize(); 83 SSItem sItem; 84 int res = 0; 85 for(int i=0;i<len;i++) 86 { 87 sItem = CSignalSlot::m_SSArray.GetAt(i); 88 if(false==sItem.is_use) 89 { 90 continue; 91 } 92 if(NULL==signal_pSelf) 93 { 94 if(slot_pSelf==sItem.slot_pSelf) 95 { 96 sItem.is_use = false; 97 CSignalSlot::CloseFuncArray(sItem.pFuncArray); 98 res+=1; 99 } 100 }else if(NULL==slot_pSelf) 101 { 102 if(signal_pSelf==sItem.signal_pSelf) 103 { 104 sItem.is_use = false; 105 CSignalSlot::CloseFuncArray(sItem.pFuncArray); 106 res+=1; 107 } 108 }else if(signal_pSelf==sItem.signal_pSelf && slot_pSelf==sItem.slot_pSelf) 109 { 110 sItem.is_use = false; 111 CSignalSlot::CloseFuncArray(sItem.pFuncArray); 112 res+=1; 113 break; 114 } 115 } 116 return res; 117 } 118 119 120 // 删除信号槽连接 121 // 返回值:1 成功 0 已不存在该连接 -1 删除失败 122 int CSignalSlot::DisConnectSS(void *signal_pSelf, CMemberFuncPointer signal_F, void *slot_pSelf, CMemberFuncPointer slot_F) 123 { 124 int len = CSignalSlot::m_CsiArray.GetSize(); 125 C_ss_signal_item *pTemp = NULL; 126 for(int i=0;i<len;i++) 127 { 128 pTemp = CSignalSlot::m_CsiArray.GetAt(i); 129 if(pTemp->Get_signalSelf()==signal_pSelf) 130 { 131 return pTemp->DisConnectSS(signal_F,slot_pSelf,slot_F); 132 } 133 } 134 return 0; 135 } 136 137 138 void CSignalSlot::CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray) 139 { 140 int sum = pFuncArray->GetSize(); 141 FuncItem item; 142 for(int k=0;k<sum;k++) 143 { 144 item = pFuncArray->GetAt(k); 145 item.is_use = false; 146 pFuncArray->SetAt(k,item); 147 } 148 }