void CCTouchDispatcher::forceRemoveDelegate(CCTouchDelegate *pDelegate) { CCTouchHandler *pHandler; CCMutableArray<CCTouchHandler*>::CCMutableArrayIterator iter; // XXX: remove it from both handlers ??? // remove handler from m_pStandardHandlers for (iter = m_pStandardHandlers->begin(); iter != m_pStandardHandlers->end(); ++iter) { pHandler = *iter; if (pHandler && pHandler->getDelegate() == pDelegate) { m_pStandardHandlers->removeObject(pHandler); break; } } // remove handler from m_pTargetedHandlers for (iter = m_pTargetedHandlers->begin(); iter != m_pTargetedHandlers->end(); ++iter) { pHandler = *iter; if (pHandler && pHandler->getDelegate() == pDelegate) { m_pTargetedHandlers->removeObject(pHandler); break; } } }
// // handlers management // void CCTouchDispatcher::forceAddHandler(CCTouchHandler *pHandler, CCMutableArray<CCTouchHandler*> *pArray) { unsigned int u = 0; CCMutableArray<CCTouchHandler*>::CCMutableArrayIterator iter; for (iter = pArray->begin(); iter != pArray->end(); ++iter) { CCTouchHandler *h = *iter; if (h) { if (h->getPriority() < pHandler->getPriority()) { ++u; } if (h->getDelegate() == pHandler->getDelegate()) { CCAssert(0, ""); return; } } } pArray->insertObjectAtIndex(pHandler, u); }
// // 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 0 if (h->getPriority() == pHandler->getPriority()) { if (h->getDelegate()->getSubPriority() < pHandler->getDelegate()->getSubPriority()) { ++u; } } #endif if (h->getDelegate() == pHandler->getDelegate()) { CCAssert(0, ""); return; } } }
void CCTouchDispatcher::setPriority(int nPriority, CCTouchDelegate *pDelegate) { CCAssert(pDelegate != NULL, ""); CCTouchHandler *handler = NULL; handler = this->findHandler(pDelegate); CCAssert(handler != NULL, ""); handler->setPriority(nPriority); this->rearrangeHandlers(m_pTargetedHandlers); this->rearrangeHandlers(m_pStandardHandlers); }
CCTouchHandler* CCTouchHandler::handlerWithDelegate(CCTouchDelegate *pDelegate, int nPriority) { CCTouchHandler *pHandler = new CCTouchHandler(); if (pHandler) { if (pHandler->initWithDelegate(pDelegate, nPriority)) { pHandler->autorelease(); } else { CC_SAFE_RELEASE_NULL(pHandler); } } return pHandler; }
// // 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(); } }