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)
对于最多几千人同时在线的通信应用,通常使用单台服务器就可以支撑.但是,当同时在线的用户数达到几万.几十万.甚至百万的时候,我们就需要很多的服务器来分担负载.但是,依据什么规则和结构来组织这些服务器,并 ...
随机推荐
- 【Qt开发】事件循环与线程 二
事件循环与线程 二 Qt 线程类 Qt对线程的支持已经有很多年了(发布于2000年九月22日的Qt2.2引入了QThread类),Qt 4.0版本的release则对其所有所支持平台默认地是对多线程支 ...
- Tomcat原理剖析
Tomcat原理学习 理解Tomcat工作原理 Tomcat的概念及启动原理浅析 Tomcat系统架构与设计模式
- Mysql 5.7存储过程的学习
存储过程:对sql的封装和重用,经编译创建并保存在数据库中,通过指定存储过程的名字并给定参数(需要时)来调用执行. 优缺点: (1) 优点: 执行速度快------存储过程只在创建时进行编译,以后每次 ...
- 秒懂Vuejs、Angular、React原理和前端发展历史
「前端程序发展的历史」 「 不学自知,不问自晓,古今行事,未之有也 」 我们都知道现在流行的框架:Vue.Js.AngularJs.ReactJs,已经逐渐应用到各个项目和实际应用中,它们都是MVVM ...
- jquery中的插件EChars的使用
首先,进入EChars的官网下载页面:http://echarts.baidu.com/download.html 下载自己需要的版本. 引入jquery包和echars,进入官网的实例:htt ...
- ModelForm操作
ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 labels=None, # 提示信 ...
- C/C++ 递归
递归 当一个函数调用它自己来定义时称它为递归函数.(什么叫它自己调用它自己呢?) 1.1.引出递归 从一个简单的问题考虑递归,求0,1,2, 3,4,5......n的和. 首先定义一个求和公式:su ...
- 解决Chrome浏览器无法自动播放音频视频的问题,Uncaught (in promise) DOMException
转载自:http://www.nooong.com/docs/chrome_video_autoplay.htm 在最新版的Chrome浏览器(以及所有以Chromium为内核的浏览器)中,已不再允许 ...
- 什么是CPC,CPA,CVR,CTR,ROI
合格的网络营销人员都应该熟悉下面的常见英文缩写,这些都是我们必须知道的名词解释:CVR (Click Value Rate): 转化率,衡量CPA广告效果的指标CTR (Click Through R ...
- UITableViewCell选中后子View背景色被Clear
在TableView中,当cell 处于Hightlighted(高亮)或者Selected(选中)状态下,Cell上的子控件的背景颜色会被 Clear. 解决方法:(4种) 1. 直接设置子控件的 ...