Skip to content

Instantly share code, notes, and snippets.

@ThirdPartyNinjas
Last active September 22, 2022 19:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ThirdPartyNinjas/704b50fae447fbeb48fae2fa7f62ab18 to your computer and use it in GitHub Desktop.
Save ThirdPartyNinjas/704b50fae447fbeb48fae2fa7f62ab18 to your computer and use it in GitHub Desktop.
Simple Coroutines (for XNA/FNA/etc.)
using System.Collections;
using System.Collections.Generic;
namespace Memento
{
public class Coroutine
{
public bool Paused { get; set; }
internal void Reset(IEnumerator routine)
{
routines.Clear();
routines.Push(routine);
Paused = false;
}
internal bool Update()
{
if (!Paused)
{
if (routines.Peek().MoveNext() == false)
{
routines.Pop();
if (routines.Count == 0)
{
return false;
}
}
else if (routines.Peek().Current is IEnumerator)
{
routines.Push((IEnumerator)routines.Peek().Current);
}
}
return true;
}
private Stack<IEnumerator> routines = new Stack<IEnumerator>();
}
}
using System.Collections;
using System.Collections.Generic;
namespace Memento
{
public class CoroutineController
{
public Coroutine StartCoroutine(IEnumerator routine)
{
var coroutine = coroutinePool.Take();
coroutine.Reset(routine);
incomingCoroutines.Add(coroutine);
return coroutine;
}
public void StopCoroutine(Coroutine coroutine)
{
int index = activeCoroutines.FindIndex((c) => c == coroutine);
if (index != -1)
{
coroutinePool.Return(activeCoroutines[index]);
activeCoroutines.RemoveAt(index);
}
}
public void UpdateCoroutines()
{
activeCoroutines.AddRange(incomingCoroutines);
incomingCoroutines.Clear();
for (int i = 0; i < activeCoroutines.Count; i++)
{
if (activeCoroutines[i].Update() == false)
{
coroutinePool.Return(activeCoroutines[i]);
activeCoroutines[i] = null;
}
}
activeCoroutines.RemoveAll((x) => { return x == null; });
}
private List<Coroutine> activeCoroutines = new List<Coroutine>();
private List<Coroutine> incomingCoroutines = new List<Coroutine>();
private ObjectPool<Coroutine> coroutinePool = new ObjectPool<Coroutine>(() => new Coroutine());
}
}
using Memento;
using Microsoft.Xna.Framework;
using System;
using System.Collections;
namespace CoroutineTest
{
public class TestGame : Game
{
public TestGame()
{
graphics = new GraphicsDeviceManager(this)
{
PreferredBackBufferWidth = 1280,
PreferredBackBufferHeight = 720
};
coroutineController = new CoroutineController();
coroutineController.StartCoroutine(PrintEveryTenFrames());
}
protected override void Update(GameTime gameTime)
{
coroutineController.UpdateCoroutines();
}
private IEnumerator PrintEveryTenFrames()
{
int frames = 0;
while (true)
{
frames++;
if (frames >= 10)
{
frames = 0;
Console.WriteLine("Ten Frames");
}
yield return null;
}
}
private GraphicsDeviceManager graphics;
private CoroutineController coroutineController;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment