// // handlers management // 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; } } }
// // dispatch events // void CCTouchDispatcher::touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex) { assert(uIndex >= 0 && uIndex < 4); CCSet *pMutableTouches; m_bLocked = true; // optimization to prevent a mutable copy when it is not necessary unsigned int uTargetedHandlersCount = m_pTargetedHandlers->count(); unsigned int uStandardHandlersCount = m_pStandardHandlers->count(); bool bNeedsMutableSet = (uTargetedHandlersCount && uStandardHandlersCount); pMutableTouches = (bNeedsMutableSet ? pTouches->mutableCopy() : pTouches); struct ccTouchHandlerHelperData sHelper = m_sHandlerHelperData[uIndex]; // // process the target handlers 1st // if (uTargetedHandlersCount > 0) { CCTouch *pTouch; CCSetIterator setIter; for (setIter = pTouches->begin(); setIter != pTouches->end(); ++setIter) { pTouch = (CCTouch *)(*setIter); CCTargetedTouchHandler *pHandler; CCMutableArray<CCTouchHandler*>::CCMutableArrayIterator arrayIter; for (arrayIter = m_pTargetedHandlers->begin(); arrayIter != m_pTargetedHandlers->end(); ++arrayIter) /*for (unsigned int i = 0; i < m_pTargetedHandlers->num; ++i)*/ { pHandler = (CCTargetedTouchHandler *)(*arrayIter); if (! pHandler) { break; } bool bClaimed = false; if (uIndex == ccTouchBegan) { #ifdef ENABLE_LUA CCString*pLuaFn = pHandler->getDelegate()->getLuaEvent(ccTouchBegan); if (pLuaFn) { bClaimed = true; pHandler->getDelegate()->excuteLuaTouchEvent(pLuaFn, pTouch); } else { bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent); } #else bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent); #endif if (bClaimed) { pHandler->getClaimedTouches()->addObject(pTouch); } } else if (pHandler->getClaimedTouches()->containsObject(pTouch)) { // moved ended cancelled bClaimed = true; #ifdef ENABLE_LUA CCString*pLuaFn = pHandler->getDelegate()->getLuaEvent(sHelper.m_type); switch (sHelper.m_type) { case ccTouchMoved: if (pLuaFn) { pHandler->getDelegate()->excuteLuaTouchEvent(pLuaFn, pTouch); } else { pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent); } break; case ccTouchEnded: if (pLuaFn) { pHandler->getDelegate()->excuteLuaTouchEvent(pLuaFn, pTouch); } else { pHandler->getDelegate()->ccTouchEnded(pTouch, pEvent); } pHandler->getClaimedTouches()->removeObject(pTouch); break; case ccTouchCancelled: if (pLuaFn) { pHandler->getDelegate()->excuteLuaTouchEvent(pLuaFn, pTouch); } else { pHandler->getDelegate()->ccTouchCancelled(pTouch, pEvent); } pHandler->getClaimedTouches()->removeObject(pTouch); break; } #else 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; } #endif } if (bClaimed && pHandler->isSwallowsTouches()) { if (bNeedsMutableSet) { pMutableTouches->removeObject(pTouch); } break; } } } } // // process standard handlers 2nd // if (uStandardHandlersCount > 0 && pMutableTouches->count() > 0) { CCMutableArray<CCTouchHandler*>::CCMutableArrayIterator iter; CCStandardTouchHandler *pHandler; for (iter = m_pStandardHandlers->begin(); iter != m_pStandardHandlers->end(); ++iter) { pHandler = (CCStandardTouchHandler*)(*iter); if (! pHandler) { break; } #ifdef ENABLE_LUA CCString*pLuaTouchesfn = pHandler->getDelegate()->getLuaEvent(sHelper.m_type); if (pLuaTouchesfn) { pHandler->getDelegate()->excuteLuaTouchesEvent(pLuaTouchesfn, pMutableTouches); } else { switch (sHelper.m_type) { case ccTouchBegan: pHandler->getDelegate()->ccTouchesBegan(pMutableTouches, pEvent); break; case ccTouchMoved: pHandler->getDelegate()->ccTouchesMoved(pMutableTouches, pEvent); break; case ccTouchEnded: pHandler->getDelegate()->ccTouchesEnded(pMutableTouches, pEvent); break; case ccTouchCancelled: pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches, pEvent); break; } } #else switch (sHelper.m_type) { case ccTouchBegan: pHandler->getDelegate()->ccTouchesBegan(pMutableTouches, pEvent); break; case ccTouchMoved: pHandler->getDelegate()->ccTouchesMoved(pMutableTouches, pEvent); break; case ccTouchEnded: pHandler->getDelegate()->ccTouchesEnded(pMutableTouches, pEvent); break; case ccTouchCancelled: pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches, pEvent); break; } #endif } } if (bNeedsMutableSet) { pMutableTouches->release(); } // // Optimization. To prevent a [handlers copy] which is expensive // the add/removes/quit is done after the iterations // m_bLocked = false; if (m_bToRemove) { m_bToRemove = false; for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i) { forceRemoveDelegate((CCTouchDelegate*)m_pHandlersToRemove->arr[i]); } ccCArrayRemoveAllValues(m_pHandlersToRemove); } if (m_bToAdd) { m_bToAdd = false; CCMutableArray<CCTouchHandler*>::CCMutableArrayIterator iter; CCTouchHandler *pHandler; for (iter = m_pHandlersToAdd->begin(); iter != m_pHandlersToAdd->end(); ++iter) { pHandler = *iter; if (! pHandler) { break; } if (pHandler->getDelegate()->getTouchDelegateType() & ccTouchDelegateTargetedBit) { forceAddHandler(pHandler, m_pTargetedHandlers); } else { forceAddHandler(pHandler, m_pStandardHandlers); } } m_pHandlersToAdd->removeAllObjects(); } if (m_bToQuit) { m_bToQuit = false; forceRemoveAllDelegates(); } }