Last active
April 27, 2018 15:30
-
-
Save spi8823/906abfd81b8a4d87d35ece6c05642c30 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
namespace spi8823 | |
{ | |
/// <summary> | |
/// Coroutineの役目を果たす | |
/// </summary> | |
public class Iterator | |
{ | |
protected Stack<IEnumerator<IteratorResult>> IteratorStack { get; } = new Stack<IEnumerator<IteratorResult>>(); | |
public bool IsProgressing { get; set; } = true; | |
public Iterator(IEnumerator<IteratorResult> iterator) | |
{ | |
IteratorStack.Push(iterator); | |
} | |
/// <summary> | |
/// イテレータを進める | |
/// </summary> | |
public void Progress() | |
{ | |
if (!IsProgressing) | |
return; | |
if (IteratorStack.Count == 0) | |
return; | |
var iterator = IteratorStack.Peek(); | |
iterator.MoveNext(); | |
var result = iterator.Current; | |
switch (result.Type) | |
{ | |
case IteratorResult.ResultType.Continue: | |
break; | |
case IteratorResult.ResultType.Canceled: | |
case IteratorResult.ResultType.Completed: | |
case IteratorResult.ResultType.Return: | |
IteratorStack.Pop(); | |
break; | |
case IteratorResult.ResultType.Nest: | |
IteratorStack.Push(result.NextIterator); | |
break; | |
} | |
} | |
public static IEnumerator<IteratorResult> WaitForSeconds(double second) | |
{ | |
var time = 0.0; | |
while(time < second) | |
{ | |
time += Time.deltaTime; | |
yield return IteratorResult.Continue(); | |
} | |
yield return IteratorResult.Completed(); | |
} | |
public static IEnumerator<IteratorResult> WaitWhile(System.Func<bool> function) | |
{ | |
while (function()) | |
yield return IteratorResult.Continue(); | |
yield return IteratorResult.Completed(); | |
} | |
public static IEnumerator<IteratorResult> WaitUntil(System.Func<bool> function) | |
{ | |
while (!function()) | |
yield return IteratorResult.Continue(); | |
yield return IteratorResult.Completed(); | |
} | |
} | |
/// <summary> | |
/// イテレータが返すべきクラス | |
/// </summary> | |
public class IteratorResult | |
{ | |
private static readonly IteratorResult _Continue = new IteratorResult(ResultType.Continue); | |
public static IteratorResult Continue() => _Continue; | |
public static IteratorResult<T> Continue<T>() => new IteratorResult<T>(Continue()); | |
private static readonly IteratorResult _Completed = new IteratorResult(ResultType.Completed); | |
public static IteratorResult Completed() => _Completed; | |
public static IteratorResult<T> Completed<T>() => new IteratorResult<T>(Completed()); | |
public static readonly IteratorResult _Canceled = new IteratorResult(ResultType.Canceled); | |
public static IteratorResult Canceled() => _Canceled; | |
public static IteratorResult<T> Canceled<T>() => new IteratorResult<T>(Canceled()); | |
public static IteratorResult Nest(IEnumerator<IteratorResult> next) => new IteratorResult(ResultType.Nest, next); | |
public static IteratorResult<T> Nest<T>(IEnumerator<IteratorResult> next) => new IteratorResult<T>(Nest(next)); | |
public static IteratorResult WaitForSeconds(double second) => Nest(Iterator.WaitForSeconds(second)); | |
public static IteratorResult<T> WaitForSeconds<T>(double second) => Nest<T>(Iterator.WaitForSeconds(second)); | |
public static IteratorResult WaitWhile(System.Func<bool> function) => Nest(Iterator.WaitWhile(function)); | |
public static IteratorResult<T> WaitWhile<T>(System.Func<bool> function) => Nest<T>(Iterator.WaitWhile(function)); | |
public static IteratorResult WaitUntil(System.Func<bool> function) => Nest(Iterator.WaitUntil(function)); | |
public static IteratorResult<T> WaitUntil<T>(System.Func<bool> function) => Nest<T>(Iterator.WaitUntil(function)); | |
public static IteratorResult<T> Return<T>(T value) => new IteratorResult<T>(value); | |
public ResultType Type { get; } | |
public IEnumerator<IteratorResult> NextIterator { get; } | |
public IteratorResult(ResultType type, IEnumerator<IteratorResult> next = null) | |
{ | |
if (type == ResultType.Nest && next == null) | |
throw new System.Exception("Nestになってるのにnextがnullです"); | |
Type = type; | |
NextIterator = next; | |
} | |
public enum ResultType | |
{ | |
Continue, Completed, Canceled, Nest, Return | |
} | |
} | |
/// <summary> | |
/// Tという型の値を返す | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class IteratorResult<T> : IteratorResult | |
{ | |
public T Value { get; } | |
public IteratorResult(IteratorResult result) : base(result.Type, result.NextIterator) { } | |
public IteratorResult(T value) | |
: base(ResultType.Return) | |
{ | |
Value = value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment