// // dispatch events // void touches(HashSet <UITouch> touches, kCCTouch touchType) { NSUtils.Assert((int)touchType < 4, "Invalid idx value"); HashSet <UITouch> mutableTouches; locked = true; // optimization to prevent a mutable copy when it is not necessary int targetedHandlersCount = targetedHandlers.Count; int standardHandlersCount = standardHandlers.Count; bool needsMutableSet = (targetedHandlersCount != 0 && standardHandlersCount != 0); mutableTouches = needsMutableSet?(new HashSet <UITouch>(touches)):touches; ccTouchHandlerHelperData helper = handlerHelperData[(int)touchType]; // // process the target handlers 1st // if (targetedHandlersCount > 0) { var enumerator = touches.GetEnumerator(); while (enumerator.MoveNext()) { UITouch touch = enumerator.Current; var targetedHandlersEnumerator = targetedHandlers.GetEnumerator(); while (targetedHandlersEnumerator.MoveNext()) { CCTargetedTouchHandler handler = (CCTargetedTouchHandler)targetedHandlersEnumerator.Current; bool claimed = false; if (touchType == kCCTouch.Began) { claimed = ((CCTouchOneByOneDelegate)handler.delegate_).ccTouchBegan(touch); if (claimed) { handler.claimedTouches.Add(touch); } } // else (moved, ended, cancelled) else if (handler.claimedTouches.Contains(touch)) { claimed = true; if (((int)handler.enabledSelectors & (int)(helper.type)) != 0) { Type thisType = handler.delegate_.GetType(); MethodInfo theMethod = thisType.GetMethod(helper.touchSel); theMethod.Invoke(handler.delegate_, new object[1] { touch }); } if (((int)helper.type & ((int)kCCTouchSelectorFlag.CancelledBit | (int)kCCTouchSelectorFlag.EndedBit)) != 0) { handler.claimedTouches.Remove(touch); } } if (claimed && handler.swallowsTouches) { if (needsMutableSet) { mutableTouches.Remove(touch); } break; } } } } // // process standard handlers 2nd // if (standardHandlersCount > 0 && mutableTouches.Count > 0) { var enumerator = standardHandlers.GetEnumerator(); while (enumerator.MoveNext()) { var handler = enumerator.Current; if (((int)handler.enabledSelectors & ((int)(helper.type))) != 0) { Type thisType = handler.delegate_.GetType(); MethodInfo theMethod = thisType.GetMethod(helper.touchesSel); theMethod.Invoke(handler.delegate_, new object[1] { mutableTouches }); } } } if (needsMutableSet) { mutableTouches = null; } // // Optimization. To prevent a [handlers copy] which is expensive // the add/removes/quit is done after the iterations // locked = false; //issue 1084, 1139 first add then remove if (toAdd) { toAdd = false; var enumerator = handlersToAdd.GetEnumerator(); while (enumerator.MoveNext()) { var handler = enumerator.Current; if (handler is CCTargetedTouchHandler) { forceAddHandler((CCTouchHandler)handler, targetedHandlers); } else { forceAddHandler((CCTouchHandler)handler, standardHandlers); } } handlersToAdd.Clear(); } if (toRemove) { toRemove = false; var enumerator = handlersToRemove.GetEnumerator(); while (enumerator.MoveNext()) { var aDelegate = enumerator.Current; forceRemoveDelegate(aDelegate); } handlersToRemove.Clear(); } if (toQuit) { toQuit = false; forceRemoveAllDelegates(); } }
// // dispatch events // void touches(HashSet<UITouch> touches, kCCTouch touchType) { NSUtils.Assert((int)touchType < 4, "Invalid idx value"); HashSet<UITouch> mutableTouches; locked = true; // optimization to prevent a mutable copy when it is not necessary int targetedHandlersCount = targetedHandlers.Count; int standardHandlersCount = standardHandlers.Count; bool needsMutableSet = (targetedHandlersCount!=0 && standardHandlersCount!=0); mutableTouches = needsMutableSet?(new HashSet<UITouch>(touches)):touches; ccTouchHandlerHelperData helper = handlerHelperData[(int)touchType]; // // process the target handlers 1st // if( targetedHandlersCount > 0 ) { var enumerator = touches.GetEnumerator(); while (enumerator.MoveNext()) { UITouch touch = enumerator.Current; var targetedHandlersEnumerator = targetedHandlers.GetEnumerator(); while (targetedHandlersEnumerator.MoveNext()) { CCTargetedTouchHandler handler = (CCTargetedTouchHandler)targetedHandlersEnumerator.Current; bool claimed = false; if( touchType == kCCTouch.Began ) { claimed = ((CCTouchOneByOneDelegate)handler.delegate_).ccTouchBegan(touch); if( claimed ) handler.claimedTouches.Add(touch); } // else (moved, ended, cancelled) else if( handler.claimedTouches.Contains(touch) ) { claimed = true; if( ((int)handler.enabledSelectors & (int)(helper.type)) != 0){ Type thisType = handler.delegate_.GetType(); MethodInfo theMethod = thisType.GetMethod(helper.touchSel); theMethod.Invoke(handler.delegate_, new object[1]{touch}); } if( ((int)helper.type & ((int)kCCTouchSelectorFlag.CancelledBit | (int)kCCTouchSelectorFlag.EndedBit)) != 0) handler.claimedTouches.Remove(touch); } if( claimed && handler.swallowsTouches ) { if( needsMutableSet ) mutableTouches.Remove(touch); break; } } } } // // process standard handlers 2nd // if( standardHandlersCount > 0 && mutableTouches.Count>0 ) { var enumerator = standardHandlers.GetEnumerator(); while (enumerator.MoveNext()) { var handler = enumerator.Current; if( ((int)handler.enabledSelectors & ((int)(helper.type))) != 0){ Type thisType = handler.delegate_.GetType(); MethodInfo theMethod = thisType.GetMethod(helper.touchesSel); theMethod.Invoke(handler.delegate_, new object[1]{mutableTouches}); } } } if( needsMutableSet ) mutableTouches = null; // // Optimization. To prevent a [handlers copy] which is expensive // the add/removes/quit is done after the iterations // locked = false; //issue 1084, 1139 first add then remove if( toAdd ) { toAdd = false; var enumerator = handlersToAdd.GetEnumerator(); while (enumerator.MoveNext()) { var handler = enumerator.Current; if( handler is CCTargetedTouchHandler ) forceAddHandler((CCTouchHandler)handler, targetedHandlers); else forceAddHandler((CCTouchHandler)handler, standardHandlers); } handlersToAdd.Clear(); } if( toRemove ) { toRemove = false; var enumerator = handlersToRemove.GetEnumerator(); while (enumerator.MoveNext()) { var aDelegate = enumerator.Current; forceRemoveDelegate(aDelegate); } handlersToRemove.Clear(); } if( toQuit ) { toQuit = false; forceRemoveAllDelegates(); } }