I’ve identified the following bug relating to the adding of standard touch delegates (
CCStandardTouchDelegate) inside of a touchesBegan event. If this occurs during a touchesBegan event, the
m_bLocked flag of
CCTouchDispatcher is true. Thus, when
CCTouchDispatcher::addStandardDelegate is called, the newly created TouchHandler is added to the
m_pHandlersToAdd list. Then, when the existing touch handlers have finished processing, this array is iterated over to finish adding the deferred handlers to the correct lists.
However, this part of the code relies on the return value of
CCTouchDelegate::getTouchDelegateType. This should be set to either
ccTouchDelegateTargetedBit as appropriate. However, both
CCTouchDelegate directly, which has its value of
m_eTouchDelegateType set to
CCLayer directly calls
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate. Thus, when
CCTouchDispatcher::touches iterates over
m_pHandlersToAdd, the result of
pHandler->getDelegate()->getTouchDelegateType() & ccTouchDelegateTargetedBit is always true, and thus all handlers are added to m_pTargetedHandlers.
Finally, in my application this leads to a crash, as the TargetedHandlers list contains a StandardHandler, which is then cast to a TargetedHandler without any type checking. Then an attempt to access pHandler->getClaimedTouches() results in an exception.
I have fixed this in my code by forcing the value of
m_eTouchDelegateType to the correct flag inside both
CCTargetedTouchHandler::initWithDelegate. However, this is probably not ideal as this variable currently has no set accessor. Perhaps a more robust solution can be found.
ccTouchDeletateAllBit should probably be renamed