类定义:CSignalSlot

=======================================================================

 // SignalSlot.h: interface for the CSignalSlot class.
//
////////////////////////////////////////////////////////////////////// #if !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_)
#define AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_ #include <Afxtempl.h>
#include "MemberFuncPointer.h"
#include "_ss_signal_item.h"
#include "ss_type_def.h" #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 //blog.csdn.net/hairetz/article/details/4153252 //成员函数指针文章
//http://www.docin.com/p-862983384.html //QT信号操机制研究 //-------------------------------------------------------------------------------------------- /*
宏定义1: 信号槽类注册
说明: 信号槽(接收方)类定义需要使用该宏声明
在类定义最开始位置声明,结尾不需要冒号。例子如下所示:
class CTest
{
SS_REGISTER(CTest)
public:
...
} 参数: ClassName 为类名称
宏展开: 定义了一个公有静态函数:
SS_STATIC_SLOT: 函数名称
pSelf: 类对象指针
slot_F: 槽函数ID (成员函数指针转换得到)
pSrc: 信号发送方输入参数void通用指针
pDes: 返回参数内存指针(由调用方提供)
*/
#define SS_REGISTER(ClassName) \
public: static int _SS_STATIC_SLOT_(void *pSelf,CMemberFuncPointer slot_F,void *pSrc,void *pDes)\
{\
int(ClassName::*SLOTFUNC)(void*pSrc,void*pDes=NULL);\
slot_F.Get(&SLOTFUNC);\
int res = (((ClassName*)(pSelf))->*SLOTFUNC)(pSrc,pDes);\
return res;\
} // 宏定义2: 信号函数定义
#define SS_SIGNAL(ClassName,FuncName) \
int FuncName(void*pSrc,void*pDes=NULL)\
{\
int(ClassName::*SLOTFUNC)(void*,void*)=&ClassName::FuncName;\
CMemberFuncPointer MFP;\
MFP.Set(&SLOTFUNC,sizeof(SLOTFUNC));\
return CSignalSlot::SignalSS(this,MFP,pSrc,pDes);\
} // 宏定义3: 连接功能函数
#define SS_CONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \
{\
int(signalClassName::*SIGNAL_PF)(void*,void*) = &signalClassName::signalFunc;\
int(slotClassName::*SLOT_PF)(void*,void*) = &slotClassName::slotFunc;\
CMemberFuncPointer signal_F(&SIGNAL_PF,sizeof(SIGNAL_PF));\
CMemberFuncPointer slot_F(&SLOT_PF,sizeof(SLOT_PF));\
*res = CSignalSlot::ConnectSS(signalSelf,signal_F,slotSelf,slot_F,slotClassName::_SS_STATIC_SLOT_);\
} // 宏定义4: 断开功能连接
#define SS_DISCONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \
{\
int(signalClassName::*SIGNAL_PF)(void*,void*) = &signalClassName::signalFunc;\
int(slotClassName::*SLOT_PF)(void*,void*) = &slotClassName::slotFunc;\
CMemberFuncPointer signal_F(&SIGNAL_PF,sizeof(SIGNAL_PF));\
CMemberFuncPointer slot_F(&SLOT_PF,sizeof(SLOT_PF));\
*res = CSignalSlot::DisConnectSS(signalSelf,signal_F,slotSelf,slot_F);\
} //------------------------------------------------------------------------------------------------------------------------------ class CSignalSlot
{
public:
static int DisConnectSS(void* signal_pSelf,CMemberFuncPointer signal_F,void* slot_pSelf,CMemberFuncPointer slot_F);
static int CloseSS(void *signal_pSelf,void*slot_pSelf);
static int SignalSS(void *signal_pSelf,CMemberFuncPointer signal_F,void *pSrc,void *pDes=NULL);
static int ConnectSS(void* signal_pSelf,CMemberFuncPointer &signal_F,void* slot_pSelf,CMemberFuncPointer &slot_F,SS_STAIC_SLOTFUNC slot_pFunc);
CSignalSlot();
virtual ~CSignalSlot();
private:
static void CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray);
static CArray<SSItem,SSItem>m_SSArray;
static int m_loopback; static CArray<C_ss_signal_item*,C_ss_signal_item*>m_CsiArray;
}; #endif // !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_)
 // SignalSlot.cpp: implementation of the CSignalSlot class.
