C++ 对象间通信框架 V2.0 ××××××× 之(三)
类定义: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);
}
}
C++ 对象间通信框架 V2.0 ××××××× 之(三)的更多相关文章
- C++ 对象间通信框架 V2.0 ××××××× 之一
V2.0 主要是信号槽连接的索引性能做了改进,新设计了程序构架实现了多级分层索引,索引时间性能基本不受连接表的大小影响. 类定义:CSignalSlot C_MemberFuncPointer C_s ...
- C++ 对象间通信框架 V2.0 ××××××× 之(五)
类定义: ======================================================================= // MemberFuncPointer.h: ...
- C++ 对象间通信框架 V2.0 ××××××× 之(二)
公共头文件:ss_type_def.h ================================================================================ ...
- C++ 对象间通信框架 V2.0 ××××××× 之(四)
类定义:CMemberFuncPointer ======================================================================= // Me ...
- 文件断点续传原理与实现—— ESFramework 通信框架4.0 进阶(12)
在ESFramework通信框架 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍和ESFramework通信框架 4.0 快速上手(14) -- 聊天系统Demo,增加文件传送功能( ...
- C++对象间通信组件,让C++对象“无障碍交流”
介绍 这是很久之前的一个项目了,最近刚好有些时间,就来总结一下吧! 推荐初步熟悉项目后阅读本文: https://gitee.com/smalldyy/easy-msg-cpp 从何而来 这要从我从事 ...
- 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)
使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了, ...
- 接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]
基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版] by:授客 QQ:1033553122 由于篇幅问题,,暂且采用网盘分享的形式: 下载地址: [授客] ...
- ESPlatform 支持的三种群集模型 —— ESFramework通信框架 4.0 进阶(09)
对于最多几千人同时在线的通信应用,通常使用单台服务器就可以支撑.但是,当同时在线的用户数达到几万.几十万.甚至百万的时候,我们就需要很多的服务器来分担负载.但是,依据什么规则和结构来组织这些服务器,并 ...
随机推荐
- MSSQL注入--反弹注入
明明是sql注入的点,却无法进行注入,注射工具拆解的速度异常的缓慢,错误提示信息关闭,无法返回注入的结果,这个时候你便可以尝试使用反弹注入, 反弹注入需要依赖于函数opendatasource的支持, ...
- Windows.命令行(CMD)_执行命令&环境变量
1.CMD命令中如果 命令有换行的话,就使用 ^来连接(这就类似于 Linux命令行中 \ 的作用) 2.环境变量 2.1.显示 所有环境变量的值,命令:set 2.2.显示 某个环境变量的值,命令 ...
- Golang中的error类型
Golang中的error类型 error类型本身就是一个预定义好的接口,里面定义了一个method type error interface { Error() string } 生成一个新的err ...
- IDEA中解决 git pull 冲突
0.事先准备.1)把远程仓库的README.md内容改写为bbb(原先为aaa). 2)本地仓库的README.md内容改写为ccc(原先也为aaa). 以此来模仿代码冲突. 1.先commit ...
- Linux搜索文件
1.7.1 使用which 查找可执行文件的绝对路径 ·只能用来查找PATH环境变量中出现的路径下的可执行文件 1.7.2 使用whereis 查找文件 ·通过预先生成的一个文件列表库查找与给出文件名 ...
- 杭州集训Day5
下面是Day5的题目!(其实都咕了好几天了 100+70+40=210. T1 皇后 XY 的疑难 (1s 512MB) 1.1 题目描述 有一个n*n的王国城堡地图上,皇后XY喜欢看骑士之间的战斗, ...
- GmSSL Build with VS2017
使用背景: 最近研究GB35114, 有关于sip协议部分,exosip的已经编译过,由于gb3511中采用的是国密算法,因此这里记录一下GMSSL在windows下的编译过程以及遇到的错误 详细GM ...
- 搜索专题: HDU1242 Rescue
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- Python和Js打印心形
看到一行Python写的代码,会用LovePython输出心形: print('\n'.join([''.join([('LovePython'[(x-y)%10]if((x*0.05)**2+(y* ...
- 批处理遍历文件夹执行git pull
echo off & color 0A for /d %%f in (D:\www\*) do ( D: cd %%f chdir git pull ) pause 遍历D:\www\这个文件 ...