Created
October 1, 2018 14:18
-
-
Save simonwittber/1a57e8e418d14b404977b0b364482369 to your computer and use it in GitHub Desktop.
Pooled coroutines for Unity.
This file contains hidden or 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; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| public class StopAction : YieldInstruction | |
| { | |
| } | |
| public class GoroutinePool | |
| { | |
| static public int maxFreeListSize = 2; | |
| static Dictionary<System.Type, Queue<Goroutine>> pool = new Dictionary<System.Type, Queue<Goroutine>>(); | |
| static void Clear() | |
| { | |
| pool.Clear(); | |
| } | |
| static public T Take<T>() where T : Goroutine, new() | |
| { | |
| Queue<Goroutine> freeList; | |
| if (pool.TryGetValue(typeof(T), out freeList)) | |
| { | |
| if (freeList.Count > 0) | |
| { | |
| var rc = freeList.Dequeue(); | |
| rc.Reset(); | |
| return (T)rc; | |
| } | |
| } | |
| return new T(); | |
| } | |
| static public void Recycle(Goroutine rc) | |
| { | |
| Queue<Goroutine> freeList; | |
| var type = rc.GetType(); | |
| if (!pool.TryGetValue(type, out freeList)) | |
| { | |
| freeList = new Queue<Goroutine>(); | |
| pool.Add(type, freeList); | |
| } | |
| if (freeList.Count < maxFreeListSize) | |
| { | |
| freeList.Enqueue(rc); | |
| } | |
| } | |
| } | |
| public class Goroutine : IEnumerator, System.IDisposable | |
| { | |
| public static readonly StopAction Stop = new StopAction(); | |
| YieldInstruction current; | |
| bool isDone = false; | |
| bool reset = true; | |
| public object Current | |
| { | |
| get | |
| { | |
| return current; | |
| } | |
| } | |
| public void Dispose() | |
| { | |
| Reset(); | |
| } | |
| protected virtual YieldInstruction OnContinue() | |
| { | |
| return null; | |
| } | |
| protected virtual void OnStart() | |
| { | |
| } | |
| protected virtual void OnFinish() | |
| { | |
| GoroutinePool.Recycle(this); | |
| } | |
| public bool MoveNext() | |
| { | |
| if (isDone) | |
| return false; | |
| if (reset) | |
| { | |
| reset = false; | |
| OnStart(); | |
| } | |
| current = OnContinue(); | |
| if (current is StopAction) | |
| { | |
| OnFinish(); | |
| isDone = true; | |
| return false; | |
| } | |
| return true; | |
| } | |
| public void Reset() | |
| { | |
| if (!isDone) | |
| { | |
| OnFinish(); | |
| } | |
| isDone = false; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requires writing a class for each coroutine, instead of using yield keywords.