Introduce cloning mechanism for React Shadow Node

Reviewed By: achen1

Differential Revision: D7018869

fbshipit-source-id: beca45b1df9602ebbc9172091b24a2bf44e103f4
This commit is contained in:
David Vacca
2018-02-20 19:03:59 -08:00
committed by Facebook Github Bot
parent 9dd7608c97
commit ad06403c3e
3 changed files with 66 additions and 11 deletions

View File

@@ -67,6 +67,11 @@ public interface ReactShadowNode<T extends 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 extends 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 extends ReactShadowNode> {
T removeNativeChildAt(int i);
void removeAllChildren();
void removeAllNativeChildren();
int getNativeChildCount();

View File

@@ -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<ReactShadowNodeImpl> {
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<ReactShadowNodeImpl>
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<ReactShadowNodeImpl>
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<ReactShadowNodeImpl>
return removed;
}
@Override
public final void removeAllChildren() {
removeAllNativeChildren();
mChildren.clear();
}
@Override
public final void removeAllNativeChildren() {
if (mNativeChildren != null) {

View File

@@ -20,7 +20,7 @@ public class YogaNodePool {
synchronized (sInitLock) {
if (sPool == null) {
sPool = new ClearableSynchronizedPool<YogaNode>(1024);
sPool = new ClearableSynchronizedPool<>(1024);
}
return sPool;
}