Skip to content

Commit

Permalink
Move YGLogger into YGConfig and associate YGNodeRef with log events
Browse files Browse the repository at this point in the history
Summary:
Moves the `YGLogger` into `YGConfig` and pass the `YGNodeRef` into the logger to be able to associate the log messages and assertions with the specific node.

Tackles facebook/yoga#530 and facebook/yoga#446
Closes facebook/yoga#531

Reviewed By: astreet

Differential Revision: D4970149

Pulled By: emilsjolander

fbshipit-source-id: b7fcdaa273143ea2fa35861620b2e4d79f04f0af
  • Loading branch information
woehrl01 authored and facebook-github-bot committed May 3, 2017
1 parent 1c07658 commit 5f2edfc
Show file tree
Hide file tree
Showing 11 changed files with 433 additions and 271 deletions.
11 changes: 11 additions & 0 deletions ReactAndroid/src/main/java/com/facebook/yoga/YogaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class YogaConfig {
}

long mNativePointer;
private YogaLogger mLogger;

private native long jni_YGConfigNew();
public YogaConfig() {
Expand Down Expand Up @@ -67,4 +68,14 @@ public void setPointScaleFactor(float pixelsInPoint) {
public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) {
jni_YGConfigSetUseLegacyStretchBehaviour(mNativePointer, useLegacyStretchBehaviour);
}

private native void jni_YGConfigSetLogger(long nativePointer, Object logger);
public void setLogger(YogaLogger logger) {
mLogger = logger;
jni_YGConfigSetLogger(mNativePointer, logger);
}

public YogaLogger getLogger() {
return mLogger;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public enum YogaLogLevel {
WARN(1),
INFO(2),
DEBUG(3),
VERBOSE(4);
VERBOSE(4),
FATAL(5);

private int mIntValue;

Expand All @@ -36,6 +37,7 @@ public static YogaLogLevel fromInt(int value) {
case 2: return INFO;
case 3: return DEBUG;
case 4: return VERBOSE;
case 5: return FATAL;
default: throw new IllegalArgumentException("Unknown enum value: " + value);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
@DoNotStrip
public interface YogaLogger {
@DoNotStrip
void log(YogaLogLevel level, String message);
void log(YogaNode node, YogaLogLevel level, String message);
}
6 changes: 0 additions & 6 deletions ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ public class YogaNode {
* Get native instance count. Useful for testing only.
*/
static native int jni_YGNodeGetInstanceCount();
static native void jni_YGLog(int level, String message);

private static native void jni_YGSetLogger(Object logger);
public static void setLogger(YogaLogger logger) {
jni_YGSetLogger(logger);
}

private YogaNode mParent;
private List<YogaNode> mChildren;
Expand Down
114 changes: 68 additions & 46 deletions ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
using namespace facebook::jni;
using namespace std;

static inline weak_ref<jobject> *YGNodeJobject(YGNodeRef node) {
return reinterpret_cast<weak_ref<jobject> *>(YGNodeGetContext(node));
struct JYogaNode : public JavaClass<JYogaNode> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaNode;";
};

static inline weak_ref<JYogaNode> *YGNodeJobject(YGNodeRef node) {
return reinterpret_cast<weak_ref<JYogaNode> *>(YGNodeGetContext(node));
}

static void YGTransferLayoutDirection(YGNodeRef node, alias_ref<jobject> javaNode) {
Expand All @@ -24,7 +28,7 @@ static void YGTransferLayoutDirection(YGNodeRef node, alias_ref<jobject> javaNod
}

static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
if(YGNodeGetHasNewLayout(root)){
if (YGNodeGetHasNewLayout(root)) {
if (auto obj = YGNodeJobject(root)->lockLocal()) {
static auto widthField = obj->getClass()->getField<jfloat>("mWidth");
static auto heightField = obj->getClass()->getField<jfloat>("mHeight");
Expand Down Expand Up @@ -54,28 +58,28 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
const int PADDING = 2;
const int BORDER = 4;

int hasEdgeSetFlag = (int)obj->getFieldValue(edgeSetFlagField);
int hasEdgeSetFlag = (int) obj->getFieldValue(edgeSetFlagField);

obj->setFieldValue(widthField, YGNodeLayoutGetWidth(root));
obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root));
obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root));
obj->setFieldValue(topField, YGNodeLayoutGetTop(root));

if((hasEdgeSetFlag & MARGIN) == MARGIN){
if ((hasEdgeSetFlag & MARGIN) == MARGIN) {
obj->setFieldValue(marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft));
obj->setFieldValue(marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop));
obj->setFieldValue(marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight));
obj->setFieldValue(marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom));
}

if((hasEdgeSetFlag & PADDING) == PADDING){
if ((hasEdgeSetFlag & PADDING) == PADDING) {
obj->setFieldValue(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft));
obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop));
obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight));
obj->setFieldValue(paddingBottomField, YGNodeLayoutGetPadding(root, YGEdgeBottom));
}

