| using UnityEngine; | 
| using System.Collections.Generic; | 
| using ILRuntime.Other; | 
| using System; | 
| using System.Collections; | 
| using ILRuntime.Runtime.Enviorment; | 
| using ILRuntime.Runtime.Intepreter; | 
| using ILRuntime.CLR.Method; | 
|   | 
| namespace ILCrossBinding | 
| { | 
|     public class CoroutineAdapter : CrossBindingAdaptor | 
|     { | 
|         public override Type BaseCLRType | 
|         { | 
|             get | 
|             { | 
|                 return null; | 
|             } | 
|         } | 
|   | 
|         public override Type[] BaseCLRTypes | 
|         { | 
|             get | 
|             { | 
|                 //跨域继承只能有1个Adapter,因此应该尽量避免一个类同时实现多个外部接口,对于coroutine来说是IEnumerator<object>,IEnumerator和IDisposable, | 
|                 //ILRuntime虽然支持,但是一定要小心这种用法,使用不当很容易造成不可预期的问题 | 
|                 //日常开发如果需要实现多个DLL外部接口,请在Unity这边先做一个基类实现那些个接口,然后继承那个基类 | 
|                 return new Type[] { typeof(IEnumerator<object>), typeof(IEnumerator), typeof(IDisposable) }; | 
|             } | 
|         } | 
|   | 
|         public override Type AdaptorType | 
|         { | 
|             get | 
|             { | 
|                 return typeof(Adaptor); | 
|             } | 
|         } | 
|   | 
|         public override object CreateCLRInstance(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) | 
|         { | 
|             return new Adaptor(appdomain, instance); | 
|         } | 
|         //Coroutine生成的类实现了IEnumerator<System.Object>, IEnumerator, IDisposable,所以都要实现,这个可以通过reflector之类的IL反编译软件得知 | 
|         internal class Adaptor : IEnumerator<System.Object>, IEnumerator, IDisposable, CrossBindingAdaptorType | 
|         { | 
|             ILTypeInstance instance; | 
|             ILRuntime.Runtime.Enviorment.AppDomain appdomain; | 
|   | 
|             public Adaptor() | 
|             { | 
|   | 
|             } | 
|   | 
|             public Adaptor(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) | 
|             { | 
|                 this.appdomain = appdomain; | 
|                 this.instance = instance; | 
|             } | 
|   | 
|             public ILTypeInstance ILInstance { get { return instance; } } | 
|   | 
|             IMethod mCurrentMethod; | 
|             bool mCurrentMethodGot; | 
|             public object Current | 
|             { | 
|                 get | 
|                 { | 
|                     if (!mCurrentMethodGot) | 
|                     { | 
|                         mCurrentMethod = instance.Type.GetMethod("get_Current", 0); | 
|                         if (mCurrentMethod == null) | 
|                         { | 
|                             //这里写System.Collections.IEnumerator.get_Current而不是直接get_Current是因为coroutine生成的类是显式实现这个接口的,通过Reflector等反编译软件可得知 | 
|                             //为了兼容其他只实现了单一Current属性的,所以上面先直接取了get_Current | 
|                             mCurrentMethod = instance.Type.GetMethod("System.Collections.IEnumerator.get_Current", 0); | 
|                         } | 
|                         mCurrentMethodGot = true; | 
|                     } | 
|   | 
|                     if (mCurrentMethod != null) | 
|                     { | 
|                         var res = appdomain.Invoke(mCurrentMethod, instance, null); | 
|                         return res; | 
|                     } | 
|                     else | 
|                     { | 
|                         return null; | 
|                     } | 
|                 } | 
|             } | 
|   | 
|             IMethod mDisposeMethod; | 
|             bool mDisposeMethodGot; | 
|             public void Dispose() | 
|             { | 
|                 if (!mDisposeMethodGot) | 
|                 { | 
|                     mDisposeMethod = instance.Type.GetMethod("Dispose", 0); | 
|                     if (mDisposeMethod == null) | 
|                     { | 
|                         mDisposeMethod = instance.Type.GetMethod("System.IDisposable.Dispose", 0); | 
|                     } | 
|                     mDisposeMethodGot = true; | 
|                 } | 
|   | 
|                 if (mDisposeMethod != null) | 
|                 { | 
|                     appdomain.Invoke(mDisposeMethod, instance, null); | 
|                 } | 
|             } | 
|   | 
|             IMethod mMoveNextMethod; | 
|             bool mMoveNextMethodGot; | 
|             public bool MoveNext() | 
|             { | 
|                 if (!mMoveNextMethodGot) | 
|                 { | 
|                     mMoveNextMethod = instance.Type.GetMethod("MoveNext", 0); | 
|                     mMoveNextMethodGot = true; | 
|                 } | 
|   | 
|                 if (mMoveNextMethod != null) | 
|                 { | 
|                     return (bool)appdomain.Invoke(mMoveNextMethod, instance, null); | 
|                 } | 
|                 else | 
|                 { | 
|                     return false; | 
|                 } | 
|             } | 
|   | 
|             IMethod mResetMethod; | 
|             bool mResetMethodGot; | 
|             public void Reset() | 
|             { | 
|                 if (!mResetMethodGot) | 
|                 { | 
|                     mResetMethod = instance.Type.GetMethod("Reset", 0); | 
|                     mResetMethodGot = true; | 
|                 } | 
|   | 
|                 if (mResetMethod != null) | 
|                 { | 
|                     appdomain.Invoke(mResetMethod, instance, null); | 
|                 } | 
|             } | 
|   | 
|             public override string ToString() | 
|             { | 
|                 IMethod m = appdomain.ObjectType.GetMethod("ToString", 0); | 
|                 m = instance.Type.GetVirtualMethod(m); | 
|                 if (m == null || m is ILMethod) | 
|                 { | 
|                     return instance.ToString(); | 
|                 } | 
|                 else | 
|                     return instance.Type.FullName; | 
|             } | 
|         } | 
|     } | 
| } |