move property storage into sub-object

Summary:
Here we introduce an abstraction over node property storage, in order to experiment with different approaches for Java/C integration.

- interface `YogaNodeProperties` as abstraction
- current JNI code factored into `YogaNodePropertiesJNI.java`
- `YogaNode` delegates all calls, no API changes

Reviewed By: astreet

Differential Revision: D8769448

fbshipit-source-id: e67327ce41fa047a51a986c652b3d59992a510e2
This commit is contained in:
David Aurelio
2018-07-30 09:30:50 -07:00
committed by Facebook Github Bot
parent 006f6460a9
commit b1821ab4cd
4 changed files with 873 additions and 343 deletions

View File

@@ -21,6 +21,11 @@ struct JYogaConfig : public JavaClass<JYogaConfig> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaConfig;";
};
struct JYogaNodePropertiesJNI : public JavaClass<JYogaNodePropertiesJNI> {
static constexpr auto kJavaDescriptor =
"Lcom/facebook/yoga/YogaNodePropertiesJNI;";
};
struct YGConfigContext {
global_ref<jobject>* logger;
global_ref<jobject>* config;
@@ -33,16 +38,34 @@ struct YGConfigContext {
}
};
struct JNINodeContext {
weak_ref<JYogaNode> node;
weak_ref<JYogaNodePropertiesJNI> props;
};
static inline weak_ref<JYogaNode>* YGNodeJobject(YGNodeRef node) {
return reinterpret_cast<weak_ref<JYogaNode>*>(node->getContext());
return &reinterpret_cast<JNINodeContext*>(node->getContext())->node;
}
static inline weak_ref<JYogaNodePropertiesJNI>* YGNodePropsJObject(
YGNodeRef node) {
return &reinterpret_cast<JNINodeContext*>(node->getContext())->props;
}
static inline void setNodeContext(
YGNodeRef node,
alias_ref<JYogaNode> javaNode,
alias_ref<JYogaNodePropertiesJNI> javaNodeProps) {
node->setContext(
new JNINodeContext{make_weak(javaNode), make_weak(javaNodeProps)});
}
static void YGTransferLayoutDirection(
YGNodeRef node,
alias_ref<jobject> javaNode) {
alias_ref<JYogaNodePropertiesJNI> javaProps) {
static auto layoutDirectionField =
javaNode->getClass()->getField<jint>("mLayoutDirection");
javaNode->setFieldValue(
javaProps->getClass()->getField<jint>("mLayoutDirection");
javaProps->setFieldValue(
layoutDirectionField, static_cast<jint>(YGNodeLayoutGetDirection(node)));
}
@@ -50,7 +73,7 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
if (!root->getHasNewLayout()) {
return;
}
auto obj = YGNodeJobject(root)->lockLocal();
auto obj = YGNodePropsJObject(root)->lockLocal();
if (!obj) {
YGLog(
root,
@@ -223,7 +246,9 @@ static YGSize YGJNIMeasureFunc(
findClassStatic("com/facebook/yoga/YogaNode")
->getMethod<jlong(jfloat, jint, jfloat, jint)>("measure");
YGTransferLayoutDirection(node, obj);
if (auto jProps = YGNodePropsJObject(node)->lockLocal()) {
YGTransferLayoutDirection(node, jProps);
}
const auto measureResult =
measureFunc(obj, width, widthMode, height, heightMode);
@@ -287,18 +312,21 @@ static int YGJNILogFunc(
return result;
}
jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
jlong jni_YGNodeNew(
alias_ref<JYogaNodePropertiesJNI> javaProps,
alias_ref<JYogaNode> javaNode) {
const YGNodeRef node = YGNodeNew();
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
// YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz)));
setNodeContext(node, javaNode, javaProps);
node->setPrintFunc(YGPrint);
// YGNodeSetPrintFunc(node, YGPrint);
return reinterpret_cast<jlong>(node);
}
jlong jni_YGNodeNewWithConfig(alias_ref<jobject> thiz, jlong configPointer) {
jlong jni_YGNodeNewWithConfig(
alias_ref<JYogaNodePropertiesJNI> javaProps,
alias_ref<JYogaNode> javaNode,
jlong configPointer) {
const YGNodeRef node = YGNodeNewWithConfig(_jlong2YGConfigRef(configPointer));
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
setNodeContext(node, javaNode, javaProps);
node->setPrintFunc(YGPrint);
return reinterpret_cast<jlong>(node);
}
@@ -314,18 +342,18 @@ void jni_YGNodeSetOwner(
}
jlong jni_YGNodeClone(
alias_ref<jobject> thiz,
alias_ref<jclass>,
jlong nativePointer,
alias_ref<jobject> clonedJavaObject) {
alias_ref<JYogaNode> clonedJavaObject,
alias_ref<JYogaNodePropertiesJNI> clonedJavaProps) {
const YGNodeRef clonedYogaNode = YGNodeClone(_jlong2YGNodeRef(nativePointer));
clonedYogaNode->setContext(
new weak_ref<jobject>(make_weak(clonedJavaObject)));
setNodeContext(clonedYogaNode, clonedJavaObject, clonedJavaProps);
return reinterpret_cast<jlong>(clonedYogaNode);
}
void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
delete YGNodeJobject(node);
delete reinterpret_cast<JNINodeContext*>(node->getContext());
YGNodeFree(node);
}
@@ -387,6 +415,12 @@ void jni_YGNodeCalculateLayout(
static_cast<float>(width),
static_cast<float>(height),
YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)));
}
static void jni_YGTransferLayoutOutputsRecursive(
alias_ref<jclass>,
jlong nativePointer) {
const YGNodeRef root = _jlong2YGNodeRef(nativePointer);
YGTransferLayoutOutputsRecursive(root);
}
@@ -666,23 +700,14 @@ jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
jint JNI_OnLoad(JavaVM* vm, void*) {
return initialize(vm, [] {
registerNatives(
"com/facebook/yoga/YogaNode",
"com/facebook/yoga/YogaNodePropertiesJNI",
{
YGMakeNativeMethod(jni_YGNodeClone),
YGMakeNativeMethod(jni_YGNodeNew),
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
YGMakeNativeMethod(jni_YGNodeFree),
YGMakeNativeMethod(jni_YGNodeReset),
YGMakeNativeMethod(jni_YGNodeClearChildren),
YGMakeNativeMethod(jni_YGNodeInsertChild),
YGMakeNativeMethod(jni_YGNodeInsertSharedChild),
YGMakeNativeMethod(jni_YGNodeRemoveChild),
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
YGMakeNativeMethod(jni_YGNodeMarkDirty),
YGMakeNativeMethod(jni_YGNodeMarkDirtyAndPropogateToDescendants),
YGMakeNativeMethod(jni_YGNodeIsDirty),
YGMakeNativeMethod(jni_YGNodeSetHasMeasureFunc),
YGMakeNativeMethod(jni_YGNodeSetHasBaselineFunc),
YGMakeNativeMethod(jni_YGNodeCopyStyle),
YGMakeNativeMethod(jni_YGNodeStyleGetDirection),
YGMakeNativeMethod(jni_YGNodeStyleSetDirection),
YGMakeNativeMethod(jni_YGNodeStyleGetFlexDirection),
@@ -745,9 +770,23 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
YGMakeNativeMethod(jni_YGNodeStyleSetMaxHeightPercent),
YGMakeNativeMethod(jni_YGNodeStyleGetAspectRatio),
YGMakeNativeMethod(jni_YGNodeStyleSetAspectRatio),
YGMakeNativeMethod(jni_YGTransferLayoutOutputsRecursive),
});
registerNatives(
"com/facebook/yoga/YogaNode",
{
YGMakeNativeMethod(jni_YGNodeClearChildren),
YGMakeNativeMethod(jni_YGNodeInsertChild),
YGMakeNativeMethod(jni_YGNodeInsertSharedChild),
YGMakeNativeMethod(jni_YGNodeRemoveChild),
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
YGMakeNativeMethod(jni_YGNodeMarkDirty),
YGMakeNativeMethod(jni_YGNodeMarkDirtyAndPropogateToDescendants),
YGMakeNativeMethod(jni_YGNodeSetHasMeasureFunc),
YGMakeNativeMethod(jni_YGNodeSetHasBaselineFunc),
YGMakeNativeMethod(jni_YGNodeCopyStyle),
YGMakeNativeMethod(jni_YGNodeGetInstanceCount),
YGMakeNativeMethod(jni_YGNodePrint),
YGMakeNativeMethod(jni_YGNodeClone),
YGMakeNativeMethod(jni_YGNodeSetOwner),
});
registerNatives(