【cocos2d-x IOS游戏开发-捕鱼达人5】C++中函数代理与信号插槽机制

原创 2013年12月05日 15:07:57

尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17141275


上节回顾

【cocos2d-x IOS游戏开发-捕鱼达人4】基本游戏框架


1、函数代理与C++实现

什么是函数代理(function delegate)
函数代理是一种对象,它能模拟函数的使用方式。并且它可以使调用者不用关心回调函数的类型

回调函数类型
       全局函数
       静态成员函数
       成员函数

C++中的函数代理
C++中没有原生的函数代理类型,必须要自己实现。

实现方式
模板
使用方式
delegate<void(int,int,CCObject*)> m_delegate;
m_delegate(0,0,NULL);


2、信号插槽机制

signal/slot
       在qt、boost等库中有相关实现。
开源的库
        FastDelegate
        sigslot

我们的方案
将delegate封装,使其可以支持多个delegate监听


来看具体的实现:

#ifndef __SINGAL_SLOT_H__
#define __SINGAL_SLOT_H__

#include <vector>
namespace fishingjoy
{
	namespace base
	{
		//===============delegate==================
		//使用模版封装代理
		template<typename T>
		struct Delegate{};


		//void param.
		template<>
		struct Delegate<void(void)>
		{
			typedef Delegate<void(void)> SELF_CLASS;
			typedef void (SELF_CLASS::*CALL_BACK_FN)();
			typedef void (*GENERIC_CALL_BACK_FN)();
			SELF_CLASS* m_pThis;
			union{
				CALL_BACK_FN m_pMemberCallback;
				GENERIC_CALL_BACK_FN m_pGenericCallback;
			};
			

			Delegate()
				:m_pThis(NULL)
				,m_pMemberCallback(NULL)
			{

			}
			
			//使用方式base::Delegate<void(void)> testd(this,&CGameLogic::shutdown);然后会在operator()函数中执行testd
			template<typename X>
			Delegate(X* pThis,void(X::*pCallback)())
			{
				this->m_pThis = (SELF_CLASS*)pThis;
				this->m_pMemberCallback = (CALL_BACK_FN)pCallback;
			}

			Delegate(void (*Callback)())
			{
				m_pThis = NULL;
				m_pGenericCallback = Callback;
			}

		public:
			void operator()()
			{
				if(m_pThis!=NULL&& this->m_pMemberCallback!=NULL)
				{
					(m_pThis->*m_pMemberCallback)();
				}
				else if(m_pThis==NULL){
					if(m_pGenericCallback!=NULL)
						m_pGenericCallback();
				}
			}
		};


		//=================signal===========================
		template<typename T>
		struct Signal{};

		template<>
		struct Signal<void(void)>
		{
			std::vector<Delegate<void(void)> > m_Slots;

			void operator()()
			{
				size_t t = m_Slots.size();
				for(size_t i = 0; i < t; ++i){
					Delegate<void(void)>& d = m_Slots[i];
					d();
				}
			}

			void operator +=(const Delegate<void(void)>& d)
			{
				m_Slots.push_back(d);
			}
		};
	}
}
#endif

使用方式:

#ifndef _GAME_LOGIC_H_
#define _GAME_LOGIC_H_
#include "cocos2d.h"
USING_NS_CC;

#include "../include/IGameScene.h"
#include "../include/SignalSlot.h"
namespace fishingjoy
{
	namespace logic
	{
		class CGameLogic:public cocos2d::CCObject
		{
			scene::IGameScene* m_pGameScene;
		public:
			//override base class.
			void update(float dt)
			{
				if(m_pGameScene)
					m_pGameScene->update(dt);
			}

		public:
			bool init(CCScene* pScene)
			{
				//会去执行CGameLogic::shutdown函数,结束导演的执行
				base::Delegate<void(void)> testd(this,&CGameLogic::shutdown);
				testd();

				base::Signal<void(void)> s;
				s+=testd;
				s();

				if(pScene==NULL)
					return false;
				m_pGameScene = scene::createScene();
				if(m_pGameScene==NULL)
					return false;

				m_pGameScene->attachTo(pScene);
				return true;
			}
			void shutdown()
			{
				//to do..

				//exit.
				CCDirector::sharedDirector()->end();
			}
		};
	}
}
#endif

