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 @@ -5,6 +5,7 @@
#include <reanimated/LayoutAnimations/LayoutAnimationsProxy.h>

#include <react/renderer/uimanager/UIManagerCommitHook.h>
#include <react/renderer/mounting/ShadowTree.h>

#include <memory>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ std::shared_ptr<ShadowNode> cloneShadowTreeWithNewPropsRecursive(

Props::Shared newProps = mergeProps(shadowNode, propsMap, *family);

#ifdef ANDROID
if (newProps) {
ReanimatedSystraceSection s("ShadowTreeCloner::equalityCheck");

Expand All @@ -97,6 +98,7 @@ std::shared_ptr<ShadowNode> cloneShadowTreeWithNewPropsRecursive(
tagsToRemove.push_back(shadowNode.getTag());
}
}
#endif

return shadowNode.clone(
{newProps ? newProps : ShadowNodeFragment::propsPlaceholder(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ void LayoutAnimationsProxy::addOngoingAnimations(
for (auto &[tag, updateValues] : updateMap) {
#ifdef ANDROID
i++;
if (correctedTags[i] == -1) {
if (correctedTags && correctedTags[i] == -1) {
// skip views that have not been mounted yet
// on Android we start entering animations from the JS thread
// so it might happen, that the first frame of the animation goes through
Expand Down Expand Up @@ -890,6 +890,7 @@ void LayoutAnimationsProxy::transferConfigFromNativeID(
layoutAnimationsManager_->transferConfigFromNativeID(nativeId, tag);
} catch (std::invalid_argument) {
} catch (std::out_of_range) {
} catch (...) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs further investigation. In the monorepo this is throwing an invalid_argument exception but not being caught.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i remember we already fixed that once somewhere.
I think the bug was that auto nativeId = stoi(nativeIdString); the nativeid is usually a number, but when the user sets the nativeId prop as a regular text then this can throw, let me find what we did back then …

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right, the std::invalid_argument should catch this but in the past didn't due to misconfigured rtti and exceptions flags:

we should double check if we did regress that?

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -696,28 +696,38 @@ void ReanimatedModuleProxy::unmarkNodeAsRemovable(
/**
* Returns false if there are no layout props, true if there are.
*/
bool ReanimatedModuleProxy::updateNoneLayoutProps(const folly::dynamic &props, Tag tag) {
folly::dynamic nonLayoutProps = nullptr;
bool hasLayoutProps = false;
for (const auto& prop : props.items()) {
const std::string propName = prop.first.asString();
bool isLayoutProp = collection::contains(nativePropNames_, propName);
if (isLayoutProp) {
hasLayoutProps = true;
continue;
}
bool ReanimatedModuleProxy::updateNoneLayoutProps(
jsi::Runtime &rt,
const jsi::Object &props,
Tag tag) {

if (nonLayoutProps == nullptr) {
nonLayoutProps = folly::dynamic::object();
}
nonLayoutProps.insert(propName, prop.second);
}
jsi::Object nonLayoutPropsJSI(rt);
bool hasNonLayoutProps = false;
bool hasLayoutProps = false;

if (nonLayoutProps.isObject()) {
synchronouslyUpdateUIPropsFunction_(tag, nonLayoutProps);
}
auto propNames = props.getPropertyNames(rt);
size_t size = propNames.size(rt);

for (size_t i = 0; i < size; i++) {
auto propName = propNames.getValueAtIndex(rt, i).asString(rt);
std::string propNameStr = propName.utf8(rt);

return hasLayoutProps;
bool isLayoutProp = collection::contains(nativePropNames_, propNameStr);

if (isLayoutProp) {
hasLayoutProps = true;
} else {
hasNonLayoutProps = true;
auto propValue = props.getProperty(rt, propName);
nonLayoutPropsJSI.setProperty(rt, propName, propValue);
}
}

if (hasNonLayoutProps) {
synchronouslyUpdateUIPropsFunction_(rt, tag, nonLayoutPropsJSI);
}

return hasLayoutProps;
}

jsi::Value ReanimatedModuleProxy::filterNonAnimatableProps(
Expand Down Expand Up @@ -863,13 +873,17 @@ void ReanimatedModuleProxy::performOperations() {
// way but backgroundColor, shadowOpacity etc. would get overwritten (see
// `_propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN`).
for (const auto &[shadowNode, props] : copiedOperationsQueue) {
folly::dynamic propsDynamic = dynamicFromValue(rt, *props);
auto tag = shadowNode->getTag();
bool hasLayoutUpdates = updateNoneLayoutProps(propsDynamic, tag);
if (hasLayoutUpdates) {
layoutUpdatesByTag.insert(tag);
}
propsRegistry_->update(shadowNode, std::move(propsDynamic));
auto tag = shadowNode->getTag();

// Pass the JSI object directly
bool hasLayoutUpdates = updateNoneLayoutProps(rt, props->asObject(rt), tag);
if (hasLayoutUpdates) {
layoutUpdatesByTag.insert(tag);
}

// Still need to convert to dynamic for propsRegistry
folly::dynamic propsDynamic = dynamicFromValue(rt, *props);
propsRegistry_->update(shadowNode, std::move(propsDynamic));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class ReanimatedModuleProxy
void requestAnimationFrame(jsi::Runtime &rt, const jsi::Value &callback);

#ifdef RCT_NEW_ARCH_ENABLED
bool updateNoneLayoutProps(const folly::dynamic &props, Tag tag);
bool updateNoneLayoutProps(jsi::Runtime &rt, const jsi::Object &props, Tag tag);
jsi::Value filterNonAnimatableProps(
jsi::Runtime &rt,
const jsi::Value &props);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ namespace reanimated {
#ifdef RCT_NEW_ARCH_ENABLED

using SynchronouslyUpdateUIPropsFunction =
std::function<void(Tag tag, const folly::dynamic &props)>;
std::function<void(jsi::Runtime &rt, Tag tag, const jsi::Object &props)>;
#ifndef ANDROID
using PreserveMountedTagsFunction =
std::function<std::optional<std::unique_ptr<int[]>>(std::vector<int> &)>;
#endif // !ANDROID
using UpdatePropsFunction =
std::function<void(jsi::Runtime &rt, const jsi::Value &operations)>;
using ObtainPropFunction = std::function<jsi::Value(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,10 @@ void NativeProxy::progressLayoutAnimation(

PlatformDepMethodsHolder NativeProxy::getPlatformDependentMethods() {
#ifdef RCT_NEW_ARCH_ENABLED
auto synchronouslyUpdateUIPropsFunction =
bindThis(&NativeProxy::synchronouslyUpdateUIProps);
auto synchronouslyUpdateUIPropsFunction = [this](jsi::Runtime &rt, Tag tag, const jsi::Object &props) {
folly::dynamic dynamicProps = jsi::dynamicFromValue(rt, jsi::Value(rt, props));
this->synchronouslyUpdateUIProps(tag, dynamicProps);
};
#else
auto updatePropsFunction = bindThis(&NativeProxy::updateProps);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ typedef void (^REAPerformOperations)();
- (void)dispatchEvent:(id<RCTEvent>)event;

#ifdef RCT_NEW_ARCH_ENABLED
- (void)setSurfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter;
- (void)registerPerformOperations:(REAPerformOperations)performOperations;
- (void)synchronouslyUpdateViewOnUIThread:(nonnull NSNumber *)viewTag props:(nonnull NSDictionary *)uiProps;
#else
- (void)configureUiProps:(nonnull NSSet<NSString *> *)uiPropsSet
andNativeProps:(nonnull NSSet<NSString *> *)nativePropsSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ @implementation REANodesManager {
#ifdef RCT_NEW_ARCH_ENABLED
__weak RCTBridge *_bridge;
REAPerformOperations _performOperations;
__weak id<RCTSurfacePresenterStub> _surfacePresenter;
NSMutableDictionary<NSNumber *, NSMutableDictionary *> *_operationsInBatch;
#else
NSMutableArray<REANativeAnimationOp> *_operationsInBatch;
Expand Down Expand Up @@ -201,6 +202,7 @@ - (nonnull instancetype)initWithModule:(REAModule *)reanimatedModule
{
if ((self = [super init])) {
_bridge = bridge;
_surfacePresenter = surfacePresenter;
_reanimatedModule = reanimatedModule;
_wantRunUpdates = NO;
_onAnimationCallbacks = [NSMutableArray new];
Expand Down Expand Up @@ -239,6 +241,13 @@ - (void)invalidate
[displayLink invalidate];
}];
}

#ifdef RCT_NEW_ARCH_ENABLED
- (void)setSurfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter
{
_surfacePresenter = surfacePresenter;
}
#endif

- (void)operationsBatchDidComplete
{
Expand Down Expand Up @@ -414,7 +423,22 @@ - (BOOL)isNativeViewMounted:(NSNumber *)viewTag
}

#ifdef RCT_NEW_ARCH_ENABLED
// nothing
- (void)synchronouslyUpdateViewOnUIThread:(nonnull NSNumber *)viewTag props:(nonnull NSDictionary *)uiProps
{
// adapted from RCTPropsAnimatedNode.m
RCTSurfacePresenter *surfacePresenter = _bridge.surfacePresenter ?: _surfacePresenter;
RCTComponentViewRegistry *componentViewRegistry = surfacePresenter.mountingManager.componentViewRegistry;
REAUIView<RCTComponentViewProtocol> *componentView =
[componentViewRegistry findComponentViewWithTag:[viewTag integerValue]];

NSSet<NSString *> *propKeysManagedByAnimated = [componentView propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN];
[surfacePresenter synchronouslyUpdateViewOnUIThread:viewTag props:uiProps];
[componentView setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:propKeysManagedByAnimated];

// `synchronouslyUpdateViewOnUIThread` does not flush props like `backgroundColor` etc.
// so that's why we need to call `finalizeUpdates` here.
[componentView finalizeUpdates:RNComponentViewUpdateMask{}];
}
#else

- (void)updateProps:(nonnull NSDictionary *)props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,25 @@ RequestRenderFunction makeRequestRender(REANodesManager *nodesManager)
}

#ifdef RCT_NEW_ARCH_ENABLED
// nothing
PreserveMountedTagsFunction makePreserveMountedTagsFunction()
{
//std::function<std::optional<std::unique_ptr<int[]>>(std::vector<int> &)>;
auto preserveMountedTagsFunction = [](std::vector<int> &tags) -> std::optional<std::unique_ptr<int[]>> {
// TODO: Implement me
return nullptr;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This didn't seem to be called by ios new arch and can maybe be left as a noop.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thats noop on iOS 👍

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering if we can also ifdef android that 🤔 thats how SWM did it in the v4 code:

but i'd also be fine with having this here + a comment 🤷

};
return preserveMountedTagsFunction;
}

SynchronouslyUpdateUIPropsFunction makeSynchronouslyUpdateUIPropsFunction(REANodesManager *nodesManager)
{
auto synchronouslyUpdateUIPropsFunction = [nodesManager](jsi::Runtime &rt, Tag tag, const jsi::Object &props) -> void {
NSNumber *viewTag = @(tag);
NSDictionary *uiProps = convertJSIObjectToNSDictionary(rt, props);
[nodesManager synchronouslyUpdateViewOnUIThread:viewTag props:uiProps];
};
return synchronouslyUpdateUIPropsFunction;
}
#else // RCT_NEW_ARCH_ENABLED
UpdatePropsFunction makeUpdatePropsFunction(REAModule *reaModule)
{
Expand Down Expand Up @@ -279,7 +297,9 @@ KeyboardEventUnsubscribeFunction makeUnsubscribeFromKeyboardEventsFunction(REAKe
auto requestRender = makeRequestRender(nodesManager);

#ifdef RCT_NEW_ARCH_ENABLED
// nothing
auto preserveMountedTagsFunction = makePreserveMountedTagsFunction();

auto synchronouslyUpdateUIPropsFunction = makeSynchronouslyUpdateUIPropsFunction(nodesManager);
#else
RCTUIManager *uiManager = nodesManager.uiManager;
auto updatePropsFunction = makeUpdatePropsFunction(reaModule);
Expand Down Expand Up @@ -338,7 +358,7 @@ KeyboardEventUnsubscribeFunction makeUnsubscribeFromKeyboardEventsFunction(REAKe
PlatformDepMethodsHolder platformDepMethodsHolder = {
requestRender,
#ifdef RCT_NEW_ARCH_ENABLED
// nothing
synchronouslyUpdateUIPropsFunction,
#else
updatePropsFunction,
scrollToFunction,
Expand Down Expand Up @@ -367,6 +387,10 @@ PlatformDepMethodsHolder makePlatformDepMethodsHolderBridgeless(
REAModule *reaModule)
{
auto requestRender = makeRequestRender(nodesManager);

auto preserveMountedTagsFunction = makePreserveMountedTagsFunction();

auto synchronouslyUpdateUIPropsFunction = makeSynchronouslyUpdateUIPropsFunction(nodesManager);

auto getAnimationTimestamp = makeGetAnimationTimestamp();

Expand All @@ -392,6 +416,7 @@ PlatformDepMethodsHolder makePlatformDepMethodsHolderBridgeless(

PlatformDepMethodsHolder platformDepMethodsHolder = {
requestRender,
synchronouslyUpdateUIPropsFunction,
getAnimationTimestamp,
progressLayoutAnimation,
endLayoutAnimation,
Expand Down
Loading