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
This commit is contained in:
parent
60c000022e
commit
402ae2f01f
|
@ -1081,6 +1081,26 @@ RCT_EXPORT_METHOD(dispatchViewManagerCommand:(nonnull NSNumber *)reactTag
|
|||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
void (^mountingBlock)(void) = ^{
|
||||
typeof(self) strongSelf = weakSelf;
|
||||
|
||||
@try {
|
||||
for (RCTViewManagerUIBlock block in previousPendingUIBlocks) {
|
||||
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(^{
|
||||
|
@ -1088,14 +1108,9 @@ RCT_EXPORT_METHOD(dispatchViewManagerCommand:(nonnull NSNumber *)reactTag
|
|||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[UIManager flushUIBlocks]", (@{
|
||||
@"count": [@(previousPendingUIBlocks.count) stringValue],
|
||||
}));
|
||||
@try {
|
||||
for (RCTViewManagerUIBlock block in previousPendingUIBlocks) {
|
||||
block(self, self->_viewRegistry);
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Exception thrown while executing UI block: %@", exception);
|
||||
}
|
||||
|
||||
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 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (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);
|
||||
|
|
Loading…
Reference in New Issue