Allow to use JNI without global refs
Summary: @public Adds the ability to opt into avoiding global weak JNI refs via `YogaConfig`. Note that only homogeneous trees are supported, i.e. **mixing weak-ref and non-weak-ref nodes will break!** Not using JNI refs hopefully will help with avoiding JNI reference table overflows, and will help creating trees on multiple threads, as no lock has to be acquired at any time. Reviewed By: SidharthGuglani Differential Revision: D14151037 fbshipit-source-id: 56d94713d39aee080d54be4cb4cdf5e3eccb473a
This commit is contained in:
committed by
Facebook Github Bot
parent
dcd9438488
commit
05f36a835a
@@ -40,6 +40,7 @@ public class YogaNodeJNI extends YogaNode implements Cloneable {
|
|||||||
private int mEdgeSetFlag = 0;
|
private int mEdgeSetFlag = 0;
|
||||||
|
|
||||||
private boolean mHasSetPosition = false;
|
private boolean mHasSetPosition = false;
|
||||||
|
private final boolean mAvoidGlobalJNIRefs;
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
private float mWidth = YogaConstants.UNDEFINED;
|
private float mWidth = YogaConstants.UNDEFINED;
|
||||||
@@ -81,15 +82,17 @@ public class YogaNodeJNI extends YogaNode implements Cloneable {
|
|||||||
|
|
||||||
private native long jni_YGNodeNew();
|
private native long jni_YGNodeNew();
|
||||||
public YogaNodeJNI() {
|
public YogaNodeJNI() {
|
||||||
|
mAvoidGlobalJNIRefs = false;
|
||||||
mNativePointer = jni_YGNodeNew();
|
mNativePointer = jni_YGNodeNew();
|
||||||
if (mNativePointer == 0) {
|
if (mNativePointer == 0) {
|
||||||
throw new IllegalStateException("Failed to allocate native memory");
|
throw new IllegalStateException("Failed to allocate native memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native long jni_YGNodeNewWithConfig(long configPointer);
|
private native long jni_YGNodeNewWithConfig(long configPointer, boolean avoidGlobalJNIRefs);
|
||||||
public YogaNodeJNI(YogaConfig config) {
|
public YogaNodeJNI(YogaConfig config) {
|
||||||
mNativePointer = jni_YGNodeNewWithConfig(config.mNativePointer);
|
mAvoidGlobalJNIRefs = config.avoidGlobalJNIRefs;
|
||||||
|
mNativePointer = jni_YGNodeNewWithConfig(config.mNativePointer, mAvoidGlobalJNIRefs);
|
||||||
if (mNativePointer == 0) {
|
if (mNativePointer == 0) {
|
||||||
throw new IllegalStateException("Failed to allocate native memory");
|
throw new IllegalStateException("Failed to allocate native memory");
|
||||||
}
|
}
|
||||||
@@ -188,13 +191,13 @@ public class YogaNodeJNI extends YogaNode implements Cloneable {
|
|||||||
|
|
||||||
private static native void jni_YGNodeSetOwner(long nativePointer, long newOwnerNativePointer);
|
private static native void jni_YGNodeSetOwner(long nativePointer, long newOwnerNativePointer);
|
||||||
|
|
||||||
private native long jni_YGNodeClone(long nativePointer, Object newNode);
|
private native long jni_YGNodeClone(long nativePointer, Object newNode, boolean avoidGlobalJNIRefs);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public YogaNodeJNI clone() {
|
public YogaNodeJNI clone() {
|
||||||
try {
|
try {
|
||||||
YogaNodeJNI clonedYogaNode = (YogaNodeJNI) super.clone();
|
YogaNodeJNI clonedYogaNode = (YogaNodeJNI) super.clone();
|
||||||
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode, mAvoidGlobalJNIRefs);
|
||||||
|
|
||||||
if (mChildren != null) {
|
if (mChildren != null) {
|
||||||
for (YogaNodeJNI child : mChildren) {
|
for (YogaNodeJNI child : mChildren) {
|
||||||
@@ -222,7 +225,7 @@ public class YogaNodeJNI extends YogaNode implements Cloneable {
|
|||||||
public YogaNodeJNI cloneWithNewChildren() {
|
public YogaNodeJNI cloneWithNewChildren() {
|
||||||
try {
|
try {
|
||||||
YogaNodeJNI clonedYogaNode = (YogaNodeJNI) super.clone();
|
YogaNodeJNI clonedYogaNode = (YogaNodeJNI) super.clone();
|
||||||
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode, mAvoidGlobalJNIRefs);
|
||||||
clonedYogaNode.mOwner = null;
|
clonedYogaNode.mOwner = null;
|
||||||
clonedYogaNode.mNativePointer = clonedNativePointer;
|
clonedYogaNode.mNativePointer = clonedNativePointer;
|
||||||
clonedYogaNode.clearChildren();
|
clonedYogaNode.clearChildren();
|
||||||
@@ -276,9 +279,29 @@ public class YogaNodeJNI extends YogaNode implements Cloneable {
|
|||||||
return mChildren == null ? -1 : mChildren.indexOf(child);
|
return mChildren == null ? -1 : mChildren.indexOf(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void jni_YGNodeCalculateLayout(long nativePointer, float width, float height);
|
private static native void jni_YGNodeCalculateLayout(long nativePointer, float width, float height, long[] nativePointers, YogaNodeJNI[] nodes);
|
||||||
public void calculateLayout(float width, float height) {
|
public void calculateLayout(float width, float height) {
|
||||||
jni_YGNodeCalculateLayout(mNativePointer, width, height);
|
long[] nativePointers = null;
|
||||||
|
YogaNodeJNI[] nodes = null;
|
||||||
|
|
||||||
|
if (mAvoidGlobalJNIRefs) {
|
||||||
|
ArrayList<YogaNodeJNI> n = new ArrayList<>();
|
||||||
|
n.add(this);
|
||||||
|
for (int i = 0; i < n.size(); ++i) {
|
||||||
|
List<YogaNodeJNI> children = n.get(i).mChildren;
|
||||||
|
if (children != null) {
|
||||||
|
n.addAll(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes = n.toArray(new YogaNodeJNI[n.size()]);
|
||||||
|
nativePointers = new long[nodes.length];
|
||||||
|
for (int i = 0; i < nodes.length; ++i) {
|
||||||
|
nativePointers[i] = nodes[i].mNativePointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jni_YGNodeCalculateLayout(mNativePointer, width, height, nativePointers, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNewLayout() {
|
public boolean hasNewLayout() {
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
#include <yoga/log.h>
|
#include <yoga/log.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
using namespace facebook::jni;
|
using namespace facebook::jni;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -22,6 +23,34 @@ struct JYogaConfig : public JavaClass<JYogaConfig> {
|
|||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaConfig;";
|
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaConfig;";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PtrJNodeMap {
|
||||||
|
using JNodeArray = JArrayClass<JYogaNode::javaobject>;
|
||||||
|
std::map<YGNodeRef, size_t> ptrsToIdxs_;
|
||||||
|
alias_ref<JNodeArray> javaNodes_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PtrJNodeMap() : ptrsToIdxs_{}, javaNodes_{} {}
|
||||||
|
PtrJNodeMap(
|
||||||
|
alias_ref<JArrayLong> nativePointers,
|
||||||
|
alias_ref<JNodeArray> javaNodes)
|
||||||
|
: javaNodes_{javaNodes} {
|
||||||
|
auto pin = nativePointers->pinCritical();
|
||||||
|
auto ptrs = pin.get();
|
||||||
|
for (size_t i = 0, n = pin.size(); i < n; ++i) {
|
||||||
|
ptrsToIdxs_[(YGNodeRef) ptrs[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local_ref<JYogaNode> ref(YGNodeRef node) {
|
||||||
|
auto idx = ptrsToIdxs_.find(node);
|
||||||
|
if (idx == ptrsToIdxs_.end()) {
|
||||||
|
return local_ref<JYogaNode>{};
|
||||||
|
} else {
|
||||||
|
return javaNodes_->getElement(idx->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct YGConfigContext {
|
struct YGConfigContext {
|
||||||
global_ref<jobject>* logger;
|
global_ref<jobject>* logger;
|
||||||
global_ref<jobject>* config;
|
global_ref<jobject>* config;
|
||||||
@@ -34,8 +63,15 @@ struct YGConfigContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline weak_ref<JYogaNode>* YGNodeJobject(YGNodeRef node) {
|
static inline local_ref<JYogaNode> YGNodeJobject(
|
||||||
return reinterpret_cast<weak_ref<JYogaNode>*>(node->getContext());
|
YGNodeRef node,
|
||||||
|
void* layoutContext) {
|
||||||
|
if (layoutContext == nullptr) {
|
||||||
|
return reinterpret_cast<weak_ref<JYogaNode>*>(node->getContext())
|
||||||
|
->lockLocal();
|
||||||
|
} else {
|
||||||
|
return reinterpret_cast<PtrJNodeMap*>(layoutContext)->ref(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGTransferLayoutDirection(
|
static void YGTransferLayoutDirection(
|
||||||
@@ -47,11 +83,13 @@ static void YGTransferLayoutDirection(
|
|||||||
layoutDirectionField, static_cast<jint>(YGNodeLayoutGetDirection(node)));
|
layoutDirectionField, static_cast<jint>(YGNodeLayoutGetDirection(node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
|
static void YGTransferLayoutOutputsRecursive(
|
||||||
|
YGNodeRef root,
|
||||||
|
void* layoutContext) {
|
||||||
if (!root->getHasNewLayout()) {
|
if (!root->getHasNewLayout()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto obj = YGNodeJobject(root)->lockLocal();
|
auto obj = YGNodeJobject(root, layoutContext);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
Log::log(
|
Log::log(
|
||||||
root,
|
root,
|
||||||
@@ -98,7 +136,7 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
|
|||||||
static auto doesLegacyStretchBehaviour = obj->getClass()->getField<jboolean>(
|
static auto doesLegacyStretchBehaviour = obj->getClass()->getField<jboolean>(
|
||||||
"mDoesLegacyStretchFlagAffectsLayout");
|
"mDoesLegacyStretchFlagAffectsLayout");
|
||||||
|
|
||||||
/* Those flags needs be in sync with YogaNodeJNI.java */
|
/* Those flags needs be in sync with YogaNode.java */
|
||||||
const int MARGIN = 1;
|
const int MARGIN = 1;
|
||||||
const int PADDING = 2;
|
const int PADDING = 2;
|
||||||
const int BORDER = 4;
|
const int BORDER = 4;
|
||||||
@@ -149,12 +187,12 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
|
|||||||
root->setHasNewLayout(false);
|
root->setHasNewLayout(false);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
|
for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
|
||||||
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i));
|
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i), layoutContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGPrint(YGNodeRef node) {
|
static void YGPrint(YGNodeRef node, void* layoutContext) {
|
||||||
if (auto obj = YGNodeJobject(node)->lockLocal()) {
|
if (auto obj = YGNodeJobject(node, layoutContext)) {
|
||||||
cout << obj->toString() << endl;
|
cout << obj->toString() << endl;
|
||||||
} else {
|
} else {
|
||||||
Log::log(
|
Log::log(
|
||||||
@@ -165,8 +203,12 @@ static void YGPrint(YGNodeRef node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float YGJNIBaselineFunc(YGNodeRef node, float width, float height) {
|
static float YGJNIBaselineFunc(
|
||||||
if (auto obj = YGNodeJobject(node)->lockLocal()) {
|
YGNodeRef node,
|
||||||
|
float width,
|
||||||
|
float height,
|
||||||
|
void* layoutContext) {
|
||||||
|
if (auto obj = YGNodeJobject(node, layoutContext)) {
|
||||||
static auto baselineFunc =
|
static auto baselineFunc =
|
||||||
findClassStatic("com/facebook/yoga/YogaNodeJNI")
|
findClassStatic("com/facebook/yoga/YogaNodeJNI")
|
||||||
->getMethod<jfloat(jfloat, jfloat)>("baseline");
|
->getMethod<jfloat(jfloat, jfloat)>("baseline");
|
||||||
@@ -187,7 +229,8 @@ static inline YGConfigRef _jlong2YGConfigRef(jlong addr) {
|
|||||||
static YGNodeRef YGJNIOnNodeClonedFunc(
|
static YGNodeRef YGJNIOnNodeClonedFunc(
|
||||||
YGNodeRef oldNode,
|
YGNodeRef oldNode,
|
||||||
YGNodeRef owner,
|
YGNodeRef owner,
|
||||||
int childIndex) {
|
int childIndex,
|
||||||
|
void* layoutContext) {
|
||||||
auto config = oldNode->getConfig();
|
auto config = oldNode->getConfig();
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -203,8 +246,8 @@ static YGNodeRef YGJNIOnNodeClonedFunc(
|
|||||||
|
|
||||||
auto newNode = onNodeClonedFunc(
|
auto newNode = onNodeClonedFunc(
|
||||||
javaConfig->get(),
|
javaConfig->get(),
|
||||||
YGNodeJobject(oldNode)->lockLocal(),
|
YGNodeJobject(oldNode, layoutContext),
|
||||||
YGNodeJobject(owner)->lockLocal(),
|
YGNodeJobject(owner, layoutContext),
|
||||||
childIndex);
|
childIndex);
|
||||||
|
|
||||||
static auto replaceChild =
|
static auto replaceChild =
|
||||||
@@ -212,7 +255,7 @@ static YGNodeRef YGJNIOnNodeClonedFunc(
|
|||||||
->getMethod<jlong(local_ref<JYogaNode>, jint)>("replaceChild");
|
->getMethod<jlong(local_ref<JYogaNode>, jint)>("replaceChild");
|
||||||
|
|
||||||
jlong newNodeNativePointer =
|
jlong newNodeNativePointer =
|
||||||
replaceChild(YGNodeJobject(owner)->lockLocal(), newNode, childIndex);
|
replaceChild(YGNodeJobject(owner, layoutContext), newNode, childIndex);
|
||||||
|
|
||||||
return _jlong2YGNodeRef(newNodeNativePointer);
|
return _jlong2YGNodeRef(newNodeNativePointer);
|
||||||
}
|
}
|
||||||
@@ -222,8 +265,9 @@ static YGSize YGJNIMeasureFunc(
|
|||||||
float width,
|
float width,
|
||||||
YGMeasureMode widthMode,
|
YGMeasureMode widthMode,
|
||||||
float height,
|
float height,
|
||||||
YGMeasureMode heightMode) {
|
YGMeasureMode heightMode,
|
||||||
if (auto obj = YGNodeJobject(node)->lockLocal()) {
|
void* layoutContext) {
|
||||||
|
if (auto obj = YGNodeJobject(node, layoutContext)) {
|
||||||
static auto measureFunc =
|
static auto measureFunc =
|
||||||
findClassStatic("com/facebook/yoga/YogaNodeJNI")
|
findClassStatic("com/facebook/yoga/YogaNodeJNI")
|
||||||
->getMethod<jlong(jfloat, jint, jfloat, jint)>("measure");
|
->getMethod<jlong(jfloat, jint, jfloat, jint)>("measure");
|
||||||
@@ -264,6 +308,7 @@ static int YGJNILogFunc(
|
|||||||
const YGConfigRef config,
|
const YGConfigRef config,
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
YGLogLevel level,
|
YGLogLevel level,
|
||||||
|
void* layoutContext,
|
||||||
const char* format,
|
const char* format,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
int result = vsnprintf(NULL, 0, format, args);
|
int result = vsnprintf(NULL, 0, format, args);
|
||||||
@@ -279,7 +324,7 @@ static int YGJNILogFunc(
|
|||||||
JYogaLogLevel::javaClassStatic()
|
JYogaLogLevel::javaClassStatic()
|
||||||
->getStaticMethod<JYogaLogLevel::javaobject(jint)>("fromInt");
|
->getStaticMethod<JYogaLogLevel::javaobject(jint)>("fromInt");
|
||||||
|
|
||||||
if (auto obj = YGNodeJobject(node)->lockLocal()) {
|
if (auto obj = YGNodeJobject(node, layoutContext)) {
|
||||||
auto jlogger =
|
auto jlogger =
|
||||||
reinterpret_cast<global_ref<jobject>*>(YGConfigGetContext(config));
|
reinterpret_cast<global_ref<jobject>*>(YGConfigGetContext(config));
|
||||||
logFunc(
|
logFunc(
|
||||||
@@ -296,16 +341,18 @@ static int YGJNILogFunc(
|
|||||||
jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
|
jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
|
||||||
const YGNodeRef node = YGNodeNew();
|
const YGNodeRef node = YGNodeNew();
|
||||||
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
|
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
|
||||||
// YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz)));
|
|
||||||
node->setPrintFunc(YGPrint);
|
node->setPrintFunc(YGPrint);
|
||||||
// YGNodeSetPrintFunc(node, YGPrint);
|
|
||||||
return reinterpret_cast<jlong>(node);
|
return reinterpret_cast<jlong>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong jni_YGNodeNewWithConfig(alias_ref<jobject> thiz, jlong configPointer) {
|
jlong jni_YGNodeNewWithConfig(
|
||||||
|
alias_ref<jobject> thiz,
|
||||||
|
jlong configPointer,
|
||||||
|
jboolean avoidGlobalJNIRefs) {
|
||||||
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
|
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
|
||||||
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
|
if (!avoidGlobalJNIRefs) {
|
||||||
node->setPrintFunc(YGPrint);
|
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
|
||||||
|
}
|
||||||
return reinterpret_cast<jlong>(node);
|
return reinterpret_cast<jlong>(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,10 +366,13 @@ void jni_YGNodeSetOwner(jlong nativePointer, jlong newOwnerNativePointer) {
|
|||||||
jlong jni_YGNodeClone(
|
jlong jni_YGNodeClone(
|
||||||
alias_ref<jobject> thiz,
|
alias_ref<jobject> thiz,
|
||||||
jlong nativePointer,
|
jlong nativePointer,
|
||||||
alias_ref<jobject> clonedJavaObject) {
|
alias_ref<jobject> clonedJavaObject,
|
||||||
|
jboolean avoidGlobalJNIRefs) {
|
||||||
const YGNodeRef clonedYogaNode = YGNodeClone(_jlong2YGNodeRef(nativePointer));
|
const YGNodeRef clonedYogaNode = YGNodeClone(_jlong2YGNodeRef(nativePointer));
|
||||||
clonedYogaNode->setContext(
|
if (!avoidGlobalJNIRefs) {
|
||||||
new weak_ref<jobject>(make_weak(clonedJavaObject)));
|
clonedYogaNode->setContext(
|
||||||
|
new weak_ref<jobject>(make_weak(clonedJavaObject)));
|
||||||
|
}
|
||||||
return reinterpret_cast<jlong>(clonedYogaNode);
|
return reinterpret_cast<jlong>(clonedYogaNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +381,10 @@ void jni_YGNodeFree(jlong nativePointer) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
||||||
delete YGNodeJobject(node);
|
auto context = node->getContext();
|
||||||
|
if (context != nullptr) {
|
||||||
|
delete reinterpret_cast<weak_ref<JYogaNode>*>(node->getContext());
|
||||||
|
}
|
||||||
YGNodeFree(node);
|
YGNodeFree(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +398,6 @@ void jni_YGNodeReset(jlong nativePointer) {
|
|||||||
void* context = node->getContext();
|
void* context = node->getContext();
|
||||||
YGNodeReset(node);
|
YGNodeReset(node);
|
||||||
node->setContext(context);
|
node->setContext(context);
|
||||||
node->setPrintFunc(YGPrint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void jni_YGNodePrint(jlong nativePointer) {
|
void jni_YGNodePrint(jlong nativePointer) {
|
||||||
@@ -384,14 +436,25 @@ void jni_YGNodeCalculateLayout(
|
|||||||
alias_ref<jclass>,
|
alias_ref<jclass>,
|
||||||
jlong nativePointer,
|
jlong nativePointer,
|
||||||
jfloat width,
|
jfloat width,
|
||||||
jfloat height) {
|
jfloat height,
|
||||||
|
alias_ref<JArrayLong> nativePointers,
|
||||||
|
alias_ref<JArrayClass<JYogaNode::javaobject>> javaNodes) {
|
||||||
|
|
||||||
|
void* layoutContext = nullptr;
|
||||||
|
auto map = PtrJNodeMap{};
|
||||||
|
if (nativePointers) {
|
||||||
|
map = PtrJNodeMap{nativePointers, javaNodes};
|
||||||
|
layoutContext = ↦
|
||||||
|
}
|
||||||
|
|
||||||
const YGNodeRef root = _jlong2YGNodeRef(nativePointer);
|
const YGNodeRef root = _jlong2YGNodeRef(nativePointer);
|
||||||
YGNodeCalculateLayout(
|
YGNodeCalculateLayoutWithContext(
|
||||||
root,
|
root,
|
||||||
static_cast<float>(width),
|
static_cast<float>(width),
|
||||||
static_cast<float>(height),
|
static_cast<float>(height),
|
||||||
YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)));
|
YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)),
|
||||||
YGTransferLayoutOutputsRecursive(root);
|
layoutContext);
|
||||||
|
YGTransferLayoutOutputsRecursive(root, layoutContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jni_YGNodeMarkDirty(jlong nativePointer) {
|
void jni_YGNodeMarkDirty(jlong nativePointer) {
|
||||||
@@ -622,9 +685,9 @@ void jni_YGConfigSetHasCloneNodeFunc(
|
|||||||
YGConfigSetContext(config, context);
|
YGConfigSetContext(config, context);
|
||||||
}
|
}
|
||||||
context->config = new global_ref<jobject>(make_global(thiz));
|
context->config = new global_ref<jobject>(make_global(thiz));
|
||||||
YGConfigSetCloneNodeFunc(config, YGJNIOnNodeClonedFunc);
|
config->setCloneNodeCallback(YGJNIOnNodeClonedFunc);
|
||||||
} else {
|
} else {
|
||||||
YGConfigSetCloneNodeFunc(config, nullptr);
|
config->setCloneNodeCallback(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,9 +708,9 @@ void jni_YGConfigSetLogger(
|
|||||||
YGConfigSetContext(config, context);
|
YGConfigSetContext(config, context);
|
||||||
}
|
}
|
||||||
context->logger = new global_ref<jobject>(make_global(logger));
|
context->logger = new global_ref<jobject>(make_global(logger));
|
||||||
YGConfigSetLogger(config, YGJNILogFunc);
|
config->setLogger(YGJNILogFunc);
|
||||||
} else {
|
} else {
|
||||||
YGConfigSetLogger(config, NULL);
|
config->setLogger(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#include "Yoga.h"
|
#include "Yoga.h"
|
||||||
|
|
||||||
struct YGConfig {
|
struct YGConfig {
|
||||||
using LogWithContextFn = void (*)(
|
using LogWithContextFn = int (*)(
|
||||||
YGConfigRef config,
|
YGConfigRef config,
|
||||||
YGNodeRef node,
|
YGNodeRef node,
|
||||||
YGLogLevel level,
|
YGLogLevel level,
|
||||||
|
Reference in New Issue
Block a user