351 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
		
		
			
		
	
	
			351 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
| 
								 | 
							
								/*
							 | 
						|||
| 
								 | 
							
								Copyright (c) 2017 Marijn Zwemmer
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Permission is hereby granted, free of charge, to any person obtaining a copy
							 | 
						|||
| 
								 | 
							
								of this software and associated documentation files (the "Software"), to deal
							 | 
						|||
| 
								 | 
							
								in the Software without restriction, including without limitation the rights
							 | 
						|||
| 
								 | 
							
								to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
							 | 
						|||
| 
								 | 
							
								copies of the Software, and to permit persons to whom the Software is
							 | 
						|||
| 
								 | 
							
								furnished to do so, subject to the following conditions:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The above copyright notice and this permission notice shall be included in all
							 | 
						|||
| 
								 | 
							
								copies or substantial portions of the Software.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						|||
| 
								 | 
							
								IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						|||
| 
								 | 
							
								FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
							 | 
						|||
| 
								 | 
							
								AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						|||
| 
								 | 
							
								LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
							 | 
						|||
| 
								 | 
							
								OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
							 | 
						|||
| 
								 | 
							
								SOFTWARE.
							 | 
						|||
| 
								 | 
							
								*/
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								using System;
							 | 
						|||
| 
								 | 
							
								using System.Collections;
							 | 
						|||
| 
								 | 
							
								using System.Collections.Generic;
							 | 
						|||
| 
								 | 
							
								using System.Reflection;
							 | 
						|||
| 
								 | 
							
								using UnityEditor;
							 | 
						|||
