Search code examples
c++cocos2d-x

cocos 2d-x add touch event callback error


I have a cocos2d-x scene and Button on it. i try to add touch event listener add provide it with callback function:

preloadScene.h:

...
public:
virtual void Do(Touch* touch, Event* event);
...

preloadScene.cpp

bool Preload::init(){
...
auto button = ui::Button::create("assets/preload_button.png");
...
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchEnded = CC_CALLBACK_2(Preload::Do, this);
button->addTouchEventListener(listener);
...
}

During compilation i got this error: Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'

i understand that something wrong with callback or the way i use it. Please help.

P.S: Next lines work just fine, but i want to have this event-handling code encapsulated in other function.

*button->addTouchEventListener(
    [](Ref* sender, ui::Widget::TouchEventType type) {
    switch (type) {
    case ui::Widget::TouchEventType::BEGAN: {
        CCLOG("touch began");
        auto scene = MainMenu::createScene();
        Director::getInstance()->popScene();
        Director::getInstance()->replaceScene(scene);
    }
        break;

Solution

  • Solution: use lambda to call your function.

    button->addTouchEventListener([this](Touch*, Event*){ this->Do();}
    

    CC_CALLBACK_2 uses std::bind under the hood. The declaration of Button::addTouchEventListener is void Button::addTouchEventListener(const ccWidgetTouchCallback& callback), where ccWidgetTouchCallback is std::function<void(Ref*,Widget::TouchEventType)> rather than a EventTouchListener.
    It is a bad practice to bind a virtual function, since the derived version will not be called.