Permalink
Browse files

New UIManager API allowing intercept/delay mounting process

Summary: In some embedding/interop cases (RN inside, something else outside), the interop layer has to have the ability to control (intercept, delay, perform synchronously with another stuff) mounting process. This API allows doing that.

Reviewed By: fkgozali

Differential Revision: D7014179

fbshipit-source-id: 04036095f7e60a5ff7e69025ff6066fea92eb361
  • Loading branch information...
shergin authored and facebook-github-bot committed Feb 21, 2018
1 parent 60c0000 commit 402ae2f01fd91051be5b717b0578e18b863854af
@@ -1081,21 +1081,36 @@ - (void)flushUIBlocksWithCompletion:(void (^)(void))completion;
return;
}
// Execute the previously queued UI blocks
RCTProfileBeginFlowEvent();
RCTExecuteOnMainQueue(^{
RCTProfileEndFlowEvent();
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[UIManager flushUIBlocks]", (@{
@"count": [@(previousPendingUIBlocks.count) stringValue],
}));
__weak typeof(self) weakSelf = self;
void (^mountingBlock)(void) = ^{
typeof(self) strongSelf = weakSelf;
@try {
for (RCTViewManagerUIBlock block in previousPendingUIBlocks) {
block(self, self->_viewRegistry);
block(strongSelf, strongSelf->_viewRegistry);
}
}
@catch (NSException *exception) {
RCTLogError(@"Exception thrown while executing UI block: %@", exception);
}
};
if ([self.observerCoordinator uiManager:self performMountingWithBlock:mountingBlock]) {
completion();
return;
}
// Execute the previously queued UI blocks
RCTProfileBeginFlowEvent();
RCTExecuteOnMainQueue(^{
RCTProfileEndFlowEvent();
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[UIManager flushUIBlocks]", (@{
@"count": [@(previousPendingUIBlocks.count) stringValue],
}));
mountingBlock();
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
RCTExecuteOnUIManagerQueue(completion);
@@ -9,6 +9,8 @@
#import <React/RCTViewManager.h>
typedef dispatch_block_t RCTUIManagerMountingBlock;
/**
* Allows hooking into UIManager internals. This can be used to execute code at
* specific points during the view updating process.
@@ -43,6 +45,13 @@
*/
- (void)uiManagerWillPerformMounting:(RCTUIManager *)manager;
/**
* Called right before flushing UI blocks and allows to intercept the mounting process.
* Return `YES` to cancel default execution of the `block` (and perform the
* execution later).
*/
- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block;
/**
* Called just after flushing UI blocks.
* This is called from the UIManager queue.
@@ -72,6 +72,20 @@ - (void)uiManagerWillPerformMounting:(RCTUIManager *)manager
}
}
- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block
{
std::lock_guard<std::mutex> lock(_mutex);
for (id<RCTUIManagerObserver> observer in _observers) {
if ([observer respondsToSelector:@selector(uiManager:performMountingWithBlock:)]) {
if ([observer uiManager:manager performMountingWithBlock:block]) {
return YES;
}
}
}
return NO;
}
- (void)uiManagerDidPerformMounting:(RCTUIManager *)manager
{
std::lock_guard<std::mutex> lock(_mutex);

0 comments on commit 402ae2f

Please sign in to comment.