C++ 对象间通信框架 V2.0 ××××××× 之(三)

类定义: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 }


 
原文地址:https://www.cnblogs.com/Esperanto/p/5261106.html