Free GCHandle

This commit is contained in:
Kazuki Sakamoto
2017-02-10 14:51:38 -08:00
parent 376ab71bb0
commit 1ceffea28e
3 changed files with 41 additions and 31 deletions

View File

@@ -22,6 +22,8 @@ namespace Facebook.Yoga
internal class YGNodeHandle : SafeHandle internal class YGNodeHandle : SafeHandle
{ {
private GCHandle _managed;
private YGNodeHandle() : base(IntPtr.Zero, true) private YGNodeHandle() : base(IntPtr.Zero, true)
{ {
} }
@@ -36,10 +38,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)]
@@ -63,7 +94,7 @@ namespace Facebook.Yoga
public static extern IntPtr YGNodeGetContext(IntPtr node); public static extern IntPtr YGNodeGetContext(IntPtr node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeSetContext(YGNodeHandle node, IntPtr managed); public static extern void YGNodeSetContext(IntPtr node, IntPtr managed);
#endif #endif
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]

View File

@@ -12,8 +12,10 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
#if __IOS__ #if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endif
#if __IOS__
using ObjCRuntime; using ObjCRuntime;
#endif #endif
@@ -27,9 +29,6 @@ namespace Facebook.Yoga
private MeasureFunction _measureFunction; private MeasureFunction _measureFunction;
private BaselineFunction _baselineFunction; private BaselineFunction _baselineFunction;
private object _data; private object _data;
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
private GCHandle _managed;
#endif
public YogaNode() public YogaNode()
{ {
@@ -548,28 +547,6 @@ namespace Facebook.Yoga
return _children != null ? _children.IndexOf(node) : -1; return _children != null ? _children.IndexOf(node) : -1;
} }
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
private void SetContext()
{
if (!_managed.IsAllocated)
{
_managed = GCHandle.Alloc(this, GCHandleType.Weak);
Native.YGNodeSetContext(_ygNode, GCHandle.ToIntPtr(_managed));
}
}
private 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
public void SetMeasureFunction(MeasureFunction measureFunction) public void SetMeasureFunction(MeasureFunction measureFunction)
{ {
_measureFunction = measureFunction; _measureFunction = measureFunction;
@@ -577,7 +554,7 @@ namespace Facebook.Yoga
if (measureFunction != null) if (measureFunction != null)
{ {
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__ #if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
SetContext(); _ygNode.SetContext(this);
func = MeasureInternalIOS; func = MeasureInternalIOS;
#else #else
func = MeasureInternal; func = MeasureInternal;
@@ -593,7 +570,7 @@ namespace Facebook.Yoga
if (baselineFunction != null) if (baselineFunction != null)
{ {
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__ #if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
SetContext(); _ygNode.SetContext(this);
func = BaselineInternalIOS; func = BaselineInternalIOS;
#else #else
func = BaselineInternal; func = BaselineInternal;
@@ -620,7 +597,7 @@ namespace Facebook.Yoga
float height, float height,
YogaMeasureMode heightMode) YogaMeasureMode heightMode)
{ {
var node = GetManaged(ygNodePtr); var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode); return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode);
} }
#endif #endif
@@ -648,7 +625,7 @@ namespace Facebook.Yoga
float width, float width,
float height) float height)
{ {
var node = GetManaged(ygNodePtr); var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.BaselineInternal(IntPtr.Zero, width, height); return node.BaselineInternal(IntPtr.Zero, width, height);
} }
#endif #endif

View File

@@ -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()