在去执行:

	static CCScene* pScene = CCScene::create();
	if(GGameLogic.init(pScene)==false)
		return false;
	pDirector->getScheduler()->scheduleUpdateForTarget(&GGameLogic,0,false);
  
	// run
	pDirector->runWithScene(pScene);

会看到程序跑起来,然后自己结束了;

shutdown函数执行了两次

log信息显示为:

?operator:fishingjoy::base::Delegate<void __cdecl(void)>::operator ()
?н:fishingjoy::logic::CGameLogic::shutdown
?operator:fishingjoy::base::Delegate<void __cdecl(void)>::operator ()
?н:fishingjoy::logic::CGameLogic::shutdown

大家可以将delegate与cocos2d-x中的menu_selector等实现对比一下,看看各自的优劣。
还可以尝试自己扩展带参的delegate和signal。

深入理解信号槽机制

深入理解信号槽(一) 这篇文章来自于 A Deeper Look at Signals and Slots,Scott Collins 2005.12.19。需要说明的是,我们这里所说的...
  • liuuze5
  • liuuze5
  • 2016年12月08日 20:00
  • 2116

用标准C++实现信号与槽机制

原文链接:http://blog.csdn.net/ilvu999/article/details/7948429 用标准C++实现信号与槽机制 信号对象保存参数,以及槽对象列表....
  • yuanhubilie
  • yuanhubilie
  • 2013年04月06日 22:42
  • 2162

信号和槽机制

QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点。 更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 Q...
  • u014066037
  • u014066037
  • 2016年10月31日 16:25
  • 906

信号与槽机制

 QT 的信号与槽机制介绍 信号与槽作为 QT 的核心机制在 QT 编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念、元对象工具以及在实际使用过程中应注意的一些问题。 ...
  • Acheld
  • Acheld
  • 2016年07月31日 13:14
  • 2236

Qt信号与槽实现原理

有网友抱怨: 哪个大牛能帮帮我,讲解一下信号槽机制的底层实现? 不要那种源码的解析,只要清楚的讲讲是怎么发送信号,怎么去选择相应的槽,再做出反应。也就是类似于一个信号槽的相应流程。。。求解啊!!! 看...
  • fuyunzhishang1
  • fuyunzhishang1
  • 2015年09月10日 16:37
  • 9541

从零开始实现信号槽机制:一

我们从一个具体的问题入手:“现在有一堆按钮,用来控制一堆电器,它们之间可能是一对多,也可能是多对一,如何设计这个结构?”这里有个形象的图:为了实现组件间的控制,我们很容易想到“回调函数”,对于C++开...
  • u011348999
  • u011348999
  • 2015年09月04日 13:49
  • 4016

iOS系统GCD学习(5):信号量机制

当我们在处理一系列线程的时候,当数量达到一定量,在以前我们可能会选择使用NSOperationQueue来处理并发控制,但如何在GCD中快速的控制并发呢?答案就是dispatch_semaphore,...
  • lusonglin121
  • lusonglin121
  • 2013年06月04日 10:26
  • 2984

Qt学习心得——信号与槽的认识1

Qt学习心得——信号与槽的认识1       信号与槽的主要实现的功能是对界面中按钮进行定义,比如主界面中有个按钮pushbutton,并设置其显现名称为“计算”,那需要定义一个当这个按钮被点击时的功...
  • wwoll
  • wwoll
  • 2016年10月24日 13:00
  • 388

iOS 开发中的消息机制-代理、通知、block

http://blog.csdn.net/italianshen
  • italianshen
  • italianshen
  • 2016年05月03日 22:45
  • 682

关于c/c++中信号传送数据函数sigqueue的认识

最近学习unix系统信号时候遇到了函数sigqueue函数,网上看了看一切前辈写的感觉思路挺清晰的,但是自我感觉理解不是很清楚,我就在这唠叨两句,留着以后复习用。(用的是ubuntu14.04系统测试...
  • good1st
  • good1st
  • 2015年01月10日 22:47
  • 442
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【cocos2d-x IOS游戏开发-捕鱼达人5】C++中函数代理与信号插槽机制
举报原因:
原因补充:

(最多只允许输入30个字)