ToAsyncLazy
parent
b8d1a09224
commit
75f0bd26e7
|
@ -6,6 +6,62 @@ using System.Threading;
|
||||||
|
|
||||||
namespace UniRx.Async
|
namespace UniRx.Async
|
||||||
{
|
{
|
||||||
|
public class AsyncLazy
|
||||||
|
{
|
||||||
|
Func<UniTask> valueFactory;
|
||||||
|
UniTask target;
|
||||||
|
object syncLock;
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
|
public AsyncLazy(Func<UniTask> valueFactory)
|
||||||
|
{
|
||||||
|
this.valueFactory = valueFactory;
|
||||||
|
this.target = default;
|
||||||
|
this.syncLock = new object();
|
||||||
|
this.initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal AsyncLazy(UniTask value)
|
||||||
|
{
|
||||||
|
this.valueFactory = null;
|
||||||
|
this.target = value;
|
||||||
|
this.syncLock = null;
|
||||||
|
this.initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTask Task => EnsureInitialized();
|
||||||
|
|
||||||
|
public UniTask.Awaiter GetAwaiter() => EnsureInitialized().GetAwaiter();
|
||||||
|
|
||||||
|
UniTask EnsureInitialized()
|
||||||
|
{
|
||||||
|
if (Volatile.Read(ref initialized))
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EnsureInitializedCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
UniTask EnsureInitializedCore()
|
||||||
|
{
|
||||||
|
lock (syncLock)
|
||||||
|
{
|
||||||
|
if (!Volatile.Read(ref initialized))
|
||||||
|
{
|
||||||
|
var f = Interlocked.Exchange(ref valueFactory, null);
|
||||||
|
if (f != null)
|
||||||
|
{
|
||||||
|
target = f().Preserve(); // with preserve(allow multiple await).
|
||||||
|
Volatile.Write(ref initialized, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class AsyncLazy<T>
|
public class AsyncLazy<T>
|
||||||
{
|
{
|
||||||
Func<UniTask<T>> valueFactory;
|
Func<UniTask<T>> valueFactory;
|
||||||
|
|
|
@ -93,6 +93,11 @@ namespace UniRx.Async
|
||||||
return factory();
|
return factory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AsyncLazy Lazy(Func<UniTask> factory)
|
||||||
|
{
|
||||||
|
return new AsyncLazy(factory);
|
||||||
|
}
|
||||||
|
|
||||||
public static AsyncLazy<T> Lazy<T>(Func<UniTask<T>> factory)
|
public static AsyncLazy<T> Lazy<T>(Func<UniTask<T>> factory)
|
||||||
{
|
{
|
||||||
return new AsyncLazy<T>(factory);
|
return new AsyncLazy<T>(factory);
|
||||||
|
|
|
@ -180,6 +180,16 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AsyncLazy ToAsyncLazy(this UniTask task)
|
||||||
|
{
|
||||||
|
return new AsyncLazy(task.Preserve()); // require Preserve
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncLazy<T> ToAsyncLazy<T>(this UniTask<T> task)
|
||||||
|
{
|
||||||
|
return new AsyncLazy<T>(task.Preserve()); // require Preserve
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerator ToCoroutine<T>(this UniTask<T> task, Action<T> resultHandler = null, Action<Exception> exceptionHandler = null)
|
public static IEnumerator ToCoroutine<T>(this UniTask<T> task, Action<T> resultHandler = null, Action<Exception> exceptionHandler = null)
|
||||||
{
|
{
|
||||||
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
||||||
|
|
Loading…
Reference in New Issue