diff --git a/java/com/facebook/yoga/YogaNative.java b/java/com/facebook/yoga/YogaNative.java index 372fb3c0..8b81e929 100644 --- a/java/com/facebook/yoga/YogaNative.java +++ b/java/com/facebook/yoga/YogaNative.java @@ -111,4 +111,5 @@ public class YogaNative { static native void jni_YGNodeSetHasBaselineFunc(long nativePointer, boolean hasMeasureFunc); static native void jni_YGNodePrint(long nativePointer); static native void jni_YGNodeSetStyleInputs(long nativePointer, float[] styleInputsArray, int size); + static native long jni_YGNodeClone(long nativePointer); } diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index 66d743f5..a01a0bdd 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -221,4 +221,6 @@ public abstract class YogaNode { public abstract void print(); public abstract void setStyleInputs(float[] styleInputs, int size); + + public abstract YogaNode cloneWithoutChildren(); } diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index e07bbb86..c48162f4 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -12,7 +12,7 @@ import java.util.List; import javax.annotation.Nullable; @DoNotStrip -public abstract class YogaNodeJNIBase extends YogaNode { +public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { @Nullable private YogaNodeJNIBase mOwner; @Nullable private List mChildren; @@ -93,6 +93,21 @@ public abstract class YogaNodeJNIBase extends YogaNode { return YogaNative.jni_YGNodeIsReferenceBaseline(mNativePointer); } + @Override + public YogaNodeJNIBase cloneWithoutChildren() { + try { + YogaNodeJNIBase clonedYogaNode = (YogaNodeJNIBase) super.clone(); + long clonedNativePointer = YogaNative.jni_YGNodeClone(mNativePointer); + clonedYogaNode.mOwner = null; + clonedYogaNode.mNativePointer = clonedNativePointer; + clonedYogaNode.clearChildren(); + return clonedYogaNode; + } catch (CloneNotSupportedException ex) { + // This class implements Cloneable, this should not happen + throw new RuntimeException(ex); + } + } + private void clearChildren() { mChildren = null; YogaNative.jni_YGNodeClearChildren(mNativePointer); diff --git a/java/jni/YGJNI.cpp b/java/jni/YGJNI.cpp index 18de9246..b8725c7e 100644 --- a/java/jni/YGJNI.cpp +++ b/java/jni/YGJNI.cpp @@ -372,6 +372,14 @@ static inline YGConfigRef _jlong2YGConfigRef(jlong addr) { return reinterpret_cast(static_cast(addr)); } +jlong jni_YGNodeClone(alias_ref thiz, jlong nativePointer) { + auto node = _jlong2YGNodeRef(nativePointer); + const YGNodeRef clonedYogaNode = YGNodeClone(node); + clonedYogaNode->setContext(node->getContext()); + + return reinterpret_cast(clonedYogaNode); +} + static YGSize YGJNIMeasureFunc( YGNodeRef node, float width, @@ -1103,6 +1111,7 @@ jint JNI_OnLoad(JavaVM* vm, void*) { YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAspectRatio), YGMakeCriticalNativeMethod(jni_YGNodeGetInstanceCount), YGMakeCriticalNativeMethod(jni_YGNodePrint), + YGMakeNativeMethod(jni_YGNodeClone), YGMakeNativeMethod(jni_YGNodeSetStyleInputs), YGMakeNativeMethod(jni_YGConfigNew), YGMakeNativeMethod(jni_YGConfigFree),