mirror of
https://github.com/status-im/react-native.git
synced 2025-02-27 00:20:31 +00:00
Introduce "Sealing" of ReactShadowNodes
Summary: This diff introduces the concept of "Seal" ReactShadowNodes. This new field will be used to guarantee immutability of commited ReactShodow Nodes. Reviewed By: fkgozali Differential Revision: D8552709 fbshipit-source-id: dfd95730f10341af0dd762f8a8aa186563cf33e9
This commit is contained in:
parent
f19c36116c
commit
001e217f33
@ -10,7 +10,6 @@ package com.facebook.react.fabric;
|
|||||||
import static android.view.View.MeasureSpec.AT_MOST;
|
import static android.view.View.MeasureSpec.AT_MOST;
|
||||||
import static android.view.View.MeasureSpec.EXACTLY;
|
import static android.view.View.MeasureSpec.EXACTLY;
|
||||||
import static android.view.View.MeasureSpec.UNSPECIFIED;
|
import static android.view.View.MeasureSpec.UNSPECIFIED;
|
||||||
import static com.facebook.react.uimanager.common.UIManagerType.DEFAULT;
|
|
||||||
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
|
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@ -22,7 +21,6 @@ import com.facebook.infer.annotation.Assertions;
|
|||||||
import com.facebook.proguard.annotations.DoNotStrip;
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
import com.facebook.react.bridge.ReadableNativeMap;
|
||||||
@ -41,13 +39,11 @@ import com.facebook.react.uimanager.ReactShadowNode;
|
|||||||
import com.facebook.react.uimanager.ReactShadowNodeImpl;
|
import com.facebook.react.uimanager.ReactShadowNodeImpl;
|
||||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.UIManagerHelper;
|
|
||||||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||||
import com.facebook.react.uimanager.ViewManager;
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
||||||
import com.facebook.react.uimanager.common.ViewUtil;
|
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
import com.facebook.systrace.Systrace;
|
import com.facebook.systrace.Systrace;
|
||||||
import com.facebook.systrace.SystraceMessage;
|
import com.facebook.systrace.SystraceMessage;
|
||||||
@ -295,10 +291,10 @@ public class FabricUIManager implements UIManager, JSHandler {
|
|||||||
"FabricUIManager.appendChild")
|
"FabricUIManager.appendChild")
|
||||||
.flush();
|
.flush();
|
||||||
try {
|
try {
|
||||||
// If the child to append is shared with another tree (child.getParent() != null),
|
// If the child to append was already committed (child.isSealed()),
|
||||||
// then we add a mutation of it. In the future this will be performed by FabricJS / Fiber.
|
// then we add a mutation of it. In the future this will be performed by FabricJS / Fiber.
|
||||||
//TODO: T27926878 avoid cloning shared child
|
//TODO: T27926878 avoid cloning shared child
|
||||||
if (child.getParent() != null) {
|
if (child.isSealed()) {
|
||||||
child = child.mutableCopy(child.getInstanceHandle());
|
child = child.mutableCopy(child.getInstanceHandle());
|
||||||
}
|
}
|
||||||
parent.addChildAt(child, parent.getChildCount());
|
parent.addChildAt(child, parent.getChildCount());
|
||||||
@ -474,6 +470,7 @@ public class FabricUIManager implements UIManager, JSHandler {
|
|||||||
// and we do not need to hold references to the previous tree anymore
|
// and we do not need to hold references to the previous tree anymore
|
||||||
node.setOriginalReactShadowNode(null);
|
node.setOriginalReactShadowNode(null);
|
||||||
node.markUpdateSeen();
|
node.markUpdateSeen();
|
||||||
|
node.markAsSealed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -377,4 +377,16 @@ public interface ReactShadowNode<T extends ReactShadowNode> {
|
|||||||
long getInstanceHandle();
|
long getInstanceHandle();
|
||||||
|
|
||||||
void setInstanceHandle(long instanceHandle);
|
void setInstanceHandle(long instanceHandle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark this {@link ReactShadowNode} as sealed. This means that the node was already committed
|
||||||
|
* and it should not be updated anymore.
|
||||||
|
*/
|
||||||
|
void markAsSealed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link boolean} that represents if the {@link ReactShadowNode} is sealed.
|
||||||
|
*/
|
||||||
|
boolean isSealed();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
|
|||||||
|
|
||||||
private @Nullable ReactStylesDiffMap mNewProps;
|
private @Nullable ReactStylesDiffMap mNewProps;
|
||||||
private long mInstanceHandle;
|
private long mInstanceHandle;
|
||||||
|
private boolean mIsSealed = false;
|
||||||
|
|
||||||
public ReactShadowNodeImpl() {
|
public ReactShadowNodeImpl() {
|
||||||
mDefaultPadding = new Spacing(0);
|
mDefaultPadding = new Spacing(0);
|
||||||
@ -164,6 +165,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
|
|||||||
mNewProps = null;
|
mNewProps = null;
|
||||||
mParent = null;
|
mParent = null;
|
||||||
mOriginalReactShadowNode = original;
|
mOriginalReactShadowNode = original;
|
||||||
|
mIsSealed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceChild(ReactShadowNodeImpl newNode, int childIndex) {
|
private void replaceChild(ReactShadowNodeImpl newNode, int childIndex) {
|
||||||
@ -1147,4 +1149,14 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
|
|||||||
public void setInstanceHandle(long instanceHandle) {
|
public void setInstanceHandle(long instanceHandle) {
|
||||||
mInstanceHandle = instanceHandle;
|
mInstanceHandle = instanceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markAsSealed() {
|
||||||
|
mIsSealed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSealed() {
|
||||||
|
return mIsSealed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,24 @@ public class FabricUIManagerTest {
|
|||||||
mFabricUIManager.completeRoot(rootTag, children);
|
mFabricUIManager.completeRoot(rootTag, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSealReactShadowNode() {
|
||||||
|
ReactRootView rootView =
|
||||||
|
new ReactRootView(RuntimeEnvironment.application.getApplicationContext());
|
||||||
|
int rootTag = mFabricUIManager.addRootView(rootView);
|
||||||
|
String viewClass = ReactViewManager.REACT_CLASS;
|
||||||
|
|
||||||
|
ReactShadowNode container = mFabricUIManager.createNode(6, viewClass, rootTag, null, randomInstanceHandle());
|
||||||
|
List<ReactShadowNode> childSet = mFabricUIManager.createChildSet(rootTag);
|
||||||
|
mFabricUIManager.appendChildToSet(childSet, container);
|
||||||
|
|
||||||
|
assertThat(container.isSealed()).isFalse();
|
||||||
|
|
||||||
|
mFabricUIManager.completeRoot(rootTag, childSet);
|
||||||
|
|
||||||
|
assertThat(container.isSealed()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that cloned text nodes will not share measure functions
|
* Tests that cloned text nodes will not share measure functions
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user