/// <summary> /// Останавливает рутину на текущем шаге с вызовом всех Finally и бряканием всех параллельных рутин /// </summary> public void Break() { if (!_finished) { if (_started) { while (_stack.Count > 0) { var entry = _stack.Pop(); var routine = entry.Enumerator as IRoutine; if (routine != null) { routine.Break(); } var @finally = entry.Finally; if (@finally != null) { foreach (var f in @finally) { f.Execute(); } } } if (_coroutines != null) { foreach (var coroutine in _coroutines) { coroutine.Break(); } } } _coroutines = null; _finished = true; } }
private bool Execution() { _coroutines.Execute(); while (_stack.Count > 0) { var entry = _stack.Peek(); var enumerator = entry.Enumerator; if (enumerator.MoveNext()) { if (enumerator.Current == null) { return(true); } #if UNITY if (enumerator.Current is AsyncOperation) { Push(Wait.Until(() => ((AsyncOperation)enumerator.Current).isDone)); } else if (enumerator.Current is WWW) { Push(Wait.Until(() => ((WWW)enumerator.Current).isDone)); } #endif else if (enumerator.Current is IEnumerator) { Push((IEnumerator)enumerator.Current); // вложенные корутины запускаются сразу! поэтому тут не return true; } else if (enumerator.Current is Break) { _exitValue = ((Break)enumerator.Current).Value; Pop(); } else if (enumerator.Current is Exit) { _exitValue = ((Exit)enumerator.Current).Value; while (_stack.Count > 0) { Pop(); } } else if (enumerator.Current is Finally) { if (entry.Finally == null) { entry.Finally = new List <Finally>(); } entry.Finally.Add((Finally)enumerator.Current); } else if (enumerator.Current is Parallel) { var parallel = (Parallel)enumerator.Current; if (parallel.IsStart) { (_coroutines ?? (_coroutines = new RoutinesSet())).Add(parallel.Routine); } else if (_coroutines != null) { _coroutines.Remove(parallel.Routine); } // Parallel не прерывает исполнения рутины! поэтому тут не return true; } } } else { Pop(); } } return(false); }