Cocos2d-x 3.x版本用CC_CALLBACK_0,CC_CALLBACK_1,CC_CALLBACK_2和CC_CALLBACK_3的宏來定義回調方法類的。
3.x版本的例子:
child->runAction(Sequence::create( DelayTime::create(1.4f), CallFunc::create( CC_CALLBACK_0(CrashTest::removeThis,this)), nullptr) );
這里的含義就是child執行了一個Action,這個Action是一個隊列,隊列的第一個執行是一個延時操作,第二個執行是一個回調。意思就是經過1.4秒后調用this對象的removeThis方法。
CC_CALLBACK_0中有兩個參數,第一個是要回調的方法名稱,用類名加方法的形式,第二個參數是函數被調用的對象的指針,一般是this。
很多人認為CC_CALLBACK_0中的0是代表回調的removeThis方法的參數是0個的意思,其實並不是。
看下面的例子:
auto action = Sequence::create( Place::create(Vec2(200,200)), Show::create(), MoveBy::create(1, Vec2(100,0)), CallFunc::create( CC_CALLBACK_0(ActionSequence2::callback1,this)), CallFunc::create( CC_CALLBACK_0(ActionSequence2::callback2,this,_grossini)), CallFunc::create( CC_CALLBACK_0(ActionSequence2::callback3,this,_grossini,0xbebabeba)), nullptr); void ActionSequence2::callback1() void ActionSequence2::callback2(Node* sender) void ActionSequence2::callback3(Node* sender, long data)
這里的三個CC_CALLBACK_0的參數列表中,除了第一個回調的方法和第二個調用的對象,第二個CC_CALLBACK_0中多了一個參數_grossini,這個變量在回調ActionSequence2::callback2方法時作為參數使用,ActionSequence2::callback2(_grossini)。同樣的ActionSequence2::callback3方法調用時的參數是_grossini和0xbebabeba,ActionSequence2::callback3(_grossini,0xbebabeba)。
CC_CALLBACK_0中的0是代表要回調的方法綁定第0個參數之后的參數。
ActionSequence2::callback2第0個后面的參數就是_grossini,那么_grossini就是第1個參數,調用就是ActionSequence2::callback2(_grossini)這個樣子。
那么, 同樣的道理CC_CALLBACK_1,2,3就代表回調的方法綁定第1,2,3個參數之后的參數。
我們再看個例子:
// Get auto labelGet = Label::createWithTTF("Test Get", "fonts/arial.ttf", 22); auto itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this, false)); itemGet->setPosition(LEFT, winSize.height - MARGIN - SPACE); menuRequest->addChild(itemGet); void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender, bool isImmediate)
這里的CC_CALLBACK_1有三個參數,前兩個就不多說了,第三個參數fasle就是回調函數onMenuGetTestClicked中的第1個參數之后的參數,也就是第二個參數。
這個回調在調用的地方是這樣:
_callback(this);
調用的時候只需要第一個參數,而第二個參數會被指定為false。
舉一個很容易理解的例子:
int add (int a, int b) { return a+b; } auto func = CC_CALLLBACK_1(add, this, 2); cout << func(3) << endl; // 結果是 5
func是一個回調方法,默認指定了第二個參數是2,調用的時候只需要指定第一個參數就可以了。
說完CC_CALLBACK的用法,再看看CC_CALLBACK這個宏的定義:
// new callbacks based on C++11 #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__) #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__) #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__) #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
C++11引入了boost庫的function和bind,bind也被3.x版本用來作為回調的綁定。
__selector__是綁定回調的方法
__target__是調用方法的對象
##__VA_ARGS__是可變的參數列表
std::placeholders::_1是占位符
std::placeholders::_2同上是占位符