//
////////////////////////////////////////////////////////////////////// #include "stdafx.h"
#include "SignalSlot.h" #ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif //////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CArray<SSItem,SSItem> CSignalSlot::m_SSArray;
int CSignalSlot::m_loopback = ;
CArray<C_ss_signal_item*,C_ss_signal_item*>CSignalSlot::m_CsiArray; CSignalSlot::CSignalSlot()
{ } CSignalSlot::~CSignalSlot()
{ } // 信号|槽连接: <signal对象+成员函数ID,slot对象+成员函数>作为一个连接项
// 返回值:1:成功 0:已存在该连接项 -1:添加失败
int CSignalSlot::ConnectSS(void* signal_pSelf,CMemberFuncPointer &signal_F,void* slot_pSelf,CMemberFuncPointer &slot_F,SS_STAIC_SLOTFUNC slot_pFunc)
{
int len = CSignalSlot::m_CsiArray.GetSize();
C_ss_signal_item *pTemp = NULL;
for(int i=;i<len;i++)
{
pTemp = CSignalSlot::m_CsiArray.GetAt(i);
if(pTemp->Get_signalSelf()==signal_pSelf)
{
return pTemp->Add(signal_F,slot_pSelf,slot_F,slot_pFunc);
}
} pTemp = new C_ss_signal_item;
pTemp->Set_signalSelf(signal_pSelf); if(==pTemp->Add(signal_F,slot_pSelf,slot_F,slot_pFunc))
{
CSignalSlot::m_CsiArray.Add(pTemp);
return ;
} delete pTemp;
return -;
} // 返回值: 调用槽的执行数目(每调用一个槽函数,返回值加1)
int CSignalSlot::SignalSS(void *signal_pSelf,CMemberFuncPointer signal_F,void *pSrc, void *pDes)
{
int res = ;
int len = CSignalSlot::m_CsiArray.GetSize();
C_ss_signal_item *p_signal_item;
for(int i=;i<len;i++)
{
p_signal_item = CSignalSlot::m_CsiArray.GetAt(i);
if(p_signal_item->Get_signalSelf()==signal_pSelf)
{
res = p_signal_item->Signal(signal_F,pSrc,pDes);
return res;
}
} return res;
} // 关闭删除对象连接(单向)
// 返回值:>0 成功 0 已不存在该连接 -1 删除失败
int CSignalSlot::CloseSS(void *signal_pSelf, void *slot_pSelf)
{
int len = CSignalSlot::m_SSArray.GetSize();
SSItem sItem;
int res = ;
for(int i=;i<len;i++)
{
sItem = CSignalSlot::m_SSArray.GetAt(i);
if(false==sItem.is_use)
{
continue;
}
if(NULL==signal_pSelf)
{
if(slot_pSelf==sItem.slot_pSelf)
{
sItem.is_use = false;
CSignalSlot::CloseFuncArray(sItem.pFuncArray);
res+=;
}
}else if(NULL==slot_pSelf)
{
if(signal_pSelf==sItem.signal_pSelf)
{
sItem.is_use = false;
CSignalSlot::CloseFuncArray(sItem.pFuncArray);
res+=;
}
}else if(signal_pSelf==sItem.signal_pSelf && slot_pSelf==sItem.slot_pSelf)
{
sItem.is_use = false;
CSignalSlot::CloseFuncArray(sItem.pFuncArray);
res+=;
break;
}
}
return res;
} // 删除信号槽连接
// 返回值:1 成功 0 已不存在该连接 -1 删除失败
int CSignalSlot::DisConnectSS(void *signal_pSelf, CMemberFuncPointer signal_F, void *slot_pSelf, CMemberFuncPointer slot_F)
{
int len = CSignalSlot::m_CsiArray.GetSize();
C_ss_signal_item *pTemp = NULL;
for(int i=;i<len;i++)
{
pTemp = CSignalSlot::m_CsiArray.GetAt(i);
if(pTemp->Get_signalSelf()==signal_pSelf)
{
return pTemp->DisConnectSS(signal_F,slot_pSelf,slot_F);
}
}
return ;
} void CSignalSlot::CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray)
{
int sum = pFuncArray->GetSize();
FuncItem item;
for(int k=;k<sum;k++)
{
item = pFuncArray->GetAt(k);
item.is_use = false;
pFuncArray->SetAt(k,item);
}
}
 
05-11 22:04