mirror of
https://github.com/status-im/react-native.git
synced 2025-01-27 17:54:48 +00:00
Pause JS DisplayLink if nothing to process.
Reviewed By: @jspahrsummers Differential Revision: D2489107
This commit is contained in:
parent
4c74f01b85
commit
e727fc817b
@ -309,6 +309,15 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
|
|||||||
config[moduleData.name] = moduleData.config;
|
config[moduleData.name] = moduleData.config;
|
||||||
if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
|
if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
|
||||||
[_frameUpdateObservers addObject:moduleData];
|
[_frameUpdateObservers addObject:moduleData];
|
||||||
|
|
||||||
|
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
__weak typeof(_javaScriptExecutor) weakJavaScriptExecutor = _javaScriptExecutor;
|
||||||
|
observer.pauseCallback = ^{
|
||||||
|
[weakJavaScriptExecutor executeBlockOnJavaScriptQueue:^{
|
||||||
|
[weakSelf updateJSDisplayLinkState];
|
||||||
|
}];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +326,23 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
|
|||||||
}, NULL);
|
}, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateJSDisplayLinkState
|
||||||
|
{
|
||||||
|
RCTAssertJSThread();
|
||||||
|
|
||||||
|
BOOL pauseDisplayLink = ![_scheduledCallbacks count] && ![_scheduledCalls count];
|
||||||
|
if (pauseDisplayLink) {
|
||||||
|
for (RCTModuleData *moduleData in _frameUpdateObservers) {
|
||||||
|
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
||||||
|
if (!observer.paused) {
|
||||||
|
pauseDisplayLink = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_jsDisplayLink.paused = pauseDisplayLink;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)injectJSONConfiguration:(NSString *)configJSON
|
- (void)injectJSONConfiguration:(NSString *)configJSON
|
||||||
onComplete:(void (^)(NSError *))onComplete
|
onComplete:(void (^)(NSError *))onComplete
|
||||||
{
|
{
|
||||||
@ -620,6 +646,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
|||||||
} else {
|
} else {
|
||||||
[strongSelf->_scheduledCalls addObject:call];
|
[strongSelf->_scheduledCalls addObject:call];
|
||||||
}
|
}
|
||||||
|
[strongSelf updateJSDisplayLinkState];
|
||||||
|
|
||||||
RCTProfileEndEvent(0, @"objc_call", call);
|
RCTProfileEndEvent(0, @"objc_call", call);
|
||||||
}];
|
}];
|
||||||
@ -804,7 +831,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
|||||||
RCTFrameUpdate *frameUpdate = [[RCTFrameUpdate alloc] initWithDisplayLink:displayLink];
|
RCTFrameUpdate *frameUpdate = [[RCTFrameUpdate alloc] initWithDisplayLink:displayLink];
|
||||||
for (RCTModuleData *moduleData in _frameUpdateObservers) {
|
for (RCTModuleData *moduleData in _frameUpdateObservers) {
|
||||||
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)moduleData.instance;
|
||||||
if (![observer respondsToSelector:@selector(isPaused)] || !observer.paused) {
|
if (!observer.paused) {
|
||||||
RCT_IF_DEV(NSString *name = [NSString stringWithFormat:@"[%@ didUpdateFrame:%f]", observer, displayLink.timestamp];)
|
RCT_IF_DEV(NSString *name = [NSString stringWithFormat:@"[%@ didUpdateFrame:%f]", observer, displayLink.timestamp];)
|
||||||
RCTProfileBeginFlowEvent();
|
RCTProfileBeginFlowEvent();
|
||||||
|
|
||||||
@ -833,6 +860,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
|||||||
[self _actuallyInvokeAndProcessModule:@"BatchedBridge"
|
[self _actuallyInvokeAndProcessModule:@"BatchedBridge"
|
||||||
method:@"processBatch"
|
method:@"processBatch"
|
||||||
arguments:@[[calls valueForKey:@"js_args"]]];
|
arguments:@[[calls valueForKey:@"js_args"]]];
|
||||||
|
[self updateJSDisplayLinkState];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCTProfileEndEvent(0, @"objc_call", nil);
|
RCTProfileEndEvent(0, @"objc_call", nil);
|
||||||
|
@ -93,18 +93,30 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
@synthesize paused = _paused;
|
@synthesize paused = _paused;
|
||||||
|
@synthesize pauseCallback = _pauseCallback;
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
|
_paused = YES;
|
||||||
_eventQueue = [NSMutableDictionary new];
|
_eventQueue = [NSMutableDictionary new];
|
||||||
_eventQueueLock = [NSLock new];
|
_eventQueueLock = [NSLock new];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setPaused:(BOOL)paused
|
||||||
|
{
|
||||||
|
if (_paused != paused) {
|
||||||
|
_paused = paused;
|
||||||
|
if (_pauseCallback) {
|
||||||
|
_pauseCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)sendAppEventWithName:(NSString *)name body:(id)body
|
- (void)sendAppEventWithName:(NSString *)name body:(id)body
|
||||||
{
|
{
|
||||||
[_bridge enqueueJSCall:@"RCTNativeAppEventEmitter.emit"
|
[_bridge enqueueJSCall:@"RCTNativeAppEventEmitter.emit"
|
||||||
@ -169,7 +181,7 @@ RCT_EXPORT_MODULE()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_eventQueue[eventID] = event;
|
_eventQueue[eventID] = event;
|
||||||
_paused = NO;
|
self.paused = NO;
|
||||||
|
|
||||||
[_eventQueueLock unlock];
|
[_eventQueueLock unlock];
|
||||||
}
|
}
|
||||||
@ -202,7 +214,7 @@ RCT_EXPORT_MODULE()
|
|||||||
[_eventQueueLock lock];
|
[_eventQueueLock lock];
|
||||||
NSDictionary *eventQueue = _eventQueue;
|
NSDictionary *eventQueue = _eventQueue;
|
||||||
_eventQueue = [NSMutableDictionary new];
|
_eventQueue = [NSMutableDictionary new];
|
||||||
_paused = YES;
|
self.paused = YES;
|
||||||
[_eventQueueLock unlock];
|
[_eventQueueLock unlock];
|
||||||
|
|
||||||
for (id<RCTEvent> event in eventQueue.allValues) {
|
for (id<RCTEvent> event in eventQueue.allValues) {
|
||||||
|
@ -40,11 +40,15 @@
|
|||||||
*/
|
*/
|
||||||
- (void)didUpdateFrame:(RCTFrameUpdate *)update;
|
- (void)didUpdateFrame:(RCTFrameUpdate *)update;
|
||||||
|
|
||||||
@optional
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synthesize and set to true to pause the calls to -[didUpdateFrame:]
|
* Synthesize and set to true to pause the calls to -[didUpdateFrame:]
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign, getter=isPaused) BOOL paused;
|
@property (nonatomic, readonly, getter=isPaused) BOOL paused;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for pause/resume observer.
|
||||||
|
* Observer should call it when paused property is changed.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, copy) dispatch_block_t pauseCallback;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
|
|
||||||
@synthesize bridge = _bridge;
|
@synthesize bridge = _bridge;
|
||||||
@synthesize paused = _paused;
|
@synthesize paused = _paused;
|
||||||
|
@synthesize pauseCallback = _pauseCallback;
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ RCT_EXPORT_MODULE()
|
|||||||
|
|
||||||
- (void)stopTimers
|
- (void)stopTimers
|
||||||
{
|
{
|
||||||
_paused = YES;
|
self.paused = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startTimers
|
- (void)startTimers
|
||||||
@ -129,7 +130,17 @@ RCT_EXPORT_MODULE()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_paused = NO;
|
self.paused = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPaused:(BOOL)paused
|
||||||
|
{
|
||||||
|
if (_paused != paused) {
|
||||||
|
_paused = paused;
|
||||||
|
if (_pauseCallback) {
|
||||||
|
_pauseCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didUpdateFrame:(__unused RCTFrameUpdate *)update
|
- (void)didUpdateFrame:(__unused RCTFrameUpdate *)update
|
||||||
|
@ -269,6 +269,7 @@ NSInteger kNeverProgressed = -10000;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@synthesize paused = _paused;
|
@synthesize paused = _paused;
|
||||||
|
@synthesize pauseCallback = _pauseCallback;
|
||||||
|
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||||
{
|
{
|
||||||
@ -321,6 +322,16 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setPaused:(BOOL)paused
|
||||||
|
{
|
||||||
|
if (_paused != paused) {
|
||||||
|
_paused = paused;
|
||||||
|
if (_pauseCallback) {
|
||||||
|
_pauseCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
_navigationController.delegate = nil;
|
_navigationController.delegate = nil;
|
||||||
@ -355,14 +366,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||||||
_dummyView.frame = (CGRect){{destination, 0}, CGSizeZero};
|
_dummyView.frame = (CGRect){{destination, 0}, CGSizeZero};
|
||||||
_currentlyTransitioningFrom = indexOfFrom;
|
_currentlyTransitioningFrom = indexOfFrom;
|
||||||
_currentlyTransitioningTo = indexOfTo;
|
_currentlyTransitioningTo = indexOfTo;
|
||||||
_paused = NO;
|
self.paused = NO;
|
||||||
}
|
}
|
||||||
completion:^(__unused id<UIViewControllerTransitionCoordinatorContext> context) {
|
completion:^(__unused id<UIViewControllerTransitionCoordinatorContext> context) {
|
||||||
[weakSelf freeLock];
|
[weakSelf freeLock];
|
||||||
_currentlyTransitioningFrom = 0;
|
_currentlyTransitioningFrom = 0;
|
||||||
_currentlyTransitioningTo = 0;
|
_currentlyTransitioningTo = 0;
|
||||||
_dummyView.frame = CGRectZero;
|
_dummyView.frame = CGRectZero;
|
||||||
_paused = YES;
|
self.paused = YES;
|
||||||
// Reset the parallel position tracker
|
// Reset the parallel position tracker
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user