From 2e8eb652e10ba5d5419f277a98294faff4e46f56 Mon Sep 17 00:00:00 2001 From: Martin Kralik Date: Wed, 3 Feb 2016 05:22:18 -0800 Subject: [PATCH] coalesce "touchMove" events (7/7) Summary: This is a final diff in the stack, which makes us not send a bazillion events to js after it's been busy while an user dragged his finger on a screen (resulting in ~two events per frame). I made "touchMove" event to be coalescable, which makes us not send anything while dragging (since this makes both scroll events and touch move events coalesced and not being send until either next js frame or the next different touch event occurs). This change is far from perfect. The event name is a hard coded string and the coalescing works with some (reasonable) assumptions on internal structure of these touch events. Which may or may not be really true. It would be great if someone could comment on these. I'm thinking about making the touches more strongly typed. Any thoughts on this? public ___ //This diff is part of a larger stack. For high level overview what's going on jump to D2884593.// Reviewed By: nicklockwood Differential Revision: D2884595 fb-gh-sync-id: f3c2f13430679e2bf52e0c7a3689650b3acae42f --- React/Base/RCTTouchEvent.m | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/React/Base/RCTTouchEvent.m b/React/Base/RCTTouchEvent.m index 780a7bec0..a6a97c037 100644 --- a/React/Base/RCTTouchEvent.m +++ b/React/Base/RCTTouchEvent.m @@ -8,6 +8,7 @@ */ #import "RCTTouchEvent.h" +#import "RCTAssert.h" @implementation RCTTouchEvent { @@ -36,12 +37,31 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) - (BOOL)canCoalesce { - return NO; + return [_eventName isEqual:@"touchMove"]; } +// We coalesce only move events, while holding some assumptions that seem reasonable but there are no explicit guarantees about them. - (id)coalesceWithEvent:(id)newEvent { - return newEvent; + RCTAssert([newEvent isKindOfClass:[RCTTouchEvent class]], @"Touch event cannot be coalesced with any other type of event, such as provided %@", newEvent); + RCTTouchEvent *newTouchEvent = (RCTTouchEvent *)newEvent; + RCTAssert([_reactTouches count] == [newTouchEvent->_reactTouches count], @"Touch events have different number of touches. %@ %@", self, newEvent); + + BOOL newEventIsMoreRecent = NO; + BOOL oldEventIsMoreRecent = NO; + NSInteger count = _reactTouches.count; + for (int i = 0; i_reactTouches[i]; + RCTAssert([touch[@"identifier"] isEqual:newTouch[@"identifier"]], @"Touch events doesn't have touches in the same order. %@ %@", touch, newTouch); + if ([touch[@"timestamp"] doubleValue] > [newTouch[@"timestamp"] doubleValue]) { + oldEventIsMoreRecent = YES; + } else { + newEventIsMoreRecent = YES; + } + } + RCTAssert(!(oldEventIsMoreRecent && newEventIsMoreRecent), @"Neither touch event is exclusively more recent than the other one. %@ %@", _reactTouches, newTouchEvent->_reactTouches); + return newEventIsMoreRecent ? newEvent : self; } + (NSString *)moduleDotMethod