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: 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.