[csharp,iOS] Fix callbacks on AOT #386
@@ -111,6 +111,13 @@ namespace Facebook.Yoga
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public static extern bool YGNodeGetHasNewLayout(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeSetContext(YGNodeHandle node, IntPtr context);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr YGNodeGetContext(IntPtr node);
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region YG_NODE_STYLE_PROPERTY
|
||||
|
@@ -8,17 +8,14 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
internal static class YogaLogger
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void Func(YogaLogLevel level, string message);
|
||||
|
||||
private static bool _initialized;
|
||||
private static Func _managedLogger = null;
|
||||
|
||||
public static Func Logger = null;
|
||||
|
||||
@@ -26,7 +23,17 @@ namespace Facebook.Yoga
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
_managedLogger = (level, message) => {
|
||||
|
||||
Native.YGInteropSetLogger(LoggerInternal);
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if __IOS__
|
||||
[ObjCRuntime.MonoPInvokeCallback(typeof(Func))]
|
||||
#endif
|
||||
public static void LoggerInternal(YogaLogLevel level, string message)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger(level, message);
|
||||
@@ -36,10 +43,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
};
|
||||
Native.YGInteropSetLogger(_managedLogger);
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
@@ -546,6 +547,10 @@ namespace Facebook.Yoga
|
||||
{
|
||||
_measureFunction = measureFunction;
|
||||
_ygMeasureFunc = measureFunction != null ? MeasureInternal : (YogaMeasureFunc)null;
|
||||
|
||||
var handle = GCHandle.Alloc(this);
|
||||
Native.YGNodeSetContext(_ygNode, GCHandle.ToIntPtr(handle));
|
||||
|
||||
Native.YGNodeSetMeasureFunc(_ygNode, _ygMeasureFunc);
|
||||
}
|
||||
|
||||
@@ -553,6 +558,10 @@ namespace Facebook.Yoga
|
||||
{
|
||||
_baselineFunction = baselineFunction;
|
||||
_ygBaselineFunc = baselineFunction != null ? BaselineInternal : (YogaBaselineFunc)null;
|
||||
|
||||
var handle = GCHandle.Alloc(this);
|
||||
Native.YGNodeSetContext(_ygNode, GCHandle.ToIntPtr(handle));
|
||||
|
||||
Native.YGNodeSetBaselineFunc(_ygNode, _ygBaselineFunc);
|
||||
}
|
||||
|
||||
@@ -565,29 +574,47 @@ namespace Facebook.Yoga
|
||||
Native.YGNodeStyleGetDirection(_ygNode));
|
||||
}
|
||||
|
||||
private YogaSize MeasureInternal(
|
||||
#if __IOS__
|
||||
[ObjCRuntime.MonoPInvokeCallback(typeof(YogaMeasureFunc))]
|
||||
#endif
|
||||
|
||||
private static YogaSize MeasureInternal(
|
||||
IntPtr node,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode)
|
||||
{
|
||||
if (_measureFunction == null)
|
||||
|
||||
var yogaNodePointer = Native.YGNodeGetContext(node);
|
||||
|
||||
YogaNode yogaNode = GCHandle.FromIntPtr(yogaNodePointer).Target as YogaNode;
|
||||
|
||||
var measureFunction = yogaNode._measureFunction;
|
||||
if (measureFunction == null)
|
||||
{
|
||||
throw new InvalidOperationException("Measure function is not defined.");
|
||||
}
|
||||
|
||||
return _measureFunction(this, width, widthMode, height, heightMode);
|
||||
return measureFunction(yogaNode, width, widthMode, height, heightMode);
|
||||
}
|
||||
|
||||
private float BaselineInternal(IntPtr node, float width, float height)
|
||||
|
||||
#if __IOS__
|
||||
[ObjCRuntime.MonoPInvokeCallback(typeof(YogaBaselineFunc))]
|
||||
#endif
|
||||
private static float BaselineInternal(IntPtr node, float width, float height)
|
||||
{
|
||||
if (_baselineFunction == null)
|
||||
var yogaNodePointer = Native.YGNodeGetContext(node);
|
||||
|
||||
YogaNode yogaNode = GCHandle.FromIntPtr(yogaNodePointer).Target as YogaNode;
|
||||
|
||||
var baselineFunction = yogaNode._baselineFunction;
|
||||
if (baselineFunction == null)
|
||||
{
|
||||
throw new InvalidOperationException("Baseline function is not defined.");
|
||||
}
|
||||
|
||||
return _baselineFunction(this, width, height);
|
||||
return baselineFunction(yogaNode, width, height);
|
||||
}
|
||||
|
||||
public string Print(YogaPrintOptions options =
|
||||
|
Reference in New Issue
Block a user
Your patch never calls
GCHandle.Free
.Also you allocate a GCHandle both SetMeasureFunction and SetBaselineFunction, if both are called one of the values stored with YGNodeSetContext will be overwritten. The same will happen if either function is called more than once.
@splhack pr #388 fixes this.