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)
对于最多几千人同时在线的通信应用,通常使用单台服务器就可以支撑.但是,当同时在线的用户数达到几万.几十万.甚至百万的时候,我们就需要很多的服务器来分担负载.但是,依据什么规则和结构来组织这些服务器,并 ...
随机推荐
- angulart 常用
angular: 使用 echarts npm install echarts --save // 安装declare const echarts: any; // 引入https://www.ech ...
- java基础笔记(10)
Html:载体 CSS:样式 JavaScript:特效 html: 1. <html></html>称为根标签,所有的网页标签都在<html>< ...
- python中输入某年某月某日,判断这一天是这一年的第几天?
输入某年某月某日,判断这一天是这一年的第几天?程序分析 特殊情况,闰年时需考虑二月多加一天: 直接上代码 #定义一个函数,判断是否为闰年 def leapyear(y): return (y % 40 ...
- pureftp安装
1.下载 #cd /usr/local/src #wget http://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.36.t ...
- Java创建二叉树
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/yeweiouyang/article/details/37814461 二叉树的值保存在数组中,以0 ...
- 线性渐变css
从上到下的线性渐变: #grad { background: -webkit-linear-gradient(red, blue); /* Safari 5.1 - 6.0 */ background ...
- 前端校招知识体系之HTML5
啥是HTML5?官方说HTML5 是下一代的 HTML... 本文主要介绍HTML5三个方面的知识,继续往下看看吧. 语义化标签 canvas&svg 响应式meta 一.语义化标签 语义化标 ...
- Tomcat编译jsp生成Servlet文件的存放位置
转自:http://www.cnblogs.com/Leon5/archive/2010/12/07/1899300.html Tomcat将jsp编译成servlet后的文件存放在\work\Cat ...
- 神经网络中的反向传播法--bp【转载】
from: 作者:Charlotte77 出处:http://www.cnblogs.com/charlotte77/ 一文弄懂神经网络中的反向传播法——BackPropagation 最近在看深度学 ...
- SPSS 23下载安装和激活
目录 1. 其他版本 2. 安装教程 3. 下载地址 1. 其他版本 参考:https://www.cnblogs.com/coco56/p/11648399.html 2. 安装教程 SPSS 23 ...