Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
changedProps:(folly::dynamic)props
componentDescriptor:(const facebook::react::ComponentDescriptor &)componentDescriptor;

- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag withProps:(facebook::react::Props::Shared)newProps;
@end

NS_ASSUME_NONNULL_END
35 changes: 35 additions & 0 deletions packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,41 @@ - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
[componentView finalizeUpdates:RNComponentViewUpdateMaskProps];
}

- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag withProps:(Props::Shared)newProps
{
RCTAssertMainQueue();

UIView<RCTComponentViewProtocol> *componentView = [_componentViewRegistry findComponentViewWithTag:reactTag];
if (!componentView) {
RCTLogWarn(@"Attempted to update view with tag %ld, but it no longer exists", (long)reactTag);
return;
}

NSSet<NSString *> *propKeys = componentView.propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN ?: [NSSet new];

Props::Shared oldProps = [componentView props];

componentView.propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = nil;
[componentView updateProps:newProps oldProps:oldProps];
componentView.propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = propKeys;

const auto &newViewProps = static_cast<const ViewProps &>(*newProps);

if (componentView.layer.opacity != (float)newViewProps.opacity) {
componentView.layer.opacity = newViewProps.opacity;
}

auto layoutMetrics = LayoutMetrics();
layoutMetrics.frame.size.width = componentView.layer.bounds.size.width;
layoutMetrics.frame.size.height = componentView.layer.bounds.size.height;
CATransform3D newTransform = RCTCATransform3DFromTransformMatrix(newViewProps.resolveTransform(layoutMetrics));
if (!CATransform3DEqualToTransform(newTransform, componentView.layer.transform)) {
componentView.layer.transform = newTransform;
}

[componentView finalizeUpdates:RNComponentViewUpdateMaskProps];
}

- (void)synchronouslyDispatchCommandOnUIThread:(ReactTag)reactTag
commandName:(NSString *)commandName
args:(NSArray *)args
Expand Down
9 changes: 9 additions & 0 deletions packages/react-native/React/Fabric/RCTScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#import <react/renderer/uimanager/UIManager.h>
#import <react/utils/ContextContainer.h>

namespace facebook::react {
struct AnimatedProps;
} // namespace facebook::react

NS_ASSUME_NONNULL_BEGIN

