转载请注明地址:http://blog.csdn.net/einsteinlike/article/details/41543237
CCTouchDispatcher中是这样分发触摸事件的:
CCARRAY_FOREACH(m_pTargetedHandlers, pObj)//这里是遍历了一个注册过触摸事件的数组,按优先级排序
{
pHandler = (CCTargetedTouchHandler *)(pObj);
if (! pHandler)
{
break;
}
bool bClaimed = false;
if (uIndex == CCTOUCHBEGAN)
{
bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent);
if (bClaimed)
{
pHandler->getClaimedTouches()->addObject(pTouch);
}
} else
if (pHandler->getClaimedTouches()->containsObject(pTouch))
{
// moved ended canceled
bClaimed = true;
switch (sHelper.m_type)
{
case CCTOUCHMOVED:
pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent);
break;
case CCTOUCHENDED:
pHandler->getDelegate()->ccTouchEnded(pTouch, pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);
break;
case CCTOUCHCANCELLED:
pHandler->getDelegate()->ccTouchCancelled(pTouch, pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);
break;
}
}
if (bClaimed && pHandler->isSwallowsTouches())
{
if (bNeedsMutableSet)
{
pMutableTouches->removeObject(pTouch);
}
break;
}
}
然后如果调用这里的
setPriority,就会重新排序数组:
rearrangeHandlers
void CCTouchDispatcher::setPriority(int nPriority, CCTouchDelegate *pDelegate)
{
CCAssert(pDelegate != NULL, "");
CCTouchHandler *handler = NULL;
handler = this->findHandler(pDelegate);
CCAssert(handler != NULL, "");
if (handler->getPriority() != nPriority)
{
handler->setPriority(nPriority);
this->rearrangeHandlers(m_pTargetedHandlers);
this->rearrangeHandlers(m_pStandardHandlers);
}
}
但是在业务层调用的 setPriority是这样的:
void CCTouchHandler::setPriority(int nPriority)
{
m_nPriority = nPriority;
}
所以你会发现如果在初始化一个控件的时候调用 setPriority就会有效,而在运行中动态更改就无效,就是因为初始化后的下一帧调用(调用onEnter时,会注册touchdelegate)会根据当前priority将其注册进那个数组:
void CCTouchDispatcher::forceAddHandler(CCTouchHandler *pHandler, CCArray *pArray)
{
unsigned int u = 0;
CCObject* pObj = NULL;
CCARRAY_FOREACH(pArray, pObj)
{
CCTouchHandler *h = (CCTouchHandler *)pObj;
if (h)
{
if (h->getPriority() < pHandler->getPriority())
{
++u;
}
if (h->getDelegate() == pHandler->getDelegate())
{
CCAssert(0, "");
return;
}
}
}
pArray->insertObject(pHandler, u);
}
所以,改变触摸分发数组的机会只有一次,之后如果想动态的改变优先级需要获取 TouchDispatcher后设置,或者类似menu可以调用现成的函数 setHandlerPriority