| 
								 | 
							
								using UnityEngine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace AmazonInternal.ThirdParty {
							 | 
						|||
| 
								 | 
							
									public class AmazonCoroutines {
							 | 
						|||
| 
								 | 
							
										public class AmazonCoroutine {
							 | 
						|||
| 
								 | 
							
											public ICoroutineYield currentYield = new YieldDefault ();
							 | 
						|||
| 
								 | 
							
											public IEnumerator routine;
							 | 
						|||
| 
								 | 
							
											public string routineUniqueHash;
							 | 
						|||
| 
								 | 
							
											public string ownerUniqueHash;
							 | 
						|||
| 
								 | 
							
											public string MethodName = "";
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public int ownerHash;
							 | 
						|||
| 
								 | 
							
											public string ownerType;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool finished = false;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public AmazonCoroutine (IEnumerator routine, int ownerHash, string ownerType) {
							 | 
						|||
| 
								 | 
							
												this.routine = routine;
							 | 
						|||
| 
								 | 
							
												this.ownerHash = ownerHash;
							 | 
						|||
| 
								 | 
							
												this.ownerType = ownerType;
							 | 
						|||
| 
								 | 
							
												ownerUniqueHash = ownerHash + "_" + ownerType;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												if (routine != null) {
							 | 
						|||
| 
								 | 
							
													string[] split = routine.ToString ().Split ('<', '>');
							 | 
						|||
| 
								 | 
							
													if (split.Length == 3) {
							 | 
						|||
| 
								 | 
							
														this.MethodName = split[1];
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												routineUniqueHash = ownerHash + "_" + ownerType + "_" + MethodName;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public AmazonCoroutine (string methodName, int ownerHash, string ownerType) {
							 | 
						|||
| 
								 | 
							
												MethodName = methodName;
							 | 
						|||
| 
								 | 
							
												this.ownerHash = ownerHash;
							 | 
						|||
| 
								 | 
							
												this.ownerType = ownerType;
							 | 
						|||
| 
								 | 
							
												ownerUniqueHash = ownerHash + "_" + ownerType;
							 | 
						|||
| 
								 | 
							
												routineUniqueHash = ownerHash + "_" + ownerType + "_" + MethodName;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										public interface ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											bool IsDone (float deltaTime);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldDefault : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												return true;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldWaitForSeconds : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public float timeLeft;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												timeLeft -= deltaTime;
							 | 
						|||
| 
								 | 
							
												return timeLeft < 0;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldCustomYieldInstruction : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public CustomYieldInstruction customYield;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												return !customYield.keepWaiting;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldWWW : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public WWW Www;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												return Www.isDone;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldAsync : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public AsyncOperation asyncOperation;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												return asyncOperation.isDone;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										struct YieldNestedCoroutine : ICoroutineYield {
							 | 
						|||
| 
								 | 
							
											public AmazonCoroutine coroutine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											public bool IsDone (float deltaTime) {
							 | 
						|||
| 
								 | 
							
												return coroutine.finished;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										static AmazonCoroutines instance = null;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										Dictionary<string, List<AmazonCoroutine>> coroutineDict = new Dictionary<string, List<AmazonCoroutine>> ();
							 | 
						|||
| 
								 | 
							
										List<List<AmazonCoroutine>> tempCoroutineList = new List<List<AmazonCoroutine>> ();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										Dictionary<string, Dictionary<string, AmazonCoroutine>> coroutineOwnerDict =
							 | 
						|||
| 
								 | 
							
											new Dictionary<string, Dictionary<string, AmazonCoroutine>> ();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										DateTime previousTimeSinceStartup;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>Starts a coroutine.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="routine">The coroutine to start.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static AmazonCoroutine StartCoroutine (IEnumerator routine, object thisReference) {
							 | 
						|||
| 
								 | 
							
											CreateInstanceIfNeeded ();
							 | 
						|||
| 
								 | 
							
											return instance.GoStartCoroutine (routine, thisReference);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>Starts a coroutine.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="methodName">The name of the coroutine method to start.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static AmazonCoroutine StartCoroutine (string methodName, object thisReference) {
							 | 
						|||
| 
								 | 
							
											return StartCoroutine (methodName, null, thisReference);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>Starts a coroutine.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="methodName">The name of the coroutine method to start.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="value">The parameter to pass to the coroutine.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static AmazonCoroutine StartCoroutine (string methodName, object value, object thisReference) {
							 | 
						|||
| 
								 | 
							
											MethodInfo methodInfo = thisReference.GetType ()
							 | 
						|||
| 
								 | 
							
												.GetMethod (methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
							 | 
						|||
| 
								 | 
							
											if (methodInfo == null) {
							 | 
						|||
| 
								 | 
							
												Debug.LogError ("Coroutine '" + methodName + "' couldn't be started, the method doesn't exist!");
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											object returnValue;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											if (value == null) {
							 | 
						|||
| 
								 | 
							
												returnValue = methodInfo.Invoke (thisReference, null);
							 | 
						|||
| 
								 | 
							
											} else {
							 | 
						|||
| 
								 | 
							
												returnValue = methodInfo.Invoke (thisReference, new object[] { value });
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											if (returnValue is IEnumerator) {
							 | 
						|||
| 
								 | 
							
												CreateInstanceIfNeeded ();
							 | 
						|||
| 
								 | 
							
												return instance.GoStartCoroutine ((IEnumerator) returnValue, thisReference);
							 | 
						|||
| 
								 | 
							
											} else {
							 | 
						|||
| 
								 | 
							
												Debug.LogError ("Coroutine '" + methodName + "' couldn't be started, the method doesn't return an IEnumerator!");
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											return null;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>Stops all coroutines being the routine running on the passed instance.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="routine"> The coroutine to stop.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static void StopCoroutine (IEnumerator routine, object thisReference) {
							 | 
						|||
| 
								 | 
							
											CreateInstanceIfNeeded ();
							 | 
						|||
| 
								 | 
							
											instance.GoStopCoroutine (routine, thisReference);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>
							 | 
						|||
| 
								 | 
							
										/// Stops all coroutines named methodName running on the passed instance.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="methodName"> The name of the coroutine method to stop.</param>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static void StopCoroutine (string methodName, object thisReference) {
							 | 
						|||
| 
								 | 
							
											CreateInstanceIfNeeded ();
							 | 
						|||
| 
								 | 
							
											instance.GoStopCoroutine (methodName, thisReference);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										/// <summary>
							 | 
						|||
| 
								 | 
							
										/// Stops all coroutines running on the passed instance.</summary>
							 | 
						|||
| 
								 | 
							
										/// <param name="thisReference">Reference to the instance of the class containing the method.</param>
							 | 
						|||
| 
								 | 
							
										public static void StopAllCoroutines (object thisReference) {
							 | 
						|||
| 
								 | 
							
											CreateInstanceIfNeeded ();
							 | 
						|||
| 
								 | 
							
											instance.GoStopAllCoroutines (thisReference);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										static void CreateInstanceIfNeeded () {
							 | 
						|||
| 
								 | 
							
											if (instance == null) {
							 | 
						|||
| 
								 | 
							
												instance = new AmazonCoroutines ();
							 | 
						|||
| 
								 | 
							
												instance.Initialize ();
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void Initialize () {
							 | 
						|||
| 
								 | 
							
											previousTimeSinceStartup = DateTime.Now;
							 | 
						|||
| 
								 | 
							
											EditorApplication.update += OnUpdate;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void GoStopCoroutine (IEnumerator routine, object thisReference) {
							 | 
						|||
| 
								 | 
							
											GoStopActualRoutine (CreateCoroutine (routine, thisReference));
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void GoStopCoroutine (string methodName, object thisReference) {
							 | 
						|||
| 
								 | 
							
											GoStopActualRoutine (CreateCoroutineFromString (methodName, thisReference));
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void GoStopActualRoutine (AmazonCoroutine routine) {
							 | 
						|||
| 
								 | 
							
											if (coroutineDict.ContainsKey (routine.routineUniqueHash)) {
							 | 
						|||
| 
								 | 
							
												coroutineOwnerDict[routine.ownerUniqueHash].Remove (routine.routineUniqueHash);
							 | 
						|||
| 
								 | 
							
												coroutineDict.Remove (routine.routineUniqueHash);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void GoStopAllCoroutines (object thisReference) {
							 | 
						|||
| 
								 | 
							
											AmazonCoroutine coroutine = CreateCoroutine (null, thisReference);
							 | 
						|||
| 
								 | 
							
											if (coroutineOwnerDict.ContainsKey (coroutine.ownerUniqueHash)) {
							 | 
						|||
| 
								 | 
							
												foreach (var couple in coroutineOwnerDict[coroutine.ownerUniqueHash]) {
							 | 
						|||
| 
								 | 
							
													coroutineDict.Remove (couple.Value.routineUniqueHash);
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
												coroutineOwnerDict.Remove (coroutine.ownerUniqueHash);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										AmazonCoroutine GoStartCoroutine (IEnumerator routine, object thisReference) {
							 | 
						|||
| 
								 | 
							
											if (routine == null) {
							 | 
						|||
| 
								 | 
							
												Debug.LogException (new Exception ("IEnumerator is null!"), null);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											AmazonCoroutine coroutine = CreateCoroutine (routine, thisReference);
							 | 
						|||
| 
								 | 
							
											GoStartCoroutine (coroutine);
							 | 
						|||
| 
								 | 
							
											return coroutine;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void GoStartCoroutine (AmazonCoroutine coroutine) {
							 | 
						|||
| 
								 | 
							
											if (!coroutineDict.ContainsKey (coroutine.routineUniqueHash)) {
							 | 
						|||
| 
								 | 
							
												List<AmazonCoroutine> newCoroutineList = new List<AmazonCoroutine> ();
							 | 
						|||
| 
								 | 
							
												coroutineDict.Add (coroutine.routineUniqueHash, newCoroutineList);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											coroutineDict[coroutine.routineUniqueHash].Add (coroutine);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											if (!coroutineOwnerDict.ContainsKey (coroutine.ownerUniqueHash)) {
							 | 
						|||
| 
								 | 
							
												Dictionary<string, AmazonCoroutine> newCoroutineDict = new Dictionary<string, AmazonCoroutine> ();
							 | 
						|||
| 
								 | 
							
												coroutineOwnerDict.Add (coroutine.ownerUniqueHash, newCoroutineDict);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											// If the method from the same owner has been stored before, it doesn't have to be stored anymore,
							 | 
						|||
| 
								 | 
							
											// One reference is enough in order for "StopAllCoroutines" to work
							 | 
						|||
| 
								 | 
							
											if (!coroutineOwnerDict[coroutine.ownerUniqueHash].ContainsKey (coroutine.routineUniqueHash)) {
							 | 
						|||
| 
								 | 
							
												coroutineOwnerDict[coroutine.ownerUniqueHash].Add (coroutine.routineUniqueHash, coroutine);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											MoveNext (coroutine);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										AmazonCoroutine CreateCoroutine (IEnumerator routine, object thisReference) {
							 | 
						|||
| 
								 | 
							
											return new AmazonCoroutine (routine, thisReference.GetHashCode (), thisReference.GetType ().ToString ());
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										AmazonCoroutine CreateCoroutineFromString (string methodName, object thisReference) {
							 | 
						|||
| 
								 | 
							
											return new AmazonCoroutine (methodName, thisReference.GetHashCode (), thisReference.GetType ().ToString ());
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										void OnUpdate () {
							 | 
						|||
| 
								 | 
							
											float deltaTime = (float) (DateTime.Now.Subtract (previousTimeSinceStartup).TotalMilliseconds / 1000.0f);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											previousTimeSinceStartup = DateTime.Now;
							 | 
						|||
| 
								 | 
							
											if (coroutineDict.Count == 0) {
							 | 
						|||
| 
								 | 
							
												return;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											tempCoroutineList.Clear ();
							 | 
						|||
| 
								 | 
							
											foreach (var pair in coroutineDict)
							 | 
						|||
| 
								 | 
							
												tempCoroutineList.Add (pair.Value);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											for (var i = tempCoroutineList.Count - 1; i >= 0; i--) {
							 | 
						|||
| 
								 | 
							
												List<AmazonCoroutine> coroutines = tempCoroutineList[i];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												for (int j = coroutines.Count - 1; j >= 0; j--) {
							 | 
						|||
| 
								 | 
							
													AmazonCoroutine coroutine = coroutines[j];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
													if (!coroutine.currentYield.IsDone (deltaTime)) {
							 | 
						|||
| 
								 | 
							
														continue;
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
													if (!MoveNext (coroutine)) {
							 | 
						|||
| 
								 | 
							
														coroutines.RemoveAt (j);
							 | 
						|||
| 
								 | 
							
														coroutine.currentYield = null;
							 | 
						|||
| 
								 | 
							
														coroutine.finished = true;
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
													if (coroutines.Count == 0) {
							 | 
						|||
| 
								 | 
							
														coroutineDict.Remove (coroutine.ownerUniqueHash);
							 | 
						|||
| 
								 | 
							
													}
							 | 
						|||
| 
								 | 
							
												}
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										static bool MoveNext (AmazonCoroutine coroutine) {
							 | 
						|||
| 
								 | 
							
											if (coroutine.routine.MoveNext ()) {
							 | 
						|||
| 
								 | 
							
												return Process (coroutine);
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											return false;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										// returns false if no next, returns true if OK
							 | 
						|||
| 
								 | 
							
										static bool Process (AmazonCoroutine coroutine) {
							 | 
						|||
| 
								 | 
							
											object current = coroutine.routine.Current;
							 | 
						|||
| 
								 | 
							
											if (current == null) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldDefault ();
							 | 
						|||
| 
								 | 
							
											} else if (current is WaitForSeconds) {
							 | 
						|||
| 
								 | 
							
												float seconds = float.Parse (GetInstanceField (typeof (WaitForSeconds), current, "m_Seconds").ToString ());
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldWaitForSeconds () { timeLeft = seconds };
							 | 
						|||
| 
								 | 
							
											} else if (current is CustomYieldInstruction) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldCustomYieldInstruction () {
							 | 
						|||
| 
								 | 
							
													customYield = current as CustomYieldInstruction
							 | 
						|||
| 
								 | 
							
												};
							 | 
						|||
| 
								 | 
							
											} else if (current is WWW) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldWWW { Www = (WWW) current };
							 | 
						|||
| 
								 | 
							
											} else if (current is WaitForFixedUpdate || current is WaitForEndOfFrame) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldDefault ();
							 | 
						|||
| 
								 | 
							
											} else if (current is AsyncOperation) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldAsync { asyncOperation = (AsyncOperation) current };
							 | 
						|||
| 
								 | 
							
											} else if (current is AmazonCoroutine) {
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldNestedCoroutine { coroutine = (AmazonCoroutine) current };
							 | 
						|||
| 
								 | 
							
											} else {
							 | 
						|||
| 
								 | 
							
												Debug.LogException (
							 | 
						|||
| 
								 | 
							
													new Exception ("<" + coroutine.MethodName + "> yielded an unknown or unsupported type! (" + current.GetType () + ")"),
							 | 
						|||
| 
								 | 
							
													null);
							 | 
						|||
| 
								 | 
							
												coroutine.currentYield = new YieldDefault ();
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											return true;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										static object GetInstanceField (Type type, object instance, string fieldName) {
							 | 
						|||
| 
								 | 
							
											BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
							 | 
						|||
| 
								 | 
							
											FieldInfo field = type.GetField (fieldName, bindFlags);
							 | 
						|||
| 
								 | 
							
											return field.GetValue (instance);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 |