/**
Expand All @@ -45,6 +49,11 @@ NS_ASSUME_NONNULL_BEGIN
forShadowView:(const facebook::react::ShadowView &)shadowView;

- (void)schedulerDidSynchronouslyUpdateViewOnUIThread:(facebook::react::Tag)reactTag props:(folly::dynamic)props;

- (void)schedulerDidSynchronouslyUpdateViewWithAnimatedPropsOnUIThread:(facebook::react::Tag)reactTag
surfaceId:(facebook::react::SurfaceId)surfaceId
animatedProps:
(const facebook::react::AnimatedProps &)animatedProps;
@end

/**
Expand Down
13 changes: 13 additions & 0 deletions packages/react-native/React/Fabric/RCTScheduler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <QuartzCore/CADisplayLink.h>
#import <cxxreact/TraceSection.h>
#import <react/featureflags/ReactNativeFeatureFlags.h>
#import <react/renderer/animationbackend/AnimatedProps.h>
#import <react/renderer/animations/LayoutAnimationDriver.h>
#import <react/renderer/componentregistry/ComponentDescriptorFactory.h>
#import <react/renderer/scheduler/Scheduler.h>
Expand Down Expand Up @@ -79,6 +80,18 @@ void schedulerShouldSynchronouslyUpdateViewOnUIThread(facebook::react::Tag tag,
[scheduler.delegate schedulerDidSynchronouslyUpdateViewOnUIThread:tag props:props];
}

void schedulerShouldSynchronouslyUpdateAnimatedPropsOnUIThread(
SurfaceId surfaceId,
const std::unordered_map<Tag, AnimatedProps> &updates) override
{
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
for (const auto &[tag, animatedProps] : updates) {
[scheduler.delegate schedulerDidSynchronouslyUpdateViewWithAnimatedPropsOnUIThread:tag
surfaceId:surfaceId
animatedProps:animatedProps];
}
}

void schedulerDidUpdateShadowTree(const std::unordered_map<Tag, folly::dynamic> &tagToProps) override
{
// Does nothing.
Expand Down
40 changes: 40 additions & 0 deletions packages/react-native/React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
#import <react/utils/FollyConvert.h>

#import <react/featureflags/ReactNativeFeatureFlags.h>
#import <react/renderer/animationbackend/AnimatedProps.h>
#import <react/renderer/componentregistry/ComponentDescriptorFactory.h>
#import <react/renderer/components/text/BaseTextProps.h>
#import <react/renderer/components/view/BaseViewProps.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/scheduler/SchedulerToolbox.h>
#import <react/utils/ContextContainer.h>
Expand Down Expand Up @@ -416,6 +418,44 @@ - (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder
[_mountingManager setIsJSResponder:isJSResponder blockNativeResponder:blockNativeResponder forShadowView:shadowView];
}

- (void)schedulerDidSynchronouslyUpdateViewWithAnimatedPropsOnUIThread:(Tag)tag
surfaceId:(SurfaceId)surfaceId
animatedProps:(const AnimatedProps &)animatedProps
{
RCTScheduler *scheduler = [self scheduler];
if (!scheduler) {
return;
}

UIView<RCTComponentViewProtocol> *componentView =
[_mountingManager.componentViewRegistry findComponentViewWithTag:tag];
if (componentView == nil) {
return;
}
ComponentHandle handle = [[componentView class] componentDescriptorProvider].handle;
auto *componentDescriptor = [scheduler findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN:handle];
if (!componentDescriptor) {
return;
}

Props::Shared oldProps = [componentView props];
PropsParserContext propsParserContext{surfaceId, *[self contextContainer]};

Props::Shared newProps;
if (animatedProps.rawProps) {
newProps = componentDescriptor->cloneProps(propsParserContext, oldProps, RawProps(*animatedProps.rawProps));
} else {
newProps = componentDescriptor->cloneProps(propsParserContext, oldProps, RawProps{});
}

auto viewProps = std::const_pointer_cast<BaseViewProps>(std::static_pointer_cast<const BaseViewProps>(newProps));
for (auto &animatedProp : animatedProps.props) {
cloneProp(*viewProps, *animatedProp);
}

[_mountingManager synchronouslyUpdateViewOnUIThread:tag withProps:newProps];
}

- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer
{
std::unique_lock lock(_observerListMutex);
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -2267,6 +2267,7 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid
public fun stopSurface (I)V
public fun stopSurface (Lcom/facebook/react/fabric/SurfaceHandlerBinding;)V
public fun sweepActiveTouchForTag (II)V
public fun synchronouslyUpdateViewBatch ([I[D)V
public fun synchronouslyUpdateViewOnUIThread (ILcom/facebook/react/bridge/ReadableMap;)V
public fun updateRootLayoutSpecs (IIIII)V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
import com.facebook.react.fabric.mounting.mountitems.BatchMountItem;
import com.facebook.react.fabric.mounting.mountitems.BatchedAnimatedPropsMountItem;
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
import com.facebook.react.fabric.mounting.mountitems.MountItemFactory;
Expand Down Expand Up @@ -858,6 +859,16 @@ private synchronized ViewTransitionSnapshotManager getViewTransitionSnapshotMana
return mViewTransitionSnapshotManager;
}

@SuppressWarnings("unused")
@UiThread
@ThreadConfined(UI)
public void synchronouslyUpdateViewBatch(final int[] intBuffer, final double[] doubleBuffer) {
UiThreadUtil.assertOnUiThread();

MountItem mountItem = new BatchedAnimatedPropsMountItem(intBuffer, doubleBuffer);
mountItem.execute(mMountingManager);
}

@SuppressLint("NotInvokedPrivateMethod")
@SuppressWarnings("unused")
@AnyThread
Expand Down
Loading
Loading