mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix NativeAnimatedModule timing for Fabric/Venice(?)
Summary: This is the second part of a rewrite of D15390384, which allows Animated timing to be driven by Paper or Fabric. The intuition is: we don't care which one drives the animation. We will expect one or both of them to issue a callback that operations are about to be executed, and the first one wins. The blocks will only execute once, the second time will be a noop. I don't think there's a 100% safe way of reimplementing Native Animated Module for Fabric/Venice (without a new API and implementing in C++) since it's inherently disconnected from the commit process and the tree. This gets us slightly closer to visual functionality, though. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21698192 fbshipit-source-id: c11d3cebd12cfc8acf4b63c87ccbe62cdbd8b672
This commit is contained in:
committed by
Facebook GitHub Bot
parent
0b00d92514
commit
8e1348046a
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.facebook.react.animated;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import com.facebook.common.logging.FLog;
|
||||
@@ -30,6 +31,8 @@ import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Module that exposes interface for creating and managing animated nodes on the "native" side.
|
||||
@@ -85,10 +88,13 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
void execute(NativeAnimatedNodesManager animatedNodesManager);
|
||||
}
|
||||
|
||||
private final GuardedFrameCallback mAnimatedFrameCallback;
|
||||
@NonNull private final GuardedFrameCallback mAnimatedFrameCallback;
|
||||
private final ReactChoreographer mReactChoreographer;
|
||||
private ArrayList<UIThreadOperation> mOperations = new ArrayList<>();
|
||||
private ArrayList<UIThreadOperation> mPreOperations = new ArrayList<>();
|
||||
@NonNull private List<UIThreadOperation> mOperations = new ArrayList<>();
|
||||
@NonNull private List<UIThreadOperation> mPreOperations = new ArrayList<>();
|
||||
|
||||
@NonNull private List<UIBlock> mPreOperationsUIBlock = new ArrayList<>();
|
||||
@NonNull private List<UIBlock> mOperationsUIBlock = new ArrayList<>();
|
||||
|
||||
private @Nullable NativeAnimatedNodesManager mNodesManager;
|
||||
|
||||
@@ -145,12 +151,31 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
|
||||
// For FabricUIManager
|
||||
@Override
|
||||
public void willDispatchPreMountItems() {}
|
||||
@UiThread
|
||||
public void willDispatchPreMountItems() {
|
||||
if (mPreOperationsUIBlock.size() != 0) {
|
||||
List<UIBlock> preOperations = mPreOperationsUIBlock;
|
||||
mPreOperationsUIBlock = new ArrayList<>();
|
||||
|
||||
for (UIBlock op : preOperations) {
|
||||
op.execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For FabricUIManager
|
||||
@Override
|
||||
@UiThread
|
||||
public void willDispatchMountItems() {}
|
||||
public void willDispatchMountItems() {
|
||||
if (mOperationsUIBlock.size() != 0) {
|
||||
List<UIBlock> operations = mOperationsUIBlock;
|
||||
mOperationsUIBlock = new ArrayList<>();
|
||||
|
||||
for (UIBlock op : operations) {
|
||||
op.execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For non-FabricUIManager
|
||||
@Override
|
||||
@@ -159,8 +184,11 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
if (mOperations.isEmpty() && mPreOperations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<UIThreadOperation> preOperations = mPreOperations;
|
||||
final ArrayList<UIThreadOperation> operations = mOperations;
|
||||
|
||||
final AtomicBoolean hasRunPreOperations = new AtomicBoolean(false);
|
||||
final AtomicBoolean hasRunOperations = new AtomicBoolean(false);
|
||||
final List<UIThreadOperation> preOperations = mPreOperations;
|
||||
final List<UIThreadOperation> operations = mOperations;
|
||||
mPreOperations = new ArrayList<>();
|
||||
mOperations = new ArrayList<>();
|
||||
|
||||
@@ -171,26 +199,44 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
// This goes away entirely in Fabric/Venice.
|
||||
UIManagerModule uiManagerModule = (UIManagerModule) uiManager;
|
||||
|
||||
uiManagerModule.prependUIBlock(
|
||||
UIBlock preOperationsUIBlock =
|
||||
new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
if (!hasRunPreOperations.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeAnimatedNodesManager nodesManager = getNodesManager();
|
||||
for (UIThreadOperation operation : preOperations) {
|
||||
operation.execute(nodesManager);
|
||||
}
|
||||
}
|
||||
});
|
||||
uiManagerModule.addUIBlock(
|
||||
};
|
||||
|
||||
UIBlock operationsUIBlock =
|
||||
new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
if (!hasRunOperations.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeAnimatedNodesManager nodesManager = getNodesManager();
|
||||
for (UIThreadOperation operation : operations) {
|
||||
operation.execute(nodesManager);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Queue up operations for Fabric
|
||||
mPreOperationsUIBlock.add(preOperationsUIBlock);
|
||||
mOperationsUIBlock.add(operationsUIBlock);
|
||||
|
||||
// Here we queue up the UI Blocks for the old, non-Fabric UIManager.
|
||||
// We queue them in both systems, let them race, and see which wins.
|
||||
uiManagerModule.prependUIBlock(preOperationsUIBlock);
|
||||
uiManagerModule.addUIBlock(operationsUIBlock);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user