Skip to content

Instantly share code, notes, and snippets.

@z3nth10n
Created April 2, 2019 22:49
Show Gist options
  • Save z3nth10n/060ef9a604095d927c6cd278a49b8262 to your computer and use it in GitHub Desktop.
Save z3nth10n/060ef9a604095d927c6cd278a49b8262 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using UnityEngine;
namespace GTAMapper.Extensions.Threading
{
public class ConcurrentQueuedCoroutines<T>
{
private List<Coroutine> coroutines;
private Coroutine coroutine;
private MonoBehaviour Mono;
public ConcurrentQueue<object> Queue { get; private set; }
public Action<T> Action { get; private set; }
public bool Debugging { get; set; }
public float SecondsToWait { get; private set; }
private ConcurrentQueuedCoroutines()
{
}
public ConcurrentQueuedCoroutines(float secondsToWait = -1)
{
Queue = new ConcurrentQueue<object>();
coroutines = new List<Coroutine>();
SecondsToWait = secondsToWait;
}
public Coroutine StartCoroutine(MonoBehaviour monoBehaviour, Action<T> action)
{
coroutines.Add(monoBehaviour.StartCoroutine(InternalCoroutine()));
Mono = monoBehaviour;
Action = action;
return coroutine;
}
public Coroutine StartCoroutineOnce(MonoBehaviour monoBehaviour, Action<T> action)
{
if (Debugging)
Debug.Log("Starting dequeing!");
if (coroutine == null)
{
coroutine = monoBehaviour.StartCoroutine(InternalCoroutine());
Mono = monoBehaviour;
Action = action;
}
return coroutine;
}
public void StopCoroutine()
{
if (coroutine != null && Mono != null)
Mono.StopCoroutine(coroutine);
}
public void StopAllCoroutines()
{
if (Mono != null && coroutines != null && coroutines.Count > 0)
coroutines.ForEach((c) => Mono.StopCoroutine(c));
}
public IEnumerator GetCoroutine(MonoBehaviour mono, Action<T> action)
{
Mono = mono;
Action = action;
return InternalCoroutine();
}
private IEnumerator InternalCoroutine()
{
if (Debugging)
Debug.Log($"Starting dequeing {Queue.Count} values!");
while (Queue.Count > 0)
{
object value = null;
bool dequeued = Queue.TryDequeue(out value);
if (!dequeued)
{
if (SecondsToWait == -1)
yield return new WaitForEndOfFrame();
else
yield return new WaitForSeconds(SecondsToWait);
continue;
}
Action?.Invoke((T)value);
if (SecondsToWait == -1)
yield return new WaitForEndOfFrame();
else
yield return new WaitForSeconds(SecondsToWait);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment