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)
对于最多几千人同时在线的通信应用,通常使用单台服务器就可以支撑.但是,当同时在线的用户数达到几万.几十万.甚至百万的时候,我们就需要很多的服务器来分担负载.但是,依据什么规则和结构来组织这些服务器,并 ...
随机推荐
- Mac021--编辑软件
一.思维导图MindNode 知乎Mac常用的思维导图:https://zhuanlan.zhihu.com/p/37768277 MindNode下载地址:https://macblcom.ctfi ...
- django 的 三个 时间 字段
- 如何在centos7中显示/etc/目录下以非字母开头,后面跟了一个字母及其它任意字符的文件或目录
ls /etc |grep "^[^[:alpha:]][[:alpha:]].*"
- sql limit order by and where
1 sql limit limit size,返回前size行. limit offset , size,返回offset开始的size行,offset从0行开始. 2 sql limit with ...
- C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)(转)
C#打印条码BarTender SDK打印之路和离开之路(web平凡之路) 从来没想过自己会写一篇博客,鉴于这次从未知的探索到一个个难点的攻破再到顺利打印,很想记录这些点滴,让后人少走弯路. 下面走进 ...
- JS跨域--window.name
JS跨域--window.name:https://www.jianshu.com/p/43ff69d076e3
- windows上安装 包管理工具choco及scoop
1.安装 choco: 1.1.使用管理员方式打开 PowerShell 1.2.输入 Set-ExecutionPolicy RemoteSigned,输入 Y 1.3.安装 choco输入:iwr ...
- PHP 中一个 False 引发的问题,差点让公司损失一百万
PHP 中一个 False 引发的问题,差点让公司损失一百万 一.场景描述 上周我一个在金融公司的同学,他在线上写一个 Bug,差点造成公司损失百万.幸好他及时发现了这个问题并修复了.这是一个由 PH ...
- 分布式事务——幂等设计(rocketmq案例)
幂等指的就是执行多次和执行一次的效果相同,主要是为了防止数据重复消费.MQ中为了保证消息的可靠性,生产者发送消息失败(例如网络超时)会触发 "重试机制",它不是生产者重试而是MQ自 ...
- C#设计模式:解释器模式(Interpreter Pattern)
一,C#设计模式:解释器模式(Interpreter Pattern) 1,解释器模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易 ...