Skip to content

Instantly share code, notes, and snippets.

@spi8823
Last active April 27, 2018 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spi8823/906abfd81b8a4d87d35ece6c05642c30 to your computer and use it in GitHub Desktop.
Save spi8823/906abfd81b8a4d87d35ece6c05642c30 to your computer and use it in GitHub Desktop.
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