2
#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__)

Please forgive my poor English~~~!

The header file "ccMacros.h" inCocos2d-x 3.x,CC_CALLBACK Technology use the the new ISO C++ standard std::bind, for instance:

    class HelloWorldScene : cocos2d::Layer
{
public :
    static cocos2d::Scene* createScene();
    virtual bool init();
    CREATE_FUNC(HelloWorldScene);
    // overload this function
    void ontouchmoved(cocos2d::Touch*, cocos2d::Event*);
};

// HelloWorld.cpp

    bool HelloWorldScene::init()
{
    auto listener = cocos2d::EventListenerTouchOneByOne::create();

    listener->onTouchBegan = [](cocos2d::Touch* _touch, cocos2d::Event* _event){ CCLOG("onTouchBegan..."); return true;};
    // using the CC_CALLBACK 
    listener->onTouchMoved = CC_CALLBACK_2(HelloWorldScene::ontouchmoved, this);
    listener->onTouchEnded = [](cocos2d::Touch* _touch, cocos2d::Event* _event){ CCLOG("onTouchEnded...");};
    cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}
void HelloWorldScene::ontouchmoved(cocos2d::Touch* touch, cocos2d::Event* event)
{
    CCLOG("onTouchMoved...");
}

I send this function "HelloWorld::ontouchmoved" and pointer "this", `"HelloWorld::ontouchmoved" is selector in CC_CALLBACK_2, "this" is target in CC_CALLBACK_2。 but why? I send no more parameter to CC_CALLBACK_2, but the definition of CC_CALLBACK_2 is :

#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)

The placeholders_1 and placehoders_2 bind no parameters, What's the use of them? I guess them bind the parameters of HelloWorld::ontouchmoved, but i don't kown the way to bind parameters of HelloWorld::ontouchmoved。

Help me!Thanks a lot!

Caramiriel
  • 7,029
  • 3
  • 30
  • 50

3 Answers3

1

I don't exactly understand your question, but why not use lambda functions?:

auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);

listener->onTouchBegan = [&](Touch* touch, Event* event){

};

listener->onTouchMoved = [&](Touch* touch, Event* event){

};

listener->onTouchEnded = [&](Touch* touch, Event* event){

};

listener->onTouchCancelled = [&](Touch* touch, Event* event){

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
Makalele
  • 7,431
  • 5
  • 54
  • 81
  • I'm so sorry that my statement is unclear。I must redeclare my confusion: for instance: listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::ontouchmoved, this); as we see, member function "ontouchmoved" and pointer "this" is passed to CC_CALLBACK_2, "HelloWorld::ontouchmoved" for __selector__, "this" for __target__, but, there are no more arguments pass to CC_CALLBACK_2, however, std::placeholders:_1 and std::placeholders::_2 is in CC_CALLBACK_2, so,I guess that std::placeholders::_1 and std::placeholders::_2 is useless。 – CountingStars Dec 14 '15 at 16:20
  • placeholders are for Touch* touch and Event* event. – Makalele Dec 14 '15 at 21:21
  • but, there are no more arguments passed to CC_CALLBACK_2 except "HelloWorld::ontouchmoved" and "this"。 therefore, What data the std::placeholder::_1 and std::placeholder::_2 stand for? Why they stand for Touch* touch and Event* event? – CountingStars Dec 15 '15 at 04:31
0

Please read more detail in addEventListenerWithSceneGraphPriority function. Touch and Event added at this point.

Vo Kim Nguyen
  • 1,613
  • 10
  • 14
0

The purpose of std::placeholders::_N is to allow std::bind to create a function with parameters matching the Nth parameter of the original function.

You can attach values instead of placeholder if you want to create a function that takes fewer parameters (wrap around the original function) or reorders or duplicates the original parameters. You can also bind any variables passed in by value or by reference.

You'll want to read up a little more on std::bind if you want to learn more about all the crazy things you can do.

http://en.cppreference.com/w/cpp/utility/functional/bind

Steve T
  • 7,729
  • 6
  • 45
  • 65