Add Unsafe
based storage backend
Summary: @public Adds another version of property storage for `YogaNode`, using `sun.misc.Unsafe`. Adopts the stub concept from Litho for `Unsafe`, as it is hidden by the Android SDK. Reviewed By: pasqualeanatriello Differential Revision: D9140103 fbshipit-source-id: a4b376eca341b724a00f873467ae8bf8eaac69f4
This commit is contained in:
committed by
Facebook Github Bot
parent
c5d4485db3
commit
be78bfbd8c
10
java/BUCK
10
java/BUCK
@@ -29,9 +29,19 @@ yoga_cxx_library(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
yoga_java_library(
|
||||||
|
name = "stubs",
|
||||||
|
srcs = glob(["stubs/**/*.java"]),
|
||||||
|
source = "1.7",
|
||||||
|
target = "1.7",
|
||||||
|
)
|
||||||
|
|
||||||
yoga_java_library(
|
yoga_java_library(
|
||||||
name = "java",
|
name = "java",
|
||||||
srcs = glob(["com/facebook/yoga/*.java"]),
|
srcs = glob(["com/facebook/yoga/*.java"]),
|
||||||
|
provided_deps = [
|
||||||
|
":stubs",
|
||||||
|
],
|
||||||
required_for_source_only_abi = True,
|
required_for_source_only_abi = True,
|
||||||
source = "1.7",
|
source = "1.7",
|
||||||
target = "1.7",
|
target = "1.7",
|
||||||
|
@@ -52,6 +52,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'com.google.code.findbugs:jsr305:3.0.1'
|
compileOnly 'com.google.code.findbugs:jsr305:3.0.1'
|
||||||
compileOnly project(':yoga:proguard-annotations')
|
compileOnly project(':yoga:proguard-annotations')
|
||||||
|
compileOnly project(':yoga:stubs')
|
||||||
implementation 'com.facebook.soloader:soloader:0.5.1'
|
implementation 'com.facebook.soloader:soloader:0.5.1'
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ public class YogaNode implements Cloneable {
|
|||||||
|
|
||||||
public static final int BYTE_BUFFER = 1;
|
public static final int BYTE_BUFFER = 1;
|
||||||
public static final int HYBRID = 2;
|
public static final int HYBRID = 2;
|
||||||
|
public static final int UNSAFE = 3;
|
||||||
|
|
||||||
/** Get native instance count. Useful for testing only. */
|
/** Get native instance count. Useful for testing only. */
|
||||||
static native int jni_YGNodeGetInstanceCount();
|
static native int jni_YGNodeGetInstanceCount();
|
||||||
@@ -50,6 +51,9 @@ public class YogaNode implements Cloneable {
|
|||||||
case HYBRID:
|
case HYBRID:
|
||||||
mDelegate = new YogaNodePropertiesHybrid(this);
|
mDelegate = new YogaNodePropertiesHybrid(this);
|
||||||
break;
|
break;
|
||||||
|
case UNSAFE:
|
||||||
|
mDelegate = new YogaNodePropertiesUnsafe(this);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mDelegate = new YogaNodePropertiesJNI(this);
|
mDelegate = new YogaNodePropertiesJNI(this);
|
||||||
}
|
}
|
||||||
@@ -63,6 +67,9 @@ public class YogaNode implements Cloneable {
|
|||||||
case HYBRID:
|
case HYBRID:
|
||||||
mDelegate = new YogaNodePropertiesHybrid(this, config);
|
mDelegate = new YogaNodePropertiesHybrid(this, config);
|
||||||
break;
|
break;
|
||||||
|
case UNSAFE:
|
||||||
|
mDelegate = new YogaNodePropertiesUnsafe(this, config);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mDelegate = new YogaNodePropertiesJNI(this, config);
|
mDelegate = new YogaNodePropertiesJNI(this, config);
|
||||||
}
|
}
|
||||||
|
@@ -31,16 +31,16 @@ public class YogaNodePropertiesByteBuffer implements YogaNodeProperties, Cloneab
|
|||||||
|
|
||||||
private static native ByteBuffer jni_getLayoutBuffer(long nativePointer);
|
private static native ByteBuffer jni_getLayoutBuffer(long nativePointer);
|
||||||
|
|
||||||
private static native long jni_YGNodeNewByteBuffer(YogaNode node);
|
private static native long jni_YGNodeNewNoProps(YogaNode node);
|
||||||
|
|
||||||
public YogaNodePropertiesByteBuffer(YogaNode node) {
|
public YogaNodePropertiesByteBuffer(YogaNode node) {
|
||||||
this(jni_YGNodeNewByteBuffer(node));
|
this(jni_YGNodeNewNoProps(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native long jni_YGNodeNewByteBufferWithConfig(YogaNode node, long configPointer);
|
private static native long jni_YGNodeNewNoPropsWithConfig(YogaNode node, long configPointer);
|
||||||
|
|
||||||
public YogaNodePropertiesByteBuffer(YogaNode node, YogaConfig config) {
|
public YogaNodePropertiesByteBuffer(YogaNode node, YogaConfig config) {
|
||||||
this(jni_YGNodeNewByteBufferWithConfig(node, config.mNativePointer));
|
this(jni_YGNodeNewNoPropsWithConfig(node, config.mNativePointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
public YogaNodePropertiesByteBuffer(long nativePointer) {
|
public YogaNodePropertiesByteBuffer(long nativePointer) {
|
||||||
@@ -84,6 +84,7 @@ public class YogaNodePropertiesByteBuffer implements YogaNodeProperties, Cloneab
|
|||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
mHasBorderSet = false;
|
mHasBorderSet = false;
|
||||||
|
mHasNewLayout = true;
|
||||||
jni_YGNodeReset(getNativePointer());
|
jni_YGNodeReset(getNativePointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
580
java/com/facebook/yoga/YogaNodePropertiesUnsafe.java
Normal file
580
java/com/facebook/yoga/YogaNodePropertiesUnsafe.java
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.facebook.yoga;
|
||||||
|
|
||||||
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
|
import com.facebook.soloader.SoLoader;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
@DoNotStrip
|
||||||
|
public class YogaNodePropertiesUnsafe implements YogaNodeProperties {
|
||||||
|
|
||||||
|
private static final int TRUE_BITS = 0x01000001;
|
||||||
|
private static final int FLOAT_SIZE = 4;
|
||||||
|
private static final int AUTO = YogaUnit.AUTO.intValue();
|
||||||
|
private static final int POINT = YogaUnit.POINT.intValue();
|
||||||
|
private static final int PERCENT = YogaUnit.PERCENT.intValue();
|
||||||
|
private static final int UNDEFINED = YogaUnit.UNDEFINED.intValue();
|
||||||
|
private static final int RTL = YogaDirection.RTL.intValue();
|
||||||
|
private static final Unsafe UNSAFE;
|
||||||
|
|
||||||
|
private final long mNativePointer;
|
||||||
|
private final long mStyleNativePointer;
|
||||||
|
private final long mLayoutNativePointer;
|
||||||
|
private boolean mHasBorderSet = false;
|
||||||
|
private boolean mHasNewLayout = true;
|
||||||
|
private boolean mIsFreed = false;
|
||||||
|
|
||||||
|
static {
|
||||||
|
SoLoader.loadLibrary("yoga");
|
||||||
|
Field instanceField = null;
|
||||||
|
try {
|
||||||
|
instanceField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
instanceField.setAccessible(true);
|
||||||
|
try {
|
||||||
|
UNSAFE = (Unsafe) instanceField.get(null);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long jni_YGNodeNewNoProps(YogaNode node);
|
||||||
|
private static native long jni_YGNodeNewNoPropsWithConfig(YogaNode node, long configPointer);
|
||||||
|
private static native long jni_YGNodeStylePointer(long nativePointer);
|
||||||
|
private static native long jni_YGNodeLayoutPointer(long nativePointer);
|
||||||
|
|
||||||
|
public YogaNodePropertiesUnsafe(YogaNode node) {
|
||||||
|
this(jni_YGNodeNewNoProps(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
public YogaNodePropertiesUnsafe(YogaNode node, YogaConfig config) {
|
||||||
|
this(jni_YGNodeNewNoPropsWithConfig(node, config.mNativePointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
public YogaNodePropertiesUnsafe(long nativePointer) {
|
||||||
|
mNativePointer = nativePointer;
|
||||||
|
mStyleNativePointer = jni_YGNodeStylePointer(nativePointer);
|
||||||
|
mLayoutNativePointer = jni_YGNodeLayoutPointer(nativePointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long jni_YGNodeCloneNoProps(long nativePointer, YogaNode newNode);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaNodeProperties clone(YogaNode node) {
|
||||||
|
long clonedNativePointer = jni_YGNodeCloneNoProps(getNativePointer(), node);
|
||||||
|
YogaNodePropertiesUnsafe clone =
|
||||||
|
new YogaNodePropertiesUnsafe(clonedNativePointer);
|
||||||
|
clone.mHasBorderSet = mHasBorderSet;
|
||||||
|
clone.mHasNewLayout = mHasNewLayout;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getNativePointer() {
|
||||||
|
return mNativePointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAfterCalculateLayout(boolean hasNewLayout) {
|
||||||
|
mHasNewLayout = hasNewLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void jni_YGNodeReset(long nativePointer);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
mHasNewLayout = true;
|
||||||
|
jni_YGNodeReset(getNativePointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNewLayout() {
|
||||||
|
return mHasNewLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native boolean jni_YGNodeIsDirty(long nativePointer);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirty() {
|
||||||
|
return jni_YGNodeIsDirty(mNativePointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markLayoutSeen() {
|
||||||
|
mHasNewLayout = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaDirection getStyleDirection() {
|
||||||
|
return YogaDirection.fromInt(getStyleInt(YogaNodeMemoryLayout.styleDirection));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDirection(YogaDirection direction) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleDirection, direction.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaFlexDirection getFlexDirection() {
|
||||||
|
return YogaFlexDirection.fromInt(getStyleInt(YogaNodeMemoryLayout.styleFlexDirection));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexDirection(YogaFlexDirection flexDirection) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleFlexDirection, flexDirection.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaJustify getJustifyContent() {
|
||||||
|
return YogaJustify.fromInt(getStyleInt(YogaNodeMemoryLayout.styleJustifyContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setJustifyContent(YogaJustify justifyContent) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleJustifyContent, justifyContent.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaAlign getAlignItems() {
|
||||||
|
return YogaAlign.fromInt(getStyleInt(YogaNodeMemoryLayout.styleAlignItems));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlignItems(YogaAlign alignItems) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleAlignItems, alignItems.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaAlign getAlignSelf() {
|
||||||
|
return YogaAlign.fromInt(getStyleInt(YogaNodeMemoryLayout.styleAlignSelf));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlignSelf(YogaAlign alignSelf) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleAlignSelf, alignSelf.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaAlign getAlignContent() {
|
||||||
|
return YogaAlign.fromInt(getStyleInt(YogaNodeMemoryLayout.styleAlignContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlignContent(YogaAlign alignContent) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleAlignContent, alignContent.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaPositionType getPositionType() {
|
||||||
|
return YogaPositionType.fromInt(getStyleInt(YogaNodeMemoryLayout.stylePositionType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPositionType(YogaPositionType positionType) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.stylePositionType, positionType.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWrap(YogaWrap flexWrap) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleFlexWrap, flexWrap.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaOverflow getOverflow() {
|
||||||
|
return YogaOverflow.fromInt(getStyleInt(YogaNodeMemoryLayout.styleOverflow));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverflow(YogaOverflow overflow) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleOverflow, overflow.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaDisplay getDisplay() {
|
||||||
|
return YogaDisplay.fromInt(getStyleInt(YogaNodeMemoryLayout.styleDisplay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDisplay(YogaDisplay display) {
|
||||||
|
putStyleInt(YogaNodeMemoryLayout.styleDisplay, display.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlex(float flex) {
|
||||||
|
putStyleOptional(YogaNodeMemoryLayout.styleFlex, flex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFlexGrow() {
|
||||||
|
return getStyleFloat(YogaNodeMemoryLayout.styleFlexGrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexGrow(float flexGrow) {
|
||||||
|
putStyleOptional(YogaNodeMemoryLayout.styleFlexGrow, flexGrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFlexShrink() {
|
||||||
|
return getStyleFloat(YogaNodeMemoryLayout.styleFlexShrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexShrink(float flexShrink) {
|
||||||
|
putStyleOptional(YogaNodeMemoryLayout.styleFlexShrink, flexShrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getFlexBasis() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleFlexBasis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexBasis(float flexBasis) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleFlexBasis, flexBasis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexBasisPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleFlexBasis, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlexBasisAuto() {
|
||||||
|
putStyleAuto(YogaNodeMemoryLayout.styleFlexBasis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getMargin(YogaEdge edge) {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleMarginOffset(edge));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMargin(YogaEdge edge, float margin) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleMarginOffset(edge), margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMarginPercent(YogaEdge edge, float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleMarginOffset(edge), percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMarginAuto(YogaEdge edge) {
|
||||||
|
putStyleAuto(YogaNodeMemoryLayout.styleMarginOffset(edge));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getPadding(YogaEdge edge) {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.stylePaddingOffset(edge));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPadding(YogaEdge edge, float padding) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.stylePaddingOffset(edge), padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPaddingPercent(YogaEdge edge, float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.stylePaddingOffset(edge), percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getBorder(YogaEdge edge) {
|
||||||
|
return mHasBorderSet
|
||||||
|
? getStyleFloat(YogaNodeMemoryLayout.styleBorderOffset(edge))
|
||||||
|
: YogaConstants.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBorder(YogaEdge edge, float border) {
|
||||||
|
mHasBorderSet = true;
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleBorderOffset(edge), border);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getPosition(YogaEdge edge) {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.stylePositionOffset(edge));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPosition(YogaEdge edge, float position) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.stylePositionOffset(edge), position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPositionPercent(YogaEdge edge, float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.stylePositionOffset(edge), percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getWidth() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWidth(float width) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleWidth, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWidthPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleWidth, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWidthAuto() {
|
||||||
|
putStyleAuto(YogaNodeMemoryLayout.styleWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getHeight() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeight(float height) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleHeight, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleHeight, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightAuto() {
|
||||||
|
putStyleAuto(YogaNodeMemoryLayout.styleHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getMinWidth() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleMinWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinWidth(float minWidth) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleMinWidth, minWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinWidthPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleMinWidth, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getMinHeight() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleMinHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinHeight(float minHeight) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleMinHeight, minHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinHeightPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleMinHeight, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getMaxWidth() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleMaxWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxWidth(float maxWidth) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleMaxWidth, maxWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxWidthPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleMaxWidth, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaValue getMaxHeight() {
|
||||||
|
return getStyleValue(YogaNodeMemoryLayout.styleMaxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxHeight(float maxHeight) {
|
||||||
|
putStylePoints(YogaNodeMemoryLayout.styleMaxHeight, maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxHeightPercent(float percent) {
|
||||||
|
putStylePercent(YogaNodeMemoryLayout.styleMaxHeight, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getAspectRatio() {
|
||||||
|
return getStyleOptional(YogaNodeMemoryLayout.styleAspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAspectRatio(float aspectRatio) {
|
||||||
|
putStyleOptional(YogaNodeMemoryLayout.styleAspectRatio, aspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutX() {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutY() {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutWidth() {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutHeight() {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getDoesLegacyStretchFlagAffectsLayout() {
|
||||||
|
return getBool(mLayoutNativePointer + YogaNodeMemoryLayout.layoutDoesLegacyStretchFlagAffectsLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutMargin(YogaEdge edge) {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutMarginOffset(layoutEdge(edge)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutPadding(YogaEdge edge) {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutPaddingOffset(layoutEdge(edge)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutBorder(YogaEdge edge) {
|
||||||
|
return getLayoutFloat(YogaNodeMemoryLayout.layoutBorderOffset(layoutEdge(edge)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaDirection getLayoutDirection() {
|
||||||
|
return YogaDirection.fromInt(getLayoutDirectionInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void jni_YGNodeFree(long nativePointer);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void freeNatives() {
|
||||||
|
if (!mIsFreed) {
|
||||||
|
mIsFreed = true;
|
||||||
|
jni_YGNodeFree(mNativePointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLayoutDirectionInt() {
|
||||||
|
return UNSAFE.getInt(null, mLayoutNativePointer + YogaNodeMemoryLayout.layoutDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private YogaEdge layoutEdge(YogaEdge edge) {
|
||||||
|
int layoutDirection = getLayoutDirectionInt();
|
||||||
|
switch (edge) {
|
||||||
|
case LEFT:
|
||||||
|
return layoutDirection == RTL ? YogaEdge.END : YogaEdge.START;
|
||||||
|
case RIGHT:
|
||||||
|
return layoutDirection == RTL ? YogaEdge.START : YogaEdge.END;
|
||||||
|
case TOP:
|
||||||
|
case BOTTOM:
|
||||||
|
case START:
|
||||||
|
case END:
|
||||||
|
return edge;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Cannot get layout properties of multi-edge shorthands");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getStyleInt(int offset) {
|
||||||
|
return UNSAFE.getInt(null, mStyleNativePointer + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStyleInt(int offset, int value) {
|
||||||
|
UNSAFE.putInt(null, mStyleNativePointer + offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getStyleFloat(int offset) {
|
||||||
|
return getFloat(mStyleNativePointer + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStyleFloat(int offset, float value) {
|
||||||
|
putFloat(mStyleNativePointer + offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStylePoints(int offset, float value) {
|
||||||
|
putStyleValue(offset, value, POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStylePercent(int offset, float value) {
|
||||||
|
putStyleValue(offset, value, PERCENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStyleAuto(int offset) {
|
||||||
|
putStyleValue(offset, 0, AUTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStyleValue(int offset, float value, int unit) {
|
||||||
|
if (YogaConstants.isUndefined(value)) {
|
||||||
|
value = YogaConstants.UNDEFINED;
|
||||||
|
unit = UNDEFINED;
|
||||||
|
}
|
||||||
|
putStyleFloat(offset, value);
|
||||||
|
putStyleInt(offset + FLOAT_SIZE, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private YogaValue getStyleValue(int offset) {
|
||||||
|
float value = getStyleFloat(offset);
|
||||||
|
int unit = getStyleInt(offset + FLOAT_SIZE);
|
||||||
|
return new YogaValue(value, YogaUnit.fromInt(unit));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putStyleOptional(int offset, float value) {
|
||||||
|
int isUndefinedBits = YogaConstants.isUndefined(value) ? TRUE_BITS : 0;
|
||||||
|
putStyleFloat(offset, value);
|
||||||
|
putStyleInt(offset + FLOAT_SIZE, isUndefinedBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getStyleOptional(int offset) {
|
||||||
|
boolean isUndefined = getBool(mStyleNativePointer + offset + FLOAT_SIZE);
|
||||||
|
return isUndefined
|
||||||
|
? YogaConstants.UNDEFINED
|
||||||
|
: getStyleFloat(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float getLayoutFloat(int offset) {
|
||||||
|
return getFloat(mLayoutNativePointer + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getFloat(long offset) {
|
||||||
|
int intBits = UNSAFE.getInt(null, offset);
|
||||||
|
return Float.intBitsToFloat(intBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void putFloat(long offset, float value) {
|
||||||
|
int intBits = Float.floatToRawIntBits(value);
|
||||||
|
UNSAFE.putInt(null, offset, intBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean getBool(long offset) {
|
||||||
|
// assumes little endian
|
||||||
|
return (UNSAFE.getInt(null, offset) & 0xFF) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -344,13 +344,11 @@ jlong jni_YGNodeNewWithConfig(
|
|||||||
return reinterpret_cast<jlong>(node);
|
return reinterpret_cast<jlong>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong jni_YGNodeNewByteBuffer(
|
jlong jni_YGNodeNewNoProps(alias_ref<jclass>, alias_ref<JYogaNode> javaNode) {
|
||||||
alias_ref<jclass>,
|
|
||||||
alias_ref<JYogaNode> javaNode) {
|
|
||||||
return jni_YGNodeNew(nullptr, javaNode);
|
return jni_YGNodeNew(nullptr, javaNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong jni_YGNodeNewByteBufferWithConfig(
|
jlong jni_YGNodeNewNoPropsWithConfig(
|
||||||
alias_ref<jclass>,
|
alias_ref<jclass>,
|
||||||
alias_ref<JYogaNode> javaNode,
|
alias_ref<JYogaNode> javaNode,
|
||||||
jlong configPointer) {
|
jlong configPointer) {
|
||||||
@@ -747,6 +745,14 @@ local_ref<JByteBuffer> jni_getLayoutBuffer(
|
|||||||
reinterpret_cast<uint8_t*>(layout), sizeof(YGLayout));
|
reinterpret_cast<uint8_t*>(layout), sizeof(YGLayout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jlong jni_YGNodeStylePointer(alias_ref<jclass>, jlong nativePointer) {
|
||||||
|
return reinterpret_cast<jlong>(&_jlong2YGNodeRef(nativePointer)->getStyle());
|
||||||
|
}
|
||||||
|
|
||||||
|
jlong jni_YGNodeLayoutPointer(alias_ref<jclass>, jlong nativePointer) {
|
||||||
|
return reinterpret_cast<jlong>(&_jlong2YGNodeRef(nativePointer)->getLayout());
|
||||||
|
}
|
||||||
|
|
||||||
#define YGMakeNativeMethod(name) makeNativeMethod(#name, name)
|
#define YGMakeNativeMethod(name) makeNativeMethod(#name, name)
|
||||||
|
|
||||||
jint JNI_OnLoad(JavaVM* vm, void*) {
|
jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||||
@@ -860,8 +866,8 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
|
|||||||
{
|
{
|
||||||
YGMakeNativeMethod(jni_YGNodeCloneNoProps),
|
YGMakeNativeMethod(jni_YGNodeCloneNoProps),
|
||||||
YGMakeNativeMethod(jni_YGNodeFree),
|
YGMakeNativeMethod(jni_YGNodeFree),
|
||||||
YGMakeNativeMethod(jni_YGNodeNewByteBuffer),
|
YGMakeNativeMethod(jni_YGNodeNewNoProps),
|
||||||
YGMakeNativeMethod(jni_YGNodeNewByteBufferWithConfig),
|
YGMakeNativeMethod(jni_YGNodeNewNoPropsWithConfig),
|
||||||
YGMakeNativeMethod(jni_YGNodeReset),
|
YGMakeNativeMethod(jni_YGNodeReset),
|
||||||
YGMakeNativeMethod(jni_YGNodeIsDirty),
|
YGMakeNativeMethod(jni_YGNodeIsDirty),
|
||||||
YGMakeNativeMethod(jni_getStyleBuffer),
|
YGMakeNativeMethod(jni_getStyleBuffer),
|
||||||
@@ -872,5 +878,17 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
|
|||||||
{
|
{
|
||||||
YGMakeNativeMethod(jni_getStyleBuffer),
|
YGMakeNativeMethod(jni_getStyleBuffer),
|
||||||
});
|
});
|
||||||
|
registerNatives(
|
||||||
|
"com/facebook/yoga/YogaNodePropertiesUnsafe",
|
||||||
|
{
|
||||||
|
YGMakeNativeMethod(jni_YGNodeCloneNoProps),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeFree),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeNewNoProps),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeNewNoPropsWithConfig),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeStylePointer),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeLayoutPointer),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeIsDirty),
|
||||||
|
YGMakeNativeMethod(jni_YGNodeReset),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
10
java/stubs/build.gradle
Normal file
10
java/stubs/build.gradle
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDirs = ['src']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
java/stubs/src/sun/misc/Unsafe.java
Normal file
27
java/stubs/src/sun/misc/Unsafe.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.misc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub for sun.misc.Unsafe, which is not exposed by the Android SDK.
|
||||||
|
*
|
||||||
|
* This only contains the methods and fields we need for Yoga.
|
||||||
|
*/
|
||||||
|
public final class Unsafe {
|
||||||
|
private static final Unsafe theUnsafe = null;
|
||||||
|
|
||||||
|
public final int getInt(Object object, long offset) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void putInt(Object object, long offset, int value) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -59,6 +59,22 @@ public class TestParametrization {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Hybrid";
|
return "Hybrid";
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
new NodeFactory() {
|
||||||
|
@Override
|
||||||
|
public YogaNode create() {
|
||||||
|
return new YogaNode(YogaNode.UNSAFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public YogaNode create(YogaConfig config) {
|
||||||
|
return new YogaNode(YogaNode.UNSAFE, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Unsafe";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
include ':yoga', ':yogacore', ':yoga-layout', ':yoga:proguard-annotations', ':libfb'
|
include ':yoga', ':yogacore', ':yoga-layout', ':yoga:proguard-annotations', ':yoga:stubs', ':libfb'
|
||||||
project(':yoga').projectDir = file('java')
|
project(':yoga').projectDir = file('java')
|
||||||
project(':yoga:proguard-annotations').projectDir = file('java/proguard-annotations')
|
project(':yoga:proguard-annotations').projectDir = file('java/proguard-annotations')
|
||||||
|
project(':yoga:stubs').projectDir = file('java/stubs')
|
||||||
project(':yoga-layout').projectDir = file('android')
|
project(':yoga-layout').projectDir = file('android')
|
||||||
project(':libfb').projectDir = file('lib/fb')
|
project(':libfb').projectDir = file('lib/fb')
|
||||||
|
Reference in New Issue
Block a user