diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java index 87950f69f..92e5badc6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -67,6 +67,11 @@ public interface ReactShadowNode { */ boolean isYogaLeafNode(); + /** + * @return a mutable copy of the {@link ReactShadowNode} + */ + T mutableCopy(); + String getViewClass(); boolean hasUpdates(); @@ -127,8 +132,11 @@ public interface ReactShadowNode { T getRootNode(); + @Deprecated() //Replaced by setRootTag method. void setRootNode(T rootNode); + void setRootTag(int rootTag); + void setViewClassName(String viewClassName); @Nullable @@ -159,6 +167,8 @@ public interface ReactShadowNode { T removeNativeChildAt(int i); + void removeAllChildren(); + void removeAllNativeChildren(); int getNativeChildCount(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java index e6bb9a586..1029519ec 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java @@ -6,6 +6,8 @@ */ package com.facebook.react.uimanager; +import static java.lang.System.arraycopy; + import com.facebook.infer.annotation.Assertions; import com.facebook.react.uimanager.annotations.ReactPropertyHolder; import com.facebook.yoga.YogaAlign; @@ -53,9 +55,17 @@ import javax.annotation.Nullable; @ReactPropertyHolder public class ReactShadowNodeImpl implements ReactShadowNode { + private static final YogaConfig sYogaConfig; + static { + sYogaConfig = new YogaConfig(); + sYogaConfig.setPointScaleFactor(0f); + sYogaConfig.setUseLegacyStretchBehaviour(true); + } + private int mReactTag; private @Nullable String mViewClassName; private @Nullable ReactShadowNodeImpl mRootNode; + private int mRootTag; private @Nullable ThemedReactContext mThemedContext; private boolean mShouldNotifyOnLayout; private boolean mNodeUpdated = true; @@ -75,26 +85,50 @@ public class ReactShadowNodeImpl implements ReactShadowNode private final float[] mPadding = new float[Spacing.ALL + 1]; private final boolean[] mPaddingIsPercent = new boolean[Spacing.ALL + 1]; private final YogaNode mYogaNode; - private static YogaConfig sYogaConfig; public ReactShadowNodeImpl() { if (!isVirtual()) { YogaNode node = YogaNodePool.get().acquire(); - if (sYogaConfig == null) { - sYogaConfig = new YogaConfig(); - sYogaConfig.setPointScaleFactor(0f); - sYogaConfig.setUseLegacyStretchBehaviour(true); - } - if (node == null) { - node = new YogaNode(sYogaConfig); - } - mYogaNode = node; + mYogaNode = node == null ? new YogaNode(sYogaConfig) : node; Arrays.fill(mPadding, YogaConstants.UNDEFINED); } else { mYogaNode = null; } } + public ReactShadowNodeImpl(ReactShadowNodeImpl original) { + try { + mReactTag = original.mReactTag; + mRootTag = original.mRootTag; + mViewClassName = original.mViewClassName; + mRootNode = original.mRootNode; + mThemedContext = original.mThemedContext; + mShouldNotifyOnLayout = original.mShouldNotifyOnLayout; + mNodeUpdated = original.mNodeUpdated; + mChildren = original.mChildren == null ? null : new ArrayList<>(original.mChildren); + mParent = original.mParent; + mIsLayoutOnly = original.mIsLayoutOnly; + mTotalNativeChildren = original.mTotalNativeChildren; + mNativeParent = original.mNativeParent; + mNativeChildren = original.mNativeChildren == null ? null : new ArrayList<>(original.mNativeChildren); + mNativeParent = original.mNativeParent; + mScreenX = original.mScreenX; + mScreenY = original.mScreenY; + mScreenWidth = original.mScreenWidth; + mScreenHeight = original.mScreenHeight; + arraycopy(original.mPadding, 0, mPadding, 0, original.mPadding.length); + arraycopy(original.mPaddingIsPercent, 0, mPaddingIsPercent, 0, original.mPaddingIsPercent.length); + mYogaNode = original.mYogaNode.clone(); + } catch (CloneNotSupportedException e) { + // it should never happen + throw new IllegalArgumentException(); + } + } + + public ReactShadowNodeImpl mutableCopy() { + return new ReactShadowNodeImpl(this); + } + /** * Nodes that return {@code true} will be treated as "virtual" nodes. That is, nodes that are not * mapped into native views (e.g. nested text node). By default this method returns {@code false}. @@ -378,6 +412,11 @@ public class ReactShadowNodeImpl implements ReactShadowNode mRootNode = rootNode; } + @Override + public void setRootTag(int rootTag) { + mRootTag = rootTag; + } + @Override public final void setViewClassName(String viewClassName) { mViewClassName = viewClassName; @@ -451,6 +490,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode return removed; } + @Override + public final void removeAllChildren() { + removeAllNativeChildren(); + mChildren.clear(); + } + @Override public final void removeAllNativeChildren() { if (mNativeChildren != null) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/YogaNodePool.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/YogaNodePool.java index c71b26123..ac6f5b380 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/YogaNodePool.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/YogaNodePool.java @@ -20,7 +20,7 @@ public class YogaNodePool { synchronized (sInitLock) { if (sPool == null) { - sPool = new ClearableSynchronizedPool(1024); + sPool = new ClearableSynchronizedPool<>(1024); } return sPool; }