Cocos2d-xでStaticクラスのメソッドやフリー関数をコールバックに指定するマクロ

タイトルにはCocos2d-xと書いてありますが、C++でstaticなメソッドとかフリー関数をstd::bind関数でバインドする方法です。

Cocos2d-xにあるCC_CALLBACK${N}を改造してCC_CALLBACK_S${N}を以下のように定義すると簡単にバインドできるようになります。

// 任意の位置に以下を定義する
#define CC_CALLBACK_S_0(__selector__, ...) std::bind(__selector__, ##__VA_ARGS__)
#define CC_CALLBACK_S_1(__selector__, ...) std::bind(__selector__, std::placeholders::_1 , ##__VA_ARGS__)
#define CC_CALLBACK_S_2(__selector__, ...) std::bind(__selector__, std::placeholders::_1 , std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_S_3(__selector__, ...) std::bind(__selector__, std::placeholders::_1 , std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)

インスタンスメソッドの指定する既存のCC_CALLBACK系と違ってインスタンスを指定する必要が無いです。

記述が大したことないので毎回std::bindしろよという感がしなくもないですが、ラムダ式で述語を記述するメソッドスタイルが最近の流行りなので定義しておいて記述の手間を省きたいと思います。

使い方は

class Hoge
{
public:
    static class sample() { /* nop */ }
};

void foo(std::function<void(void)> fnc)
{
    fnc();
}

void hoge()
{
    foo(CC_CALLBACK_S_0(Hoge::sample)); // メソッドの指定だけする
}

元々std::bind関数でstatic関数をバインドするときの指定方法が以下のように指定するのを既存のマクロと同じように定義したものとなります。

std::bind(Hoge::sample()); // 引数が無いとき
std::bind(Hoge::sample(), std::placeholders::_1); // 引数が1個の時
std::bind(Hoge::sample(), std::placeholders::_2); // 引数が2個の時

短いですが以上です。