flush events queue when an event cannot be coalesced (4/7)

Summary:
Currently only scroll events are send through `sendEvent`, and all of them are can be coalesced. In future (further in the stack) touch events will go through there as well, but they won't support coalescing.
In order to ensure js processes touch and scroll events in the same order as they were created, we will flush the coalesced events when we encounter one that cannot be coalesced.

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: D2884591

fb-gh-sync-id: a3d0e916843265ec57f16aad2f016a79764dcce8
This commit is contained in:
Martin Kralik
2016-02-03 05:22:15 -08:00
committed by facebook-github-bot-4
parent 7f2b72528e
commit 91e5829419
3 changed files with 33 additions and 2 deletions

View File

@@ -95,6 +95,14 @@ RCT_EXTERN NSString *RCTNormalizeInputEventName(NSString *eventName);
/**
* Send a pre-prepared event object.
*
* If the event can be coalesced it is added to a pool of events that are sent at the beginning of the next js frame.
* Otherwise if the event cannot be coalesced we first flush the pool of coalesced events and the new event after that.
*
* Why it works this way?
* Making sure js gets events in the right order is crucial for correctly interpreting gestures.
* Unfortunately we cannot emit all events as they come. If we would do that we would have to emit scroll and touch moved event on every frame,
* which is too much data to transfer and process on older devices. This is especially bad when js starts lagging behind main thread.
*/
- (void)sendEvent:(id<RCTEvent>)event;

View File

@@ -138,6 +138,7 @@ RCT_EXPORT_MODULE()
- (void)sendEvent:(id<RCTEvent>)event
{
if (!event.canCoalesce) {
[self flushEventsQueue];
[self dispatchEvent:event];
return;
}
@@ -168,9 +169,14 @@ RCT_EXPORT_MODULE()
}
- (void)didUpdateFrame:(__unused RCTFrameUpdate *)update
{
[self flushEventsQueue];
}
- (void)flushEventsQueue
{
[_eventQueueLock lock];
NSDictionary *eventQueue = _eventQueue;
NSDictionary *eventQueue = _eventQueue;
_eventQueue = [NSMutableDictionary new];
self.paused = YES;
[_eventQueueLock unlock];