BatchedCoroutines: Iterar coroutinas una a una
Queréis que vuestras ConcurrentQueues se ejecuten una por una? No problemo, con esta implementación to hard-codeada lo conseguiréis:
Un ejemplo de implementación:
Básicamente, en las dos Queues vamos haciendo Enqueue donde sea necesario (en otro thread).
Cuando todo haya acabado, desde el primer thread, llamamos a que se ejecute lo que acabo de mostrar.
Y en mi caso por ejemplo, esto sirve para mostrar pixel a pixel donde se ha iterado una imagen.
Y lo siguiente que ocurre es que la imagen se rellena con el algoritmo de flood-fill que enseñe el otro día. (Básicamente, para saber si se ha hecho bien)
Nota: Si queréis el código de GetFuncs es este:
Queréis que vuestras ConcurrentQueues se ejecuten una por una? No problemo, con esta implementación to hard-codeada lo conseguiréis:
Código (csharp) [Seleccionar]
using GTAMapper.Extensions.Threading;
using System;
using System.Collections;
using UnityEngine;
namespace GTAMapper.Extensions
{
public static class BatchedCoroutines
{
public static IEnumerator BatchCoroutines(
MonoBehaviour monoBehaviour,
Action finish,
Func<int, bool>[] waitUntil = null,
params Tuple<Action<object>, ConcurrentQueuedCoroutines<object>>[] tuple) // Tuple<Action<T>, ConcurrentQueuedCoroutines<T>> || dynamic
// Fix for: https://stackoverflow.com/questions/15417174/using-the-params-keyword-for-generic-parameters-in-c-sharp
{
int i = 0;
foreach (var val in tuple)
{
if (waitUntil != null && waitUntil[i] != null)
yield return new WaitUntil(() => waitUntil[i](i));
yield return val.Item2.GetCoroutine(monoBehaviour, val.Item1);
++i;
}
finish?.Invoke();
}
}
}
Un ejemplo de implementación:
Código (csharp) [Seleccionar]
protected ConcurrentQueuedCoroutines<object> debuggingCoroutine = new ConcurrentQueuedCoroutines<object>(),
colorCoroutine = new ConcurrentQueuedCoroutines<object>();
namespace GTAMapper.Core {
public class Program : MonoBehaviour {
public void Start() {
StartCoroutine(BatchedCoroutines.BatchCoroutines(
this,
() => areCoroutinesCollected = true,
F.GetFuncs(null, (_ii) => debuggingCoroutine.Queue.Count > 0),
new Tuple<Action<object>, ConcurrentQueuedCoroutines<object>>((obj) =>
{
Tuple<int, Color> tuple = (Tuple<int, Color>)obj;
int i = tuple.Item1,
_x = i % width,
_y = i / width;
UnityEngine.Color actualColor = debugTexture.GetPixel(_x, _y),
mixedColor = UnityEngine.Color.Lerp(actualColor, tuple.Item2, .5f);
if (actualColor != mixedColor)
{
debugTexture.SetPixel(_x, _y, mixedColor);
debugTexture.Apply();
}
}, colorCoroutine),
new Tuple<Action<object>, ConcurrentQueuedCoroutines<object>>((obj) =>
{
Color[] colors = (Color[])obj;
debugTexture.SetPixels32(colors.CastBack().ToArray());
debugTexture.Apply();
}, debuggingCoroutine)));
}
}
}
Básicamente, en las dos Queues vamos haciendo Enqueue donde sea necesario (en otro thread).
Cuando todo haya acabado, desde el primer thread, llamamos a que se ejecute lo que acabo de mostrar.
Y en mi caso por ejemplo, esto sirve para mostrar pixel a pixel donde se ha iterado una imagen.
Y lo siguiente que ocurre es que la imagen se rellena con el algoritmo de flood-fill que enseñe el otro día. (Básicamente, para saber si se ha hecho bien)
Nota: Si queréis el código de GetFuncs es este:
Código (csharp) [Seleccionar]
using System;
public static class F {
public static Func<int, bool>[] GetFuncs(params Func<int, bool>[] waitUntil)
{
return waitUntil;
}
}