提交 29b81cc2 编写于 作者: T tanghai

简化ETTask

上级 88642480
......@@ -20,18 +20,9 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Libs\**" />
<Compile Include="..\..\Unity\Assets\Model\Base\Async\AsyncUnit.cs">
<Link>Base\Async\AsyncUnit.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\CancellationTokenExtensions.cs">
<Link>Base\Async\CancellationTokenExtensions.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\ETAsyncTaskMethodBuilder.cs">
<Link>Base\Async\ETAsyncTaskMethodBuilder.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\ETAsyncTaskVoidMethodBuilder.cs">
<Link>Base\Async\ETAsyncTaskVoidMethodBuilder.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTask.cs">
<Link>Base\Async\ETTask.cs</Link>
</Compile>
......@@ -41,15 +32,9 @@
<Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTaskFactory.cs">
<Link>Base\Async\ETTaskFactory.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\ETTaskVoid.cs">
<Link>Base\Async\ETTaskVoid.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\IAwaiter.cs">
<Link>Base\Async\IAwaiter.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\LazyPromise.cs">
<Link>Base\Async\LazyPromise.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Base\Async\MoveNextRunner.cs">
<Link>Base\Async\MoveNextRunner.cs</Link>
</Compile>
......
using System;
namespace ETModel
{
public struct AsyncUnit: IEquatable<AsyncUnit>
{
public static readonly AsyncUnit Default = new AsyncUnit();
public override int GetHashCode()
{
return 0;
}
public bool Equals(AsyncUnit other)
{
return true;
}
public override string ToString()
{
return "()";
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 2826256cdc0af9e4b832ff24d04b58da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Threading;
namespace ETModel
{
public static class CancellationTokenExtensions
{
private static readonly Action<object> cancellationTokenCallback = Callback;
public static (ETTask, CancellationTokenRegistration) ToETTask(this CancellationToken cts)
{
if (cts.IsCancellationRequested)
{
return (ETTask.FromCanceled(cts), default);
}
var promise = new ETTaskCompletionSource<AsyncUnit>();
return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
private static void Callback(object state)
{
var promise = (ETTaskCompletionSource<AsyncUnit>) state;
promise.TrySetResult(AsyncUnit.Default);
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
{
bool restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken,
Action<object> callback, object state)
{
bool restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, state, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 1ede9bbc65a28b646b1d1313258bb658
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Security;
......@@ -7,7 +6,7 @@ namespace ETModel
{
public struct ETAsyncTaskMethodBuilder
{
private ETTaskCompletionSource promise;
private ETTaskCompletionSource tcs;
private Action moveNext;
// 1. Static Create method.
......@@ -24,9 +23,9 @@ namespace ETModel
{
get
{
if (promise != null)
if (this.tcs != null)
{
return promise.Task;
return this.tcs.Task;
}
if (moveNext == null)
......@@ -34,8 +33,8 @@ namespace ETModel
return ETTask.CompletedTask;
}
this.promise = new ETTaskCompletionSource();
return this.promise.Task;
this.tcs = new ETTaskCompletionSource();
return this.tcs.Task;
}
}
......@@ -43,18 +42,18 @@ namespace ETModel
//[DebuggerHidden]
public void SetException(Exception exception)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource();
this.tcs = new ETTaskCompletionSource();
}
if (exception is OperationCanceledException ex)
{
promise.TrySetCanceled(ex);
this.tcs.TrySetCanceled(ex);
}
else
{
promise.TrySetException(exception);
this.tcs.TrySetException(exception);
}
}
......@@ -67,12 +66,12 @@ namespace ETModel
}
else
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource();
this.tcs = new ETTaskCompletionSource();
}
promise.TrySetResult();
this.tcs.TrySetResult();
}
}
......@@ -84,9 +83,9 @@ namespace ETModel
{
if (moveNext == null)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource(); // built future.
this.tcs = new ETTaskCompletionSource(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
......@@ -106,9 +105,9 @@ namespace ETModel
{
if (moveNext == null)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource(); // built future.
this.tcs = new ETTaskCompletionSource(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
......@@ -121,8 +120,7 @@ namespace ETModel
// 7. Start
//[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
......@@ -137,7 +135,7 @@ namespace ETModel
public struct ETAsyncTaskMethodBuilder<T>
{
private T result;
private ETTaskCompletionSource<T> promise;
private ETTaskCompletionSource<T> tcs;
private Action moveNext;
// 1. Static Create method.
......@@ -154,9 +152,9 @@ namespace ETModel
{
get
{
if (promise != null)
if (this.tcs != null)
{
return new ETTask<T>(promise);
return new ETTask<T>(this.tcs);
}
if (moveNext == null)
......@@ -164,8 +162,8 @@ namespace ETModel
return new ETTask<T>(result);
}
this.promise = new ETTaskCompletionSource<T>();
return new ETTask<T>(this.promise);
this.tcs = new ETTaskCompletionSource<T>();
return this.tcs.Task;
}
}
......@@ -173,37 +171,37 @@ namespace ETModel
//[DebuggerHidden]
public void SetException(Exception exception)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource<T>();
this.tcs = new ETTaskCompletionSource<T>();
}
if (exception is OperationCanceledException ex)
{
promise.TrySetCanceled(ex);
this.tcs.TrySetCanceled(ex);
}
else
{
promise.TrySetException(exception);
this.tcs.TrySetException(exception);
}
}
// 4. SetResult
//[DebuggerHidden]
public void SetResult(T result)
public void SetResult(T ret)
{
if (moveNext == null)
{
this.result = result;
this.result = ret;
}
else
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource<T>();
this.tcs = new ETTaskCompletionSource<T>();
}
promise.TrySetResult(result);
this.tcs.TrySetResult(ret);
}
}
......@@ -215,9 +213,9 @@ namespace ETModel
{
if (moveNext == null)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource<T>(); // built future.
this.tcs = new ETTaskCompletionSource<T>(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
......@@ -237,9 +235,9 @@ namespace ETModel
{
if (moveNext == null)
{
if (promise == null)
if (this.tcs == null)
{
promise = new ETTaskCompletionSource<T>(); // built future.
this.tcs = new ETTaskCompletionSource<T>(); // built future.
}
var runner = new MoveNextRunner<TStateMachine>();
......@@ -252,8 +250,7 @@ namespace ETModel
// 7. Start
//[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
......
using System;
using System.Runtime.CompilerServices;
using System.Security;
namespace ETModel
{
public struct ETAsyncTaskVoidMethodBuilder
{
private Action moveNext;
// 1. Static Create method.
//[DebuggerHidden]
public static ETAsyncTaskVoidMethodBuilder Create()
{
ETAsyncTaskVoidMethodBuilder builder = new ETAsyncTaskVoidMethodBuilder();
return builder;
}
// 2. TaskLike Task property(void)
public ETTaskVoid Task => default;
// 3. SetException
//[DebuggerHidden]
public void SetException(Exception exception)
{
}
// 4. SetResult
//[DebuggerHidden]
public void SetResult()
{
// do nothing
}
// 5. AwaitOnCompleted
//[DebuggerHidden]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.OnCompleted(moveNext);
}
// 6. AwaitUnsafeOnCompleted
//[DebuggerHidden]
[SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (moveNext == null)
{
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
}
awaiter.UnsafeOnCompleted(moveNext);
}
// 7. Start
//[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
//[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 390ef7e019b703f46900fcc7dde998f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -10,8 +10,6 @@ namespace ETModel
[AsyncMethodBuilder(typeof (ETAsyncTaskMethodBuilder))]
public partial struct ETTask: IEquatable<ETTask>
{
private static readonly ETTask<AsyncUnit> DefaultAsyncUnitTask = new ETTask<AsyncUnit>(AsyncUnit.Default);
private readonly IAwaiter awaiter;
//[DebuggerHidden]
......@@ -20,12 +18,6 @@ namespace ETModel
this.awaiter = awaiter;
}
//[DebuggerHidden]
public ETTask(Func<ETTask> factory)
{
this.awaiter = new LazyPromise(factory);
}
//[DebuggerHidden]
public AwaiterStatus Status => awaiter?.Status ?? AwaiterStatus.Succeeded;
......@@ -47,23 +39,6 @@ namespace ETModel
return new Awaiter(this);
}
/// <summary>
/// returns (bool IsCanceled) instead of throws OperationCanceledException.
/// </summary>
public ETTask<bool> SuppressCancellationThrow()
{
AwaiterStatus status = Status;
switch (status)
{
case AwaiterStatus.Succeeded:
return CompletedTasks.False;
case AwaiterStatus.Canceled:
return CompletedTasks.True;
default:
return new ETTask<bool>(new IsCanceledAwaiter(this.awaiter));
}
}
public bool Equals(ETTask other)
{
if (this.awaiter == null && other.awaiter == null)
......@@ -96,58 +71,6 @@ namespace ETModel
: "(" + this.awaiter.Status + ")";
}
public static implicit operator ETTask<AsyncUnit>(ETTask task)
{
if (task.awaiter == null)
{
return DefaultAsyncUnitTask;
}
if (task.awaiter.IsCompleted)
{
return DefaultAsyncUnitTask;
}
// UniTask<T> -> UniTask is free but UniTask -> UniTask<T> requires wrapping cost.
return new ETTask<AsyncUnit>(new AsyncUnitAwaiter(task.awaiter));
}
private class AsyncUnitAwaiter: IAwaiter<AsyncUnit>
{
private readonly IAwaiter awaiter;
public AsyncUnitAwaiter(IAwaiter awaiter)
{
this.awaiter = awaiter;
}
public bool IsCompleted => awaiter.IsCompleted;
public AwaiterStatus Status => awaiter.Status;
public AsyncUnit GetResult()
{
awaiter.GetResult();
return AsyncUnit.Default;
}
public void OnCompleted(Action continuation)
{
awaiter.OnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
awaiter.UnsafeOnCompleted(continuation);
}
void IAwaiter.GetResult()
{
awaiter.GetResult();
}
}
private class IsCanceledAwaiter: IAwaiter<bool>
{
private readonly IAwaiter awaiter;
......@@ -261,13 +184,6 @@ namespace ETModel
this.awaiter = awaiter;
}
//[DebuggerHidden]
public ETTask(Func<ETTask<T>> factory)
{
this.result = default;
this.awaiter = new LazyPromise<T>(factory);
}
//[DebuggerHidden]
public AwaiterStatus Status => awaiter?.Status ?? AwaiterStatus.Succeeded;
......@@ -294,25 +210,6 @@ namespace ETModel
return new Awaiter(this);
}
/// <summary>
/// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException.
/// </summary>
public ETTask<(bool IsCanceled, T Result)> SuppressCancellationThrow()
{
var status = Status;
if (status == AwaiterStatus.Succeeded)
{
return new ETTask<(bool, T)>((false, Result));
}
if (status == AwaiterStatus.Canceled)
{
return new ETTask<(bool, T)>((true, default));
}
return new ETTask<(bool, T)>(new IsCanceledAwaiter(awaiter));
}
public bool Equals(ETTask<T> other)
{
if (this.awaiter == null && other.awaiter == null)
......@@ -360,45 +257,6 @@ namespace ETModel
return new ETTask();
}
private class IsCanceledAwaiter: IAwaiter<(bool, T)>
{
private readonly IAwaiter<T> awaiter;
public IsCanceledAwaiter(IAwaiter<T> awaiter)
{
this.awaiter = awaiter;
}
public bool IsCompleted => awaiter.IsCompleted;
public AwaiterStatus Status => awaiter.Status;
public (bool, T) GetResult()
{
if (awaiter.Status == AwaiterStatus.Canceled)
{
return (true, default);
}
return (false, awaiter.GetResult());
}
public void OnCompleted(Action continuation)
{
awaiter.OnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
awaiter.UnsafeOnCompleted(continuation);
}
void IAwaiter.GetResult()
{
awaiter.GetResult();
}
}
public struct Awaiter: IAwaiter<T>
{
private readonly ETTask<T> task;
......
......@@ -4,30 +4,6 @@ using System.Runtime.ExceptionServices;
namespace ETModel
{
internal class ExceptionHolder
{
private readonly ExceptionDispatchInfo exception;
private bool calledGet;
public ExceptionHolder(ExceptionDispatchInfo exception)
{
this.exception = exception;
}
public ExceptionDispatchInfo GetException()
{
if (calledGet)
{
return this.exception;
}
this.calledGet = true;
GC.SuppressFinalize(this);
return exception;
}
}
public class ETTaskCompletionSource: IAwaiter
{
// State(= AwaiterStatus)
......@@ -37,7 +13,7 @@ namespace ETModel
private const int Canceled = 3;
private int state;
private ExceptionHolder exception;
private ExceptionDispatchInfo exception;
private Action continuation; // action or list
AwaiterStatus IAwaiter.Status => (AwaiterStatus) state;
......@@ -53,15 +29,13 @@ namespace ETModel
case Succeeded:
return;
case Faulted:
this.exception.GetException().Throw();
this.exception?.Throw();
this.exception = null;
return;
case Canceled:
{
if (this.exception != null)
{
this.exception.GetException().Throw(); // guranteed operation canceled exception.
}
this.exception?.Throw(); // guranteed operation canceled exception.
this.exception = null;
throw new OperationCanceledException();
}
default:
......@@ -127,7 +101,7 @@ namespace ETModel
this.state = Faulted;
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
this.exception = ExceptionDispatchInfo.Capture(e);
this.TryInvokeContinuation();
return true;
......@@ -156,7 +130,7 @@ namespace ETModel
this.state = Canceled;
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
this.exception = ExceptionDispatchInfo.Capture(e);
this.TryInvokeContinuation();
return true;
......@@ -178,13 +152,12 @@ namespace ETModel
private int state;
private T value;
private ExceptionHolder exception;
private ExceptionDispatchInfo exception;
private Action continuation; // action or list
bool IAwaiter.IsCompleted => state != Pending;
public ETTask<T> Task => new ETTask<T>(this);
public ETTask UnitTask => new ETTask(this);
AwaiterStatus IAwaiter.Status => (AwaiterStatus) state;
......@@ -195,15 +168,13 @@ namespace ETModel
case Succeeded:
return this.value;
case Faulted:
this.exception.GetException().Throw();
this.exception?.Throw();
this.exception = null;
return default;
case Canceled:
{
if (this.exception != null)
{
this.exception.GetException().Throw(); // guranteed operation canceled exception.
}
this.exception?.Throw(); // guranteed operation canceled exception.
this.exception = null;
throw new OperationCanceledException();
}
default:
......@@ -270,7 +241,7 @@ namespace ETModel
this.state = Faulted;
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
this.exception = ExceptionDispatchInfo.Capture(e);
this.TryInvokeContinuation();
return true;
......@@ -299,7 +270,7 @@ namespace ETModel
this.state = Canceled;
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(e));
this.exception = ExceptionDispatchInfo.Capture(e);
this.TryInvokeContinuation();
return true;
......
......@@ -5,27 +5,20 @@ namespace ETModel
{
public partial struct ETTask
{
private static readonly ETTask CanceledTask = new Func<ETTask>(() =>
{
var promise = new ETTaskCompletionSource<AsyncUnit>();
promise.TrySetCanceled();
return new ETTask(promise);
})();
public static ETTask CompletedTask => new ETTask();
public static ETTask FromException(Exception ex)
{
var promise = new ETTaskCompletionSource<AsyncUnit>();
promise.TrySetException(ex);
return new ETTask(promise);
ETTaskCompletionSource tcs = new ETTaskCompletionSource();
tcs.TrySetException(ex);
return tcs.Task;
}
public static ETTask<T> FromException<T>(Exception ex)
{
var promise = new ETTaskCompletionSource<T>();
promise.TrySetException(ex);
return new ETTask<T>(promise);
var tcs = new ETTaskCompletionSource<T>();
tcs.TrySetException(ex);
return tcs.Task;
}
public static ETTask<T> FromResult<T>(T value)
......@@ -35,7 +28,7 @@ namespace ETModel
public static ETTask FromCanceled()
{
return CanceledTask;
return CanceledETTaskCache.Task;
}
public static ETTask<T> FromCanceled<T>()
......@@ -45,22 +38,28 @@ namespace ETModel
public static ETTask FromCanceled(CancellationToken token)
{
var promise = new ETTaskCompletionSource<AsyncUnit>();
promise.TrySetException(new OperationCanceledException(token));
return new ETTask(promise);
ETTaskCompletionSource tcs = new ETTaskCompletionSource();
tcs.TrySetException(new OperationCanceledException(token));
return tcs.Task;
}
public static ETTask<T> FromCanceled<T>(CancellationToken token)
{
var promise = new ETTaskCompletionSource<T>();
promise.TrySetException(new OperationCanceledException(token));
return new ETTask<T>(promise);
var tcs = new ETTaskCompletionSource<T>();
tcs.TrySetException(new OperationCanceledException(token));
return tcs.Task;
}
/// <summary>shorthand of new UniTask[T](Func[UniTask[T]] factory)</summary>
public static ETTask<T> Lazy<T>(Func<ETTask<T>> factory)
private static class CanceledETTaskCache
{
return new ETTask<T>(factory);
public static readonly ETTask Task;
static CanceledETTaskCache()
{
ETTaskCompletionSource tcs = new ETTaskCompletionSource();
tcs.TrySetCanceled();
Task = tcs.Task;
}
}
private static class CanceledETTaskCache<T>
......@@ -69,9 +68,9 @@ namespace ETModel
static CanceledETTaskCache()
{
var promise = new ETTaskCompletionSource<T>();
promise.TrySetCanceled();
Task = new ETTask<T>(promise);
var taskCompletionSource = new ETTaskCompletionSource<T>();
taskCompletionSource.TrySetCanceled();
Task = taskCompletionSource.Task;
}
}
}
......
using System;
using System.Runtime.CompilerServices;
namespace ETModel
{
[AsyncMethodBuilder(typeof (ETAsyncTaskVoidMethodBuilder))]
public struct ETTaskVoid
{
public void Forget()
{
}
//[DebuggerHidden]
public Awaiter GetAwaiter()
{
return new Awaiter();
}
public struct Awaiter: ICriticalNotifyCompletion
{
//[DebuggerHidden]
public bool IsCompleted => true;
//[DebuggerHidden]
public void GetResult()
{
throw new Exception("ETTask can't await, always fire-and-forget. use Forget instead of await.");
}
//[DebuggerHidden]
public void OnCompleted(Action continuation)
{
}
//[DebuggerHidden]
public void UnsafeOnCompleted(Action continuation)
{
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 9157caacd834b5848b11553a6ea73494
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Threading;
namespace ETModel
{
internal sealed class LazyPromise: IAwaiter
{
private Func<ETTask> factory;
private ETTask value;
public LazyPromise(Func<ETTask> factory)
{
this.factory = factory;
}
private void Create()
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
value = f();
}
}
public bool IsCompleted
{
get
{
Create();
return value.IsCompleted;
}
}
public AwaiterStatus Status
{
get
{
Create();
return value.Status;
}
}
public void GetResult()
{
Create();
value.GetResult();
}
void IAwaiter.GetResult()
{
GetResult();
}
public void UnsafeOnCompleted(Action continuation)
{
Create();
value.GetAwaiter().UnsafeOnCompleted(continuation);
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
}
internal sealed class LazyPromise<T>: IAwaiter<T>
{
private Func<ETTask<T>> factory;
private ETTask<T> value;
public LazyPromise(Func<ETTask<T>> factory)
{
this.factory = factory;
}
private void Create()
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
value = f();
}
}
public bool IsCompleted
{
get
{
Create();
return value.IsCompleted;
}
}
public AwaiterStatus Status
{
get
{
Create();
return value.Status;
}
}
public T GetResult()
{
Create();
return value.Result;
}
void IAwaiter.GetResult()
{
GetResult();
}
public void UnsafeOnCompleted(Action continuation)
{
Create();
value.GetAwaiter().UnsafeOnCompleted(continuation);
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: bf276347e994763428d1a563259218f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace ETModel
{
[ObjectSystem]
public class WwwAsyncUpdateSystem : UpdateSystem<WWWAsync>
{
public override void Update(WWWAsync self)
{
self.Update();
}
}
public class WWWAsync: Entity
{
public WWW www;
public bool isCancel;
public ETTaskCompletionSource<bool> tcs;
public float Progress
{
get
{
if (this.www == null)
{
return 0;
}
return this.www.progress;
}
}
public int ByteDownloaded
{
get
{
if (this.www == null)
{
return 0;
}
return this.www.bytesDownloaded;
}
}
public void Update()
{
if (this.isCancel)
{
this.tcs.SetResult(false);
return;
}
if (!this.www.isDone)
{
return;
}
if (!string.IsNullOrEmpty(this.www.error))
{
this.tcs.SetException(new Exception($"WWWAsync error: {this.www.error}"));
return;
}
var t = this.tcs;
this.tcs = null;
t?.SetResult(true);
}
public ETTask<bool> LoadFromCacheOrDownload(string url, Hash128 hash)
{
url = url.Replace(" ", "%20");
this.www = WWW.LoadFromCacheOrDownload(url, hash, 0);
this.tcs = new ETTaskCompletionSource<bool>();
return this.tcs.Task;
}
public ETTask<bool> LoadFromCacheOrDownload(string url, Hash128 hash, CancellationToken cancellationToken)
{
url = url.Replace(" ", "%20");
this.www = WWW.LoadFromCacheOrDownload(url, hash, 0);
this.tcs = new ETTaskCompletionSource<bool>();
cancellationToken.Register(() => { this.isCancel = true; });
return this.tcs.Task;
}
public ETTask<bool> DownloadAsync(string url)
{
url = url.Replace(" ", "%20");
this.www = new WWW(url);
this.tcs = new ETTaskCompletionSource<bool>();
return this.tcs.Task;
}
public ETTask<bool> DownloadAsync(string url, CancellationToken cancellationToken)
{
url = url.Replace(" ", "%20");
this.www = new WWW(url);
this.tcs = new ETTaskCompletionSource<bool>();
cancellationToken.Register(() => { this.isCancel = true; });
return this.tcs.Task;
}
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
base.Dispose();
www?.Dispose();
this.www = null;
this.tcs = null;
}
}
}
fileFormatVersion: 2
guid: 4d789ae4ba23a73469b228352499a1d0
timeCreated: 1498117617
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -55,16 +55,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\Model\Base\Async\AsyncMethodBuilderAttribute.cs" />
<Compile Include="Assets\Model\Base\Async\AsyncUnit.cs" />
<Compile Include="Assets\Model\Base\Async\CancellationTokenExtensions.cs" />
<Compile Include="Assets\Model\Base\Async\ETAsyncTaskMethodBuilder.cs" />
<Compile Include="Assets\Model\Base\Async\ETAsyncTaskVoidMethodBuilder.cs" />
<Compile Include="Assets\Model\Base\Async\ETTask.cs" />
<Compile Include="Assets\Model\Base\Async\ETTaskCompletionSource.cs" />
<Compile Include="Assets\Model\Base\Async\ETTaskFactory.cs" />
<Compile Include="Assets\Model\Base\Async\ETTaskVoid.cs" />
<Compile Include="Assets\Model\Base\Async\IAwaiter.cs" />
<Compile Include="Assets\Model\Base\Async\LazyPromise.cs" />
<Compile Include="Assets\Model\Base\Async\MoveNextRunner.cs" />
<Compile Include="Assets\Model\Base\DoubleMap.cs" />
<Compile Include="Assets\Model\Base\Event\Env.cs" />
......@@ -158,7 +153,6 @@
<Compile Include="Assets\Model\Entity\Hotfix.cs" />
<Compile Include="Assets\Model\Entity\Scene.cs" />
<Compile Include="Assets\Model\Entity\UnityWebRequestAsync.cs" />
<Compile Include="Assets\Model\Entity\WWWAsync.cs" />
<Compile Include="Assets\Model\Helper\ActionHelper.cs" />
<Compile Include="Assets\Model\Helper\BundleHelper.cs" />
<Compile Include="Assets\Model\Helper\GameObjectHelper.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册