| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | 
							- using System;
 
- using System.Runtime.CompilerServices;
 
- using System.Runtime.InteropServices;
 
- using System.Threading;
 
- using Object = UnityEngine.Object;
 
- namespace UnityAsync
 
- {
 
- 	public interface IAwaitInstructionAwaiter
 
- 	{
 
- 		bool Evaluate();
 
- 		FrameScheduler Scheduler { get; }
 
- 	}
 
- 	/// <summary>
 
- 	/// Encapsulates an <see cref="UnityAsync.IAwaitInstruction"/> with additional information about how the instruction
 
- 	/// will be queued and executed. Continuations are intended to be awaited after or shortly after instantiation.
 
- 	/// </summary>
 
- 	/// <typeparam name="T">The type of <see cref="UnityAsync.IAwaitInstruction"/> to encapsulate.</typeparam>
 
- 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
 
- 	public struct AwaitInstructionAwaiter<T> : IAwaitInstructionAwaiter, INotifyCompletion where T : IAwaitInstruction
 
- 	{
 
- 		static Exception exception;
 
- 		
 
- 		Object owner;
 
- 		CancellationToken cancellationToken;
 
- 		/// <summary>
 
- 		/// Evaluate the encapsulated <see cref="UnityAsync.IAwaitInstruction"/>. If the instruction is finished, the
 
- 		/// continuation delegate is invoked and the method returns <code>true</code>. If the owner is destroyed, the
 
- 		/// method will return true without invoking the continuation delegate. If it was cancelled, an exception is
 
- 		/// is thrown when the continuation delegate is invoked. Otherwise, returns false (i.e. the instruction is not
 
- 		/// finished).
 
- 		/// </summary>
 
- 		/// <returns>
 
- 		/// <code>true</code> if the <see cref="UnityAsync.IAwaitInstruction"/> is finished, its owner destroyed,
 
- 		/// or has been cancelled, otherwise <code>false</code>.
 
- 		/// </returns>
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public bool Evaluate()
 
- 		{
 
- 			try
 
- 			{
 
- 				// if cancelled, throw exception
 
- 				cancellationToken.ThrowIfCancellationRequested();
 
- 				
 
- 				// if owner is destroyed, behaves like a UnityEngine.Coroutine, ie:
 
- 				// "With this object's death, the thread of prophecy is severed. Restore a saved game to restore the
 
- 				// weave of fate, or persist in the doomed world you have created."
 
- 				if(!owner)
 
- 					return true;
 
- 				// if not completed, return false to put it back into a queue for next frame
 
- 				if(!instruction.IsCompleted())
 
- 					return false;
 
- 			}
 
- 			catch(Exception e)
 
- 			{
 
- 				// store exception in static field
 
- 				exception = e;
 
- 				
 
- 				// exception is rethrown in GetResult, at start of continuation
 
- 				continuation();
 
- 				return true;
 
- 			}
 
- 			
 
- 			// if we get here, it completed without exceptions and we can call continuation and be done with it
 
- 			continuation();
 
- 			
 
- 			return true;
 
- 		}
 
- 		public FrameScheduler Scheduler { get; private set; }
 
- 		T instruction;
 
- 		Action continuation;
 
- 		public AwaitInstructionAwaiter(in T inst)
 
- 		{
 
- 			instruction = inst;
 
- 			continuation = null;
 
- 			owner = AsyncManager.Instance;
 
- 			exception = null;
 
- 			Scheduler = FrameScheduler.Update;
 
- 		}
 
- 		public AwaitInstructionAwaiter(in T inst, FrameScheduler scheduler)
 
- 		{
 
- 			instruction = inst;
 
- 			continuation = null;
 
- 			owner = AsyncManager.Instance;
 
- 			exception = null;
 
- 			Scheduler = scheduler;
 
- 		}
 
- 		
 
- 		public AwaitInstructionAwaiter(in T inst, CancellationToken cancellationToken, FrameScheduler scheduler)
 
- 		{
 
- 			instruction = inst;
 
- 			continuation = null;
 
- 			owner = AsyncManager.Instance;
 
- 			exception = null;
 
- 			this.cancellationToken = cancellationToken;
 
- 			Scheduler = scheduler;
 
- 		}
 
- 		
 
- 		public AwaitInstructionAwaiter(in T inst, Object owner, FrameScheduler scheduler)
 
- 		{
 
- 			instruction = inst;
 
- 			continuation = null;
 
- 			this.owner = owner;
 
- 			exception = null;
 
- 			Scheduler = scheduler;
 
- 		}
 
- 		public bool IsCompleted => false;
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public void OnCompleted(Action continuation)
 
- 		{
 
- 			this.continuation = continuation;
 
- 			AsyncManager.AddContinuation(this);
 
- 		}
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public void GetResult()
 
- 		{
 
- 			if(exception != null)
 
- 			{
 
- 				var e = exception;
 
- 				exception = null;
 
- 				throw e;
 
- 			}
 
- 		}
 
- 		
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(Object owner)
 
- 		{
 
- 			this.owner = owner;
 
- 			return this;
 
- 		}
 
- 		
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(CancellationToken cancellationToken)
 
- 		{
 
- 			this.cancellationToken = cancellationToken;
 
- 			return this;
 
- 		}
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(FrameScheduler scheduler)
 
- 		{
 
- 			Scheduler = scheduler;
 
- 			return this;
 
- 		}
 
- 		
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(Object owner, FrameScheduler scheduler)
 
- 		{
 
- 			this.owner = owner;
 
- 			Scheduler = scheduler;
 
- 			return this;
 
- 		}
 
- 		
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(CancellationToken cancellationToken, FrameScheduler scheduler)
 
- 		{
 
- 			this.cancellationToken = cancellationToken;
 
- 			Scheduler = scheduler;
 
- 			return this;
 
- 		}
 
- 		
 
- 		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 
- 		public AwaitInstructionAwaiter<T> ConfigureAwait(Object owner, CancellationToken cancellationToken, FrameScheduler scheduler)
 
- 		{
 
- 			this.owner = owner;
 
- 			this.cancellationToken = cancellationToken;
 
- 			Scheduler = scheduler;
 
- 			return this;
 
- 		}
 
- 	}
 
- }
 
 
  |