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.EXACTLY;
|
||||
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 android.os.SystemClock;
|
||||
@ -22,7 +21,6 @@ import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
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.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.UIManagerHelper;
|
||||
import com.facebook.react.uimanager.UIViewOperationQueue;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
||||
import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import com.facebook.systrace.SystraceMessage;
|
||||
@ -295,10 +291,10 @@ public class FabricUIManager implements UIManager, JSHandler {
|
||||
"FabricUIManager.appendChild")
|
||||
.flush();
|
||||
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.
|
||||
//TODO: T27926878 avoid cloning shared child
|
||||
if (child.getParent() != null) {
|
||||
if (child.isSealed()) {
|
||||
child = child.mutableCopy(child.getInstanceHandle());
|
||||
}
|
||||
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
|
||||
node.setOriginalReactShadowNode(null);
|
||||
node.markUpdateSeen();
|
||||
node.markAsSealed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -377,4 +377,16 @@ public interface ReactShadowNode<T extends ReactShadowNode> {
|
||||
long getInstanceHandle();
|
||||
|
||||
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 long mInstanceHandle;
|
||||
private boolean mIsSealed = false;
|
||||
|
||||
public ReactShadowNodeImpl() {
|
||||
mDefaultPadding = new Spacing(0);
|
||||
@ -164,6 +165,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
|
||||
mNewProps = null;
|
||||
mParent = null;
|
||||
mOriginalReactShadowNode = original;
|
||||
mIsSealed = false;
|
||||
}
|
||||
|
||||
private void replaceChild(ReactShadowNodeImpl newNode, int childIndex) {
|
||||
@ -1147,4 +1149,14 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
|
||||
public void setInstanceHandle(long 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);
|
||||
}
|
||||
|
||||
@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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user