Hello,
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 ccTouchDelegateStandardBit
or ccTouchDelegateTargetedBit
as appropriate. However, both CCLayer
and CCMenu
implement CCTouchDelegate
directly, which has its value of m_eTouchDelegateType
set to ccTouchDeletateAllBit
. But CCLayer
directly calls CCTouchDispatcher::sharedDispatcher()->addStandardDelegate
, while CCMenu
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 CCStandardTouchHandler::initWithDelegate
and CCTargetedTouchHandler::initWithDelegate
. However, this is probably not ideal as this variable currently has no set accessor. Perhaps a more robust solution can be found.
Also, ccTouchDeletateAllBit
should probably be renamed ccTouchDelegateAllBit