New issue
 Projects > cocos2d-x > Issues > Bug #4317

setTouchPriority sometimes doesn't work due to a bug in CCTouchDispatcher

Bug #4317 [New]
SPQR301 2014-03-09 16:28 . Updated about 9 years ago

The problem is in version 2.2.2. The bug was introduced in this fix: http://cocos2d-x.org/issues/752

Test case:

I created a Layer, which has a sole purpose to block ("swallow";) touches, and this feature can be turned on and off.
The class is very basic, if it receives the touch it always swallows it:

`bool BlockingLayer::init(){

// Super init.
if ( !CCLayer::init() )
{
return false;
}

setTouchEnabled(true);
setTouchMode(kCCTouchesOneByOne);
setTouchPriority(INT_MAX);

return true;
}

bool BlockingLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCLOG("BlockingLayer swallowed touch!");
return true;
}

So by default it has a really bad priority, it receives touches if no other class claimed it. But in the scene where I am using this layer I would like to set it to a different priority when certain events occur:

bool MyScene::init(int unitNumber, CCString* path){
// Super init.
...
blockingLayer = BlockingLayer::create();
this->addChild(blockingLayer);

return true;
}

bool MyScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){
blockingLayer->setTouchPriority(INTMIN);
}`

Now the layer should have the best priority possible, so it should swallow all touches. But it does not, it's behaviour does not change.
I see its registerWithTouchDispatcher() called and the m_nTouchPriority changed correctly. BUT the layer's behaviour is unchanged.

Fix:

As wondeful18 suggested:

Replace in addStandardDelegate and addTargetedDelegate:

this:
if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
{
ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
return;
}

to this:
if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
{
CCTouchHandler *pOldHandler = findHandler(pDelegate);
if (pOldHandler && pOldHandler->getPriority() == nPriority)
{
ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
return;
}
}

SPQR301 2014-03-10 13:38

If the priority is changed we have the CCTouchHandler present both in m_pHandlersToRemove and m_pHandlersToAdd. But in CCTouchDispatcher::touches we first iterate m_pHandlersToRemove and than m_pHandlersToAdd. So the CCTouchHandler stays and there is no memory leak.

See: https://github.com/cocos2d/cocos2d-x/pull/5641

Atom PDF

Status:New
Start date:2014-03-09
Priority:Low
Due date:
Assignee:-
% Done:

0%

Category:all
Target version:-