Skip to content

Commit

Permalink
Expose methods of persistent yoga for Java
Browse files Browse the repository at this point in the history
Reviewed By: priteshrnandgaonkar

Differential Revision: D6918605

fbshipit-source-id: e424c78680c04e21154ebe21405671c4e90f6529
  • Loading branch information
mdvacca authored and facebook-github-bot committed Feb 14, 2018
1 parent c281f7a commit ecc08ad
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 11 deletions.
14 changes: 14 additions & 0 deletions ReactAndroid/src/main/java/com/facebook/yoga/YogaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class YogaConfig {

long mNativePointer;
private YogaLogger mLogger;
private YogaNodeClonedFunction mNodeClonedFunction;

private native long jni_YGConfigNew();
public YogaConfig() {
Expand Down Expand Up @@ -80,4 +81,17 @@ public void setLogger(YogaLogger logger) {
public YogaLogger getLogger() {
return mLogger;
}

private native void jni_YGConfigSetHasNodeClonedFunc(long nativePointer, boolean hasClonedFunc);

public void setOnNodeCloned(YogaNodeClonedFunction nodeClonedFunction) {
mNodeClonedFunction = nodeClonedFunction;
jni_YGConfigSetHasNodeClonedFunc(mNativePointer, nodeClonedFunction != null);
}

@DoNotStrip
public final void onNodeCloned(
YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
mNodeClonedFunction.onNodeCloned(oldNode, newNode, parent, childIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

package com.facebook.yoga;

import com.facebook.proguard.annotations.DoNotStrip;

@DoNotStrip
public interface YogaNodeClonedFunction {

@DoNotStrip
void onNodeCloned(YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex);
}
100 changes: 89 additions & 11 deletions ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ struct JYogaNode : public JavaClass<JYogaNode> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaNode;";
};

struct JYogaConfig : public JavaClass<JYogaConfig> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaConfig;";
};

struct YGConfigContext {
global_ref<jobject>* logger;
global_ref<jobject>* config;
YGConfigContext() : logger(nullptr), config(nullptr) {}
~YGConfigContext() {
delete config;
config = nullptr;
delete logger;
logger = nullptr;
}
};

static inline weak_ref<JYogaNode> *YGNodeJobject(YGNodeRef node) {
return reinterpret_cast<weak_ref<JYogaNode>*>(node->getContext());
}
Expand Down Expand Up @@ -118,11 +134,39 @@ static float YGJNIBaselineFunc(YGNodeRef node, float width, float height) {
}
}

static YGSize YGJNIMeasureFunc(YGNodeRef node,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode) {
static void YGJNIOnNodeClonedFunc(
YGNodeRef oldNode,
YGNodeRef newNode,
YGNodeRef parent,
int childIndex) {
auto config = oldNode->getConfig();
if (!config) {
return;
}
static auto onNodeClonedFunc = findClassStatic("com/facebook/yoga/YogaConfig")
->getMethod<void(
local_ref<JYogaNode>,
local_ref<JYogaNode>,
local_ref<JYogaNode>,
jint)>("onNodeCloned");

auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
auto javaConfig = context->config;

onNodeClonedFunc(
javaConfig->get(),
YGNodeJobject(oldNode)->lockLocal(),
YGNodeJobject(newNode)->lockLocal(),
YGNodeJobject(parent)->lockLocal(),
childIndex);
}

static YGSize YGJNIMeasureFunc(
YGNodeRef node,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode) {
if (auto obj = YGNodeJobject(node)->lockLocal()) {
static auto measureFunc = findClassStatic("com/facebook/yoga/YogaNode")
->getMethod<jlong(jfloat, jint, jfloat, jint)>("measure");
Expand Down Expand Up @@ -396,6 +440,10 @@ jlong jni_YGConfigNew(alias_ref<jobject>) {

void jni_YGConfigFree(alias_ref<jobject>, jlong nativePointer) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
if (context) {
delete context;
}
YGConfigFree(config);
}

Expand Down Expand Up @@ -430,19 +478,48 @@ void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>,
YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour);
}

void jni_YGConfigSetLogger(alias_ref<jobject>, jlong nativePointer, alias_ref<jobject> logger) {
void jni_YGConfigSetHasNodeClonedFunc(
alias_ref<jobject> thiz,
jlong nativePointer,
jboolean hasNodeClonedFunc) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
if (context && context->config) {
delete context->config;
context->config = nullptr;
}

auto context = YGConfigGetContext(config);
if (context) {
delete reinterpret_cast<global_ref<jobject> *>(context);
if (hasNodeClonedFunc) {
if (!context) {
context = new YGConfigContext();
YGConfigSetContext(config, context);
}
context->config = new global_ref<jobject>(make_global(thiz));
YGConfigSetNodeClonedFunc(config, YGJNIOnNodeClonedFunc);
} else {
YGConfigSetNodeClonedFunc(config, nullptr);
}
}

void jni_YGConfigSetLogger(
alias_ref<jobject>,
jlong nativePointer,
alias_ref<jobject> logger) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
if (context && context->logger) {
delete context->logger;
context->logger = nullptr;
}

if (logger) {
YGConfigSetContext(config, new global_ref<jobject>(make_global(logger)));
if (!context) {
context = new YGConfigContext();
YGConfigSetContext(config, context);
}
context->logger = new global_ref<jobject>(make_global(logger));
YGConfigSetLogger(config, YGJNILogFunc);
} else {
YGConfigSetContext(config, NULL);
YGConfigSetLogger(config, NULL);
}
}
Expand Down Expand Up @@ -545,6 +622,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
YGMakeNativeMethod(jni_YGConfigSetLogger),
YGMakeNativeMethod(jni_YGConfigSetHasNodeClonedFunc),
});
});
}

0 comments on commit ecc08ad

Please sign in to comment.