ToAsyncLazy
parent
b8d1a09224
commit
75f0bd26e7
|
@ -6,6 +6,62 @@ using System.Threading;
|
|||
|
||||
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>
|
||||
{
|
||||
Func<UniTask<T>> valueFactory;
|
||||
|
|
|
@ -93,6 +93,11 @@ namespace UniRx.Async
|
|||
return factory();
|
||||
}
|
||||
|
||||
public static AsyncLazy Lazy(Func<UniTask> factory)
|
||||
{
|
||||
return new AsyncLazy(factory);
|
||||
}
|
||||
|
||||
public static AsyncLazy<T> Lazy<T>(Func<UniTask<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)
|
||||
{
|
||||
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
||||
|
|
Loading…
Reference in New Issue