androidiostouchcocos2d-xcclayer

CCLayer setTouchPriority has no effect


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(INT_MIN);
     ...
}

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

This is on Cocos2D-x 2.2. Any help is appreciated.


Solution

  • Turns out this was a bug in Cocos2d-x:

    see this:

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

    Solution:

    change in CCTouchDispatcher.cpp this:

    void CCTouchDispatcher::addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority)
    {    
        CCTouchHandler *pHandler = CCStandardTouchHandler::handlerWithDelegate(pDelegate, nPriority);
        if (! m_bLocked)
        {
            forceAddHandler(pHandler, m_pStandardHandlers);
        }
        else
        {
            /* If pHandler is contained in m_pHandlersToRemove, if so remove it from     m_pHandlersToRemove and return.
             * Refer issue #752(cocos2d-x)
             */
             if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
             {
                 ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
                 return;
              }
    
            m_pHandlersToAdd->addObject(pHandler);
            m_bToAdd = true;
        }
    }
    

    and

    void CCTouchDispatcher::addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)
    {    
        CCTouchHandler *pHandler = CCTargetedTouchHandler::handlerWithDelegate(pDelegate, nPriority, bSwallowsTouches);
        if (! m_bLocked)
        {
            forceAddHandler(pHandler, m_pTargetedHandlers);
        }
        else
        {
            /* If pHandler is contained in m_pHandlersToRemove, if so remove it from m_pHandlersToRemove and return.
             * Refer issue #752(cocos2d-x)
             */
             if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
              {
                  ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
                  return;
              }
    
            m_pHandlersToAdd->addObject(pHandler);
            m_bToAdd = true;
        }
    }
    

    to this:

    void CCTouchDispatcher::addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority)
    {    
        CCTouchHandler *pHandler = CCStandardTouchHandler::handlerWithDelegate(pDelegate, nPriority);
        if (! m_bLocked)
        {
            forceAddHandler(pHandler, m_pStandardHandlers);
        }
        else
        {
            /* If pHandler is contained in m_pHandlersToRemove, if so remove it from m_pHandlersToRemove and return.
             * Refer issue #752(cocos2d-x)
             */
            if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
            {
                CCTouchHandler *pOldHandler = findHandler(pDelegate);
                if (pOldHandler && pOldHandler->getPriority() == nPriority)
                {
                    ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
                    return;
                }
            }
    
            m_pHandlersToAdd->addObject(pHandler);
            m_bToAdd = true;
        }
    }
    

    and

    void CCTouchDispatcher::addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)
    {    
        CCTouchHandler *pHandler = CCTargetedTouchHandler::handlerWithDelegate(pDelegate, nPriority, bSwallowsTouches);
        if (! m_bLocked)
        {
            forceAddHandler(pHandler, m_pTargetedHandlers);
        }
        else
        {
            /* If pHandler is contained in m_pHandlersToRemove, if so remove it from m_pHandlersToRemove and return.
             * Refer issue #752(cocos2d-x)
             */
            if (ccCArrayContainsValue(m_pHandlersToRemove, pDelegate))
            {
                CCTouchHandler *pOldHandler = findHandler(pDelegate);
                if (pOldHandler && pOldHandler->getPriority() == nPriority)
                {
                    ccCArrayRemoveValue(m_pHandlersToRemove, pDelegate);
                    return;
                }
            }
    
            m_pHandlersToAdd->addObject(pHandler);
            m_bToAdd = true;
        }
    }