2dx CC_CALLBACK1选择器

本文介绍Cocos2d-x中动作回调机制的变化,从早期版本的多个回调函数简化为使用C++11的可变参数模板特性后的CC_CALLBACK_1宏。展示了如何传递不同数量和类型的参数,并给出具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ocos2dx  3.0 之前。 


cocos2dx 提供了三个函数

[cpp]  view plain copy
  1. CCCallFunc::actionWithTarget(this,callfunc_selector(MyClass::callBackAnim));    
  2.   
  3. CCCallFuncND::actionWithTarget(this, callfuncND_selector(MyClass::callBackAnim), (void*)mInt);  
  4.   
  5. CCCallFuncND::actionWithTarget(this, callfuncND_selector(MyClass::callBackAnim));  


他们分别可以传递0个参数,1个参数,传递自身节点。


而在c++ 11 可变参数模版这个特性出来后。  他们被简化掉了成一个函数。。


下面这个方法是Sample中提供的传递自身的方法。调用CC_CALLBACK_1来实现。

[cpp]  view plain copy
  1.    
  2. grossini->runAction( Sequence::create(   
  3.                                                 MoveBy::create(1, Point(150,0)),  
  4.                                                 CallFuncN::create(CC_CALLBACK_1(LogicTest::bugMe,this)),  
  5.                                                 NULL)   
  6.                         );  
  7.   
  8. void LogicTest::bugMe(Node* node)  
  9. {  
  10.     node->stopAllActions(); //After this stop next action not working, if remove this stop everything is working  
  11.     node->runAction(ScaleTo::create(2, 2));  
  12. }  


这里是CC_CALLBACK_1的定义

[cpp]  view plain copy
  1. #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)  


##__VA_ARGS  是表示可变参数


然后如果你想传递多个参数。 你可以这么使用


[cpp]  view plain copy
  1.      Object *arg1;  
  2.      Node *arg2;  
  3.      Sprite *arg3;  
  4.      grossini->runAction( Sequence::create(   
  5.                                                 MoveBy::create(1, Point(150,0)),  
  6.                                                 CallFuncN::create(CC_CALLBACK_1(LogicTest::bugMe,this,arg1,arg2,arg3)),  
  7.                                                 NULL)   
  8.                         );  
  9.   
  10.   
  11. void LogicTest::bugMe(Node* node,Object * arg1,Object * arg2, Sprite* arg3)  
  12. {  
  13.     //(Node *)arg2  
  14.       
  15.     node->stopAllActions(); //After this stop next action not working, if remove this stop everything is working  
  16.     node->runAction(ScaleTo::create(2, 2));  
  17. }  


但在调用CC_CALLBACK_1时, this指针是必须的。。


我们可以看到。。它总共传递了4个参数。 自身节点,对象1,  以及可以向上转型的Object 对象,  以及精灵对象 arg3


可变参数模版让一切都变的简单了。。

<think>嗯,用户的问题是关于两个回调函数,connection_callback和data_callback,其中data_callback没有在main函数里注册,而是由connection_callback触发的。我需要先理解这个问题的上下文,可能涉及网络编程或者事件驱动模型。 首先,用户提到的回填可能是指回调函数。常见的场景是在网络服务器中,当有新的连接建立时,会触发connection_callback,而data_callback则处理接收的数据。通常,主函数(main)可能会注册连接回调,当连接建立后,由这个connection_callback来设置数据处理的回调,比如在socket编程中,当accept一个连接后,为这个新连接注册data_callback到事件循环中。 用户可能是在看某个代码示例,发现data_callback没有直接在main里调用或注册,所以疑惑它是否由connection_callback触发。这时候需要解释回调的链式注册,即connection_callback在每次有新连接时,负责设置后续的数据处理回调。 可能用户对事件驱动或异步编程模型不太熟悉,所以需要简要说明这种模式的工作机制。比如,主函数初始化服务器,注册连接处理的回调,当有客户端连接时,服务器调用connection_callback,在这个回调里可能会创建新的socket对象,并为其注册data_callback,这样当该socket有数据到达时,就会触发data_callback。 还需要注意用户可能的误区,比如认为回调必须显式地在main里注册,但实际上可以在其他回调中动态注册。这时候需要举例说明,比如使用Python的asyncio或者socket模块,当处理新连接时,设置读事件的回调为data_callback。 另外,可能需要区分不同框架或库中的回调注册方式,但通常模式是类似的。要确保解释清晰,避免术语混淆,比如“回填”可能是指回调函数的注册,而不是其他概念。 总结回答的结构:先说明是的,通常由connection_callback触发注册,然后解释典型的工作流程,举例说明,最后总结这种设计的原因和好处。</think>是的,通常情况下在这种异步/事件驱动的编程模型中,`data_callback` 的确是由 `connection_callback` 动态注册的。它们的协作流程一般如下: --- ### 📌 典型工作流程 1. **主函数 (`main`)** 只会直接注册 `connection_callback`(例如绑定到服务器的监听端口)。此时尚未涉及 `data_callback`。 2. **当新连接建立时** 系统触发 `connection_callback`,该回调会接收到新连接的上下文(如 `socket` 对象)。**此时才是注册 `data_callback` 的时机**。 3. **动态注册数据回调** 在 `connection_callback` 内部,通常会为新连接绑定 `data_callback`(例如调用 `set_data_callback` 或将其加入事件循环)。这样当该连接后续有数据到达时,`data_callback` 才会被触发。 --- ### 📝 伪代码示例(以事件循环为例) ```python def connection_callback(new_socket): # 当有新连接时,动态注册数据回调 new_socket.set_data_callback(data_callback) # 👈 关键步骤 print("New client connected!") def data_callback(data): print("Received data:", data) def main(): server = create_server() server.set_connection_callback(connection_callback) # 主函数只注册连接回调 server.run_forever() ``` --- ### 🌟 这种设计的意义 1. **按需绑定** 每个连接的 `data_callback` 可能有不同需求(如协议解析),动态注册更灵活。 2. **资源隔离** 每个连接的上下文(如用户状态)独立,避免全局冲突。 3. **事件驱动效率** 只在需要时监听数据事件,减少不必要的资源占用。 如果 `data_callback` 直接写在主函数中,可能意味着所有连接共享同一个固定回调,这在复杂场景下会限制扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值