if((hasEdgeSetFlag & BORDER) == BORDER){
if ((hasEdgeSetFlag & BORDER) == BORDER) {
obj->setFieldValue(borderLeftField, YGNodeLayoutGetBorder(root, YGEdgeLeft));
obj->setFieldValue(borderTopField, YGNodeLayoutGetBorder(root, YGEdgeTop));
obj->setFieldValue(borderRightField, YGNodeLayoutGetBorder(root, YGEdgeRight));
Expand All @@ -90,7 +94,7 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i));
}
} else {
YGLog(YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
YGLog(root, YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
}
}
}
Expand All @@ -99,7 +103,7 @@ static void YGPrint(YGNodeRef node) {
if (auto obj = YGNodeJobject(node)->lockLocal()) {
cout << obj->toString() << endl;
} else {
YGLog(YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
YGLog(node, YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
}
}

Expand Down Expand Up @@ -136,7 +140,7 @@ static YGSize YGJNIMeasureFunc(YGNodeRef node,

return YGSize{*measuredWidth, *measuredHeight};
} else {
YGLog(YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
YGLog(node, YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
return YGSize{
widthMode == YGMeasureModeUndefined ? 0 : width,
heightMode == YGMeasureModeUndefined ? 0 : height,
Expand All @@ -148,20 +152,28 @@ struct JYogaLogLevel : public JavaClass<JYogaLogLevel> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/yoga/YogaLogLevel;";
};

static global_ref<jobject> *jLogger;
static int YGLog(YGLogLevel level, const char *format, va_list args) {
static int YGJNILogFunc(const YGConfigRef config,
const YGNodeRef node,
YGLogLevel level,
const char *format,
va_list args) {
char buffer[256];
int result = vsnprintf(buffer, sizeof(buffer), format, args);

static auto logFunc = findClassStatic("com/facebook/yoga/YogaLogger")
->getMethod<void(local_ref<JYogaLogLevel>, jstring)>("log");
static auto logFunc =
findClassStatic("com/facebook/yoga/YogaLogger")
->getMethod<void(local_ref<JYogaNode>, local_ref<JYogaLogLevel>, jstring)>("log");

static auto logLevelFromInt =
JYogaLogLevel::javaClassStatic()->getStaticMethod<JYogaLogLevel::javaobject(jint)>("fromInt");

logFunc(jLogger->get(),
logLevelFromInt(JYogaLogLevel::javaClassStatic(), static_cast<jint>(level)),
Environment::current()->NewStringUTF(buffer));
if (auto obj = YGNodeJobject(node)->lockLocal()) {
auto jlogger = reinterpret_cast<global_ref<jobject> *>(YGConfigGetContext(config));
logFunc(jlogger->get(),
obj,
logLevelFromInt(JYogaLogLevel::javaClassStatic(), static_cast<jint>(level)),
Environment::current()->NewStringUTF(buffer));
}

return result;
}
Expand All @@ -174,27 +186,6 @@ static inline YGConfigRef _jlong2YGConfigRef(jlong addr) {
return reinterpret_cast<YGConfigRef>(static_cast<intptr_t>(addr));
}

void jni_YGSetLogger(alias_ref<jclass> clazz, alias_ref<jobject> logger) {
if (jLogger) {
jLogger->releaseAlias();
delete jLogger;
}

if (logger) {
jLogger = new global_ref<jobject>(make_global(logger));
YGSetLogger(YGLog);
} else {
jLogger = NULL;
YGSetLogger(NULL);
}
}

void jni_YGLog(alias_ref<jclass> clazz, jint level, jstring message) {
const char *nMessage = Environment::current()->GetStringUTFChars(message, 0);
YGLog(static_cast<YGLogLevel>(level), "%s", nMessage);
Environment::current()->ReleaseStringUTFChars(message, nMessage);
}

jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
const YGNodeRef node = YGNodeNew();
YGNodeSetContext(node, new weak_ref<jobject>(make_weak(thiz)));
Expand Down Expand Up @@ -225,7 +216,9 @@ void jni_YGNodeReset(alias_ref<jobject> thiz, jlong nativePointer) {

void jni_YGNodePrint(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
YGNodePrint(node, (YGPrintOptions) (YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren));
YGNodePrint(node,
(YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout |
YGPrintOptionsChildren));
}

void jni_YGNodeInsertChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer, jint index) {
Expand Down Expand Up @@ -393,26 +386,56 @@ void jni_YGConfigFree(alias_ref<jobject>, jlong nativePointer) {
YGConfigFree(config);
}

void jni_YGConfigSetExperimentalFeatureEnabled(alias_ref<jobject>, jlong nativePointer, jint feature, jboolean enabled) {
void jni_YGConfigSetExperimentalFeatureEnabled(alias_ref<jobject>,
jlong nativePointer,
jint feature,
jboolean enabled) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetExperimentalFeatureEnabled(config, static_cast<YGExperimentalFeature>(feature), enabled);
YGConfigSetExperimentalFeatureEnabled(config,
static_cast<YGExperimentalFeature>(feature),
enabled);
}

void jni_YGConfigSetUseWebDefaults(alias_ref<jobject>, jlong nativePointer, jboolean useWebDefaults) {
void jni_YGConfigSetUseWebDefaults(alias_ref<jobject>,
jlong nativePointer,
jboolean useWebDefaults) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetUseWebDefaults(config, useWebDefaults);
}

void jni_YGConfigSetPointScaleFactor(alias_ref<jobject>, jlong nativePointer, jfloat pixelsInPoint) {
void jni_YGConfigSetPointScaleFactor(alias_ref<jobject>,
jlong nativePointer,
jfloat pixelsInPoint) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetPointScaleFactor(config, pixelsInPoint);
}

void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>, jlong nativePointer, jboolean useLegacyStretchBehaviour) {
void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>,
jlong nativePointer,
jboolean useLegacyStretchBehaviour) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour);
}

void jni_YGConfigSetLogger(alias_ref<jobject>, jlong nativePointer, alias_ref<jobject> logger) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);

auto context = YGConfigGetContext(config);
if (context) {
auto jlogger = reinterpret_cast<global_ref<jobject> *>(context);
jlogger->releaseAlias();
delete jlogger;
}

if (logger) {
YGConfigSetContext(config, new global_ref<jobject>(make_global(logger)));
YGConfigSetLogger(config, YGJNILogFunc);
} else {
YGConfigSetContext(config, NULL);
YGConfigSetLogger(config, NULL);
}
}

jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
return YGNodeGetInstanceCount();
}
Expand Down Expand Up @@ -498,8 +521,6 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGNodeStyleGetAspectRatio),
YGMakeNativeMethod(jni_YGNodeStyleSetAspectRatio),
YGMakeNativeMethod(jni_YGNodeGetInstanceCount),
YGMakeNativeMethod(jni_YGSetLogger),
YGMakeNativeMethod(jni_YGLog),
YGMakeNativeMethod(jni_YGNodePrint),
});
registerNatives("com/facebook/yoga/YogaConfig",
Expand All @@ -510,6 +531,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults),
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
YGMakeNativeMethod(jni_YGConfigSetLogger),
});
});
}
Loading

0 comments on commit 5f2edfc

Please sign in to comment.