【cocos2dx入門】「ラムダ式」と「コールバック関数」のまとめ。

【cocos2dx入門】「ラムダ式」と「コールバック関数」のまとめ。
   

cocos2dxのVer3.xで、大きく変わったのが「ラムダ式」と「コールバック関数」です。
特に「ラムダ式」に関しては、個人的にcocos2dではBlock関数として非常に便利に利用ができていたので、とても嬉しいです。
「メニュー」「タッチ処理」「アクション」で利用ができます。

ラムダ式

ラムダ式とは、以下のような構文です。
[](){

  //ここに記載をされたコードを呼び出す。

};

//意味
[キャプチャ](仮引数)->戻り値{複合文};

[] : キャプチャ

まずは見ていただきたいのが、最初に記載をされた「[]」です。
中身はキャプチャと呼ばれています。
このキャプチャには、ラムダ式で参照するオブジェクトを指定します。
  • [=] : 全てのオブジェクトのコピーがラムダ式に渡されます。
  • [&] : 全てのオブジェクトの参照がラムダ式に渡されます。
  • [obj] :objのコピーがラムダ式に渡されます。
  • [&obj]:objの参照がラムダ式に渡されます。

キャプチャは複数指定することもできます。

参照とコピー

参照とコピーについて。
参照はオブジェクトを変更することができます。
int i = 0;
auto callfunc0 = CallFunc::create([&i](){
        
        i = 10; //変更可能
        
    });




コピーはオブジェクトの値を変更できません。
int i = 0;
auto callfunc0 = CallFunc::create([i](){
        
        i = 10; //エラーが出る
     CCLOG("i = %i",i); //値を読み込みことは可能
        
    });

() : 仮引数

これは省略が可能です。
auto callfunc1 = CallFuncN::create([](Ref*sender){

     Sprite *_sprite = (Sprite*)sender;

});

戻り値

これは省略可能。
listener->onTouchBegan = [](Touch *touch,Event *event)->bool{
        
        CCLOG("タッチ Began");
        return true;
        
};

複合文

ラムダ式で行う処理を記述します。


コールバック関数

Ver3.xから、マクロで登録されたコールバック関数が登場します。
使い方は、指定したメソッドを呼び出すのですが、呼び出すメソッドの引数に応じて使い分けます。
ここの認識は間違っているかもしれません。
  • CC_CALLBACK_0
  • CC_CALLBACK_1
  • CC_CALLBACK_2

CC_CALLBACK_0


[C]
//引数がない
const std::function< void()> &func

//例
void CallBackLayer::menuAction0(){


}
[/C]

CC_CALLBACK_1

[C]
//引数が1つ
const std::function< void(Node *)> &func

//例
void CallBackLayer::menuAction1(Ref *sender){


}

[/C]

CC_CALLBACK_2


[C]
//引数が2つ
std::function onTouchBegan

//例
void CallBackLayer::menuAction2(Touch *touch,Event *event){


}

[/C]


メニュー MenuItem

では具体的な例を記載します。
まずはMenuItemで利用する場合です。

Ver2.x
//Ver2.x
CCMenuItemImage *item = CCMenuItemImage::create("button.png", "button-hover.png",this,menu_selector(CallBackLayer::menuAction0));

コールバック関数
//Ver3.x
auto item = MenuItemImage::create("button.png","button-hover.png",CC_CALLBACK_0(CallBackLayer::menuAction0, this));

ラムダ式
//ラムダ式
auto mItem2 = MenuItemImage::create("button.png","button-hover.png",[](Ref*sender){
     
       //ここが呼び出されます。
});


タッチ処理

タッチ処理で利用する場合です。
Ver2.x
//Ver2.x

//.h
virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);


//.cpp
bool CallBackLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){
  
    return true;
     
}


コールバック関数
//Ver3.x
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);

listener->onTouchBegan = CC_CALLBACK_2(CallBackLayer::onTouchBegan, this);

bool CallBackLayer::onTouchBegan(cocos2d::Touch* touch,cocos2d::Event* event){
  
    return true;
     
}


ラムダ式
//ラムダ式
listener->onTouchBegan = [](Touch *touch,Event *event)->bool{
        
    
        return true;
        
};


アクション

Actionクラスの、CallFunc系で利用をします。

span style =”font-weight:700;”>Ver2.x
//Ver2.x
CCCallFunc *call = CCCallFunc::create(this,callfunc_selector(CallBackLayer::callAction));   

コールバック関数
//Ver3.x
auto call = CallFunc::create(CC_CALLBACK_0(CallBackLayer::callAction,this));
auto callN = CallFuncN::create(CC_CALLBACK_1(CallBackLayer::callActionN,this));


ラムダ式
//ラムダ式
auto call = CallFunc::create([](){
         
    //呼び出す処理を記述
    //必要ならキャプチャを付けて下さい=> [=],[&]など
});

auto callN = CallFunc::create([](Ref *sender){
         
    //呼び出す処理を記述
    //必要ならキャプチャを付けて下さい=> [=],[&]など
});




最後に

色々と触っているうちに、何となく「ラムダ式」と「コールバック関数」がどんなものかぼんやり見えてきました。
Xcodeは賢いので、もし間違っている時にはエラーがでます。
その場合には「CC_CALLBACK_0」の最後の数字を変えてみたり、ラムダ式ならキャプチャの指定がおかしくないかを調べながらやってみましょう。
とくにActionクラスで利用する際には、Ver2.xでは、とても面倒くさいと感じていましたので、表現の幅が広がりそうです。

C++ ポケットリファレンスC++ ポケットリファレンス
高橋 晶,安藤 敏彦,一戸 優介,楠田 真矢,道化師,湯朝 剛介

技術評論社
売り上げランキング : 48201

Amazonで詳しく見る


Related Posts Plugin for WordPress, Blogger...