[C#][iOS] Fix callbacks on AOT #388
@@ -22,6 +22,10 @@ namespace Facebook.Yoga
|
|||||||
|
|
||||||
internal class YGNodeHandle : SafeHandle
|
internal class YGNodeHandle : SafeHandle
|
||||||
{
|
{
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
private GCHandle _managed;
|
||||||
|
#endif
|
||||||
|
|
||||||
private YGNodeHandle() : base(IntPtr.Zero, true)
|
private YGNodeHandle() : base(IntPtr.Zero, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -36,10 +40,39 @@ namespace Facebook.Yoga
|
|||||||
|
|
||||||
protected override bool ReleaseHandle()
|
protected override bool ReleaseHandle()
|
||||||
{
|
{
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
if (_managed.IsAllocated)
|
||||||
|
{
|
||||||
|
_managed.Free();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Native.YGNodeFree(this.handle);
|
Native.YGNodeFree(this.handle);
|
||||||
GC.KeepAlive(this);
|
GC.KeepAlive(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
public void SetContext(YogaNode node)
|
||||||
|
{
|
||||||
|
if (!_managed.IsAllocated)
|
||||||
|
{
|
||||||
|
_managed = GCHandle.Alloc(node, GCHandleType.Weak);
|
||||||
|
Native.YGNodeSetContext(this.handle, GCHandle.ToIntPtr(_managed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static YogaNode GetManaged(IntPtr ygNodePtr)
|
||||||
|
{
|
||||||
|
var node =
|
||||||
|
GCHandle.FromIntPtr(Native.YGNodeGetContext(ygNodePtr)).Target as YogaNode;
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("YogaNode is already deallocated");
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -68,13 +101,17 @@ namespace Facebook.Yoga
|
|||||||
YogaExperimentalFeature feature);
|
YogaExperimentalFeature feature);
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void YGNodeInsertChild(YGNodeHandle node, YGNodeHandle child, uint index);
|
public static extern void YGNodeInsertChild(
|
||||||
|
YGNodeHandle node,
|
||||||
|
YGNodeHandle child,
|
||||||
|
uint index);
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child);
|
public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child);
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void YGNodeCalculateLayout(YGNodeHandle node,
|
public static extern void YGNodeCalculateLayout(
|
||||||
|
YGNodeHandle node,
|
||||||
float availableWidth,
|
float availableWidth,
|
||||||
float availableHeight,
|
float availableHeight,
|
||||||
YogaDirection parentDirection);
|
YogaDirection parentDirection);
|
||||||
@@ -105,7 +142,9 @@ namespace Facebook.Yoga
|
|||||||
[MarshalAs(UnmanagedType.FunctionPtr)] YogaBaselineFunc baselineFunc);
|
[MarshalAs(UnmanagedType.FunctionPtr)] YogaBaselineFunc baselineFunc);
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void YGNodeSetHasNewLayout(YGNodeHandle node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
|
public static extern void YGNodeSetHasNewLayout(
|
||||||
|
YGNodeHandle node,
|
||||||
|
[MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
|
||||||
|
|
||||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
[return: MarshalAs(UnmanagedType.I1)]
|
[return: MarshalAs(UnmanagedType.I1)]
|
||||||
@@ -328,5 +367,17 @@ namespace Facebook.Yoga
|
|||||||
public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
|
public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IOS
|
||||||
|
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr YGNodeGetContext(IntPtr node);
|
||||||
|
|
||||||
|
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void YGNodeSetContext(IntPtr node, IntPtr managed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
#if __IOS__
|
||||||
|
using ObjCRuntime;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Facebook.Yoga
|
namespace Facebook.Yoga
|
||||||
{
|
{
|
||||||
internal static class YogaLogger
|
internal static class YogaLogger
|
||||||
@@ -18,15 +22,15 @@ namespace Facebook.Yoga
|
|||||||
public delegate void Func(YogaLogLevel level, string message);
|
public delegate void Func(YogaLogLevel level, string message);
|
||||||
|
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
private static Func _managedLogger = null;
|
|
||||||
|
|
||||||
|
public static Func _loggerInternal = LoggerInternal;
|
||||||
public static Func Logger = null;
|
public static Func Logger = null;
|
||||||
|
|
||||||
public static void Initialize()
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
[MonoPInvokeCallback(typeof(Func))]
|
||||||
|
#endif
|
||||||
|
public static void LoggerInternal(YogaLogLevel level, string message)
|
||||||
{
|
{
|
||||||
if (!_initialized)
|
|
||||||
{
|
|
||||||
_managedLogger = (level, message) => {
|
|
||||||
if (Logger != null)
|
if (Logger != null)
|
||||||
{
|
{
|
||||||
Logger(level, message);
|
Logger(level, message);
|
||||||
@@ -36,8 +40,13 @@ namespace Facebook.Yoga
|
|||||||
{
|
{
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Native.YGInteropSetLogger(_managedLogger);
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
if (!_initialized)
|
||||||
|
{
|
||||||
|
Native.YGInteropSetLogger(_loggerInternal);
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,13 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
#endif
|
||||||
|
#if __IOS__
|
||||||
|
using ObjCRuntime;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Facebook.Yoga
|
namespace Facebook.Yoga
|
||||||
{
|
{
|
||||||
public partial class YogaNode : IEnumerable<YogaNode>
|
public partial class YogaNode : IEnumerable<YogaNode>
|
||||||
@@ -20,10 +27,15 @@ namespace Facebook.Yoga
|
|||||||
private WeakReference _parent;
|
private WeakReference _parent;
|
||||||
private List<YogaNode> _children;
|
private List<YogaNode> _children;
|
||||||
private MeasureFunction _measureFunction;
|
private MeasureFunction _measureFunction;
|
||||||
private YogaMeasureFunc _ygMeasureFunc;
|
|
||||||
private BaselineFunction _baselineFunction;
|
private BaselineFunction _baselineFunction;
|
||||||
private YogaBaselineFunc _ygBaselineFunc;
|
|
||||||
private object _data;
|
private object _data;
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
private static YogaMeasureFunc _measureInternalIOS = MeasureInternalIOS;
|
||||||
|
private static YogaBaselineFunc _baselineInternalIOS = BaselineInternalIOS;
|
||||||
|
#else
|
||||||
|
private YogaMeasureFunc _measureInternal;
|
||||||
|
private YogaBaselineFunc _baselineInternal;
|
||||||
|
#endif
|
||||||
|
|
||||||
public YogaNode()
|
public YogaNode()
|
||||||
{
|
{
|
||||||
@@ -545,15 +557,35 @@ namespace Facebook.Yoga
|
|||||||
public void SetMeasureFunction(MeasureFunction measureFunction)
|
public void SetMeasureFunction(MeasureFunction measureFunction)
|
||||||
{
|
{
|
||||||
_measureFunction = measureFunction;
|
_measureFunction = measureFunction;
|
||||||
_ygMeasureFunc = measureFunction != null ? MeasureInternal : (YogaMeasureFunc)null;
|
YogaMeasureFunc func = null;
|
||||||
Native.YGNodeSetMeasureFunc(_ygNode, _ygMeasureFunc);
|
if (measureFunction != null)
|
||||||
|
{
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
_ygNode.SetContext(this);
|
||||||
|
func = _measureInternalIOS;
|
||||||
|
#else
|
||||||
|
_measureInternal = MeasureInternal;
|
||||||
|
func = _measureInternal;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Native.YGNodeSetMeasureFunc(_ygNode, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBaselineFunction(BaselineFunction baselineFunction)
|
public void SetBaselineFunction(BaselineFunction baselineFunction)
|
||||||
{
|
{
|
||||||
_baselineFunction = baselineFunction;
|
_baselineFunction = baselineFunction;
|
||||||
_ygBaselineFunc = baselineFunction != null ? BaselineInternal : (YogaBaselineFunc)null;
|
YogaBaselineFunc func = null;
|
||||||
Native.YGNodeSetBaselineFunc(_ygNode, _ygBaselineFunc);
|
if (baselineFunction != null)
|
||||||
|
{
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
_ygNode.SetContext(this);
|
||||||
|
func = _baselineInternalIOS;
|
||||||
|
#else
|
||||||
|
_baselineInternal = BaselineInternal;
|
||||||
|
func = _baselineInternal;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Native.YGNodeSetBaselineFunc(_ygNode, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateLayout()
|
public void CalculateLayout()
|
||||||
@@ -565,6 +597,20 @@ namespace Facebook.Yoga
|
|||||||
Native.YGNodeStyleGetDirection(_ygNode));
|
Native.YGNodeStyleGetDirection(_ygNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
[MonoPInvokeCallback(typeof(YogaMeasureFunc))]
|
||||||
|
private static YogaSize MeasureInternalIOS(
|
||||||
|
IntPtr ygNodePtr,
|
||||||
|
float width,
|
||||||
|
YogaMeasureMode widthMode,
|
||||||
|
float height,
|
||||||
|
YogaMeasureMode heightMode)
|
||||||
|
{
|
||||||
|
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
|
||||||
|
return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private YogaSize MeasureInternal(
|
private YogaSize MeasureInternal(
|
||||||
IntPtr node,
|
IntPtr node,
|
||||||
float width,
|
float width,
|
||||||
@@ -580,6 +626,18 @@ namespace Facebook.Yoga
|
|||||||
return _measureFunction(this, width, widthMode, height, heightMode);
|
return _measureFunction(this, width, widthMode, height, heightMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||||
|
[MonoPInvokeCallback(typeof(YogaBaselineFunc))]
|
||||||
|
private static float BaselineInternalIOS(
|
||||||
|
IntPtr ygNodePtr,
|
||||||
|
float width,
|
||||||
|
float height)
|
||||||
|
{
|
||||||
|
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
|
||||||
|
return node.BaselineInternal(IntPtr.Zero, width, height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private float BaselineInternal(IntPtr node, float width, float height)
|
private float BaselineInternal(IntPtr node, float width, float height)
|
||||||
{
|
{
|
||||||
if (_baselineFunction == null)
|
if (_baselineFunction == null)
|
||||||
|
@@ -365,6 +365,7 @@ namespace Facebook.Yoga
|
|||||||
child = null;
|
child = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !__IOS__
|
||||||
[Test]
|
[Test]
|
||||||
public void TestParentDestructor()
|
public void TestParentDestructor()
|
||||||
{
|
{
|
||||||
@@ -386,6 +387,7 @@ namespace Facebook.Yoga
|
|||||||
Assert.AreEqual(instanceCount + 1, YogaNode.GetInstanceCount());
|
Assert.AreEqual(instanceCount + 1, YogaNode.GetInstanceCount());
|
||||||
parent.Insert(0, child);
|
parent.Insert(0, child);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestClearWithChildDestructor()
|
public void TestClearWithChildDestructor()
|
||||||
|
Reference in New Issue
Block a user