注意中其中 指定了两个参数 1 2
@H_404_1@运行,在 点击closeItem 的时候,就会输出这两个事先指定的参数 1 2。
@H_404_1@那么,不事先指定的参数是在什么时候传入的呢?
@H_404_1@
voidMenuItem::activate()
- if(_enabled)
- if(_callback)
- _callback(this);
- }
- if(kScriptTypeNone!=_scriptType)
- {
- BasicScriptDatadata(this);
- ScriptEventscriptEvent(kMenuClickedEvent,&data);
- ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);
- }
- }
注意到其中的 _callback(this); 对了,这个时候就传入了 这个不事先指定的回调函数参数。
@H_404_1@这样,closeItem 的回调函数的void HelloWorld::menuCloseCallback(Object* pSender,int a,int b) 的三个参数都知道了。
@H_404_1@第一个 不事先指定,在menu item调用 activate 的时候,_callback(this) 传入,this 也即是这个 menu item;第二、三个参数是事先指定的 1,2。
@H_404_1@
@H_404_1@3、bind
@H_404_1@已经知道CC_CALLBACK_ 的宏定义是 std::bind 那么我们可以直接使用std::bind。
@H_404_1@如下:
@H_404_1@
std::bind(&HelloWorld::menuCloseCallback,2));
@H_404_1@4、function
@H_404_1@最后就解决上面的一个疑惑。
@H_404_1@
std::function<void(Object*)>func=std::bind(&HelloWorld::menuCloseCallback,2);
- autocloseItem=MenuItemImage::create(
- "CloseNormal.png",248)"> "CloseSelected.png",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> func);
5、使用lambda表达式
@H_404_1@
[&](Object*sender){
- });
可见使用lambda表达式可以极大的简化代码程序,不需要再定义一个回调函数,直接将在回调中的操作在闭包中体现即可。
@H_404_1@
@H_404_1@@H_404_6@二、在cocos2d-x中,还有一个地方是需要大量使用到回调函数的,这就是回调动作:CCCallFunc、CCCallFuncN、CCCallFuncND、CCCallFuncO。
@H_404_1@@H_404_6@但是这四个回调动作在 3.0 版本中已经都提示 deprecate 了。那么在3.0 版本中已经只剩下CallFunc 和 CallFuncN.
@H_404_1@下面是官方文档中的说明:
@H_404_1@
CallFunc
can be created with anstd::function<void()>
CallFuncN
can be created with anstd::function<void(Node*)>
CallFuncND
andCallFuncO
were removed since it can be created with simulated withCallFuncN
andCallFunc
. See ActionsTest.cpp for more examples
其中:CallFuncND 和 CallFuncO 都可以通过CallFunc 和 CallFuncN 进行实现。
@H_404_1@下面通过例子详细的介绍这两个回调动作的用法。
@H_404_1@1、CallFunc
staticCallFunc*create(conststd::function<void()>&func);
@H_404_1@关于CallFunc的例子,在文档中已经有体现:
@H_404_1@
//inv2.1
- CCCallFunc*action1=CCCallFunc::create(
- autoaction1=CallFunc::create(CC_CALLBACK_0(MyClass::callback_0,153); font-weight:bold; background-color:inherit">this));
- autoaction2=CallFunc::create(CC_CALLBACK_0(MyClass::callback_1,additional_parameters));
- //inv3.0(longversion)
- autoaction1=CallFunc::create(std::bind(&MyClass::callback_0,248)"> autoaction2=CallFunc::create(std::bind(&MyClass::callback_1,0); background-color:inherit">//inv3.0youcanalsouselambdasoranyother"Function"object
- autoaction1=CallFunc::create(
- [&](){
- autos=Director::sharedDirector()->getWinSize();
- autolabel=LabelTTF::create("called:lambdacallback","MarkerFelt",16);
- label->setPosition(ccp(s.width/4*1,s.height/2-40));
- this->addChild(label);
- });
@H_404_1@
@H_404_1@2、CallFuncN
@H_404_1@
staticCallFuncN*create(void(Node*)>&func);
@H_404_1@注意到该回调动作带有一个Node*参数。
@H_404_1@假设回调函数:
@H_404_1@
voidActionCallFuncN::callback(Node*sender)
@H_404_1@
autoaction=Sequence::create(
- MoveBy::create(2.0f,Point(150,0)),
- CallFuncN::create(CC_CALLBACK_1(ActionCallFuncN::callback,153); font-weight:bold; background-color:inherit">this)),248)"> NULL);
CallFuncN::create(std::bind(&ActionCallFuncN::callback,std::placeholders::_1)),160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit" rel="nofollow">
CallFuncN::create([&](Node*sender){
- //回调动作代码
- }),108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> NULL);
受益于C++11的新语法特性 std::bind ;
CallFuncND 和 CallFuncO 都可以通过
CallFunc 和 CallFuncN 进行实现
@H_404_1@3、CallFuncND :回调动作中带有一个Node*参数和一个void*参数
@H_404_1@实现过程类似于CallFuncN
@H_404_1@假设回调函数是 :void ActionCallFuncND::doRemoveFromParentAndCleanup(Node* sender,bool cleanup)
@H_404_1@那么在回调动作中:
@H_404_1@CallFuncN::create( CC_CALLBACK_1(ActionCallFuncND::doRemoveFromParentAndCleanup,this,true))
@H_404_1@@H_404_6@这样就实现了等价于CallFuncND 的回调动作。
@H_404_1@
@H_404_1@4、CallFuncO :回调动作中带有一个Object*参数
@H_404_1@实现过程类似于CallFunc
@H_404_1@假设回调函数是:void ActionCallFuncO::callback(Node* node,bool cleanup)
@H_404_1@那么在回调动作中:
@H_404_1@CallFunc::create( CC_CALLBACK_0(ActionCallFuncO::callback,_grossini,true)
@H_404_1@@H_404_6@这样就实现了等价于CallFuncO 的回调动作。
@H_404_1@
@H_404_1@三、总结
@H_404_1@在新版的回调处理中,采用了C++11中的 std::function 、std::bind 、lambda 表达式,使得回调的处理变得形式多样,代码灵活了,而其中的lambda表达式可以极大的简化回调代码,推荐使用。