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
This commit is contained in:
Martin Kralik 2016-02-03 05:22:18 -08:00 коммит произвёл facebook-github-bot-4
Родитель 4aaa35a22e
Коммит 2e8eb652e1
1 изменённых файлов: 22 добавлений и 2 удалений

Просмотреть файл

@ -8,6 +8,7 @@
*/ */
#import "RCTTouchEvent.h" #import "RCTTouchEvent.h"
#import "RCTAssert.h"
@implementation RCTTouchEvent @implementation RCTTouchEvent
{ {
@ -36,12 +37,31 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (BOOL)canCoalesce - (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<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent - (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)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<count; i++) {
NSDictionary *touch = _reactTouches[i];
NSDictionary *newTouch = newTouchEvent->_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 + (NSString *)moduleDotMethod