Move UniTask estension to samples
parent
f53c4300e8
commit
665a6afd74
|
@ -1,145 +0,0 @@
|
||||||
using System;
|
|
||||||
using YooAsset;
|
|
||||||
using static Cysharp.Threading.Tasks.Internal.Error;
|
|
||||||
|
|
||||||
namespace Cysharp.Threading.Tasks
|
|
||||||
{
|
|
||||||
public static class AsyncOperationBaseExtensions
|
|
||||||
{
|
|
||||||
public static UniTask.Awaiter GetAwaiter(this AsyncOperationBase handle)
|
|
||||||
{
|
|
||||||
return ToUniTask(handle).GetAwaiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask ToUniTask(this AsyncOperationBase handle,
|
|
||||||
IProgress<float> progress = null,
|
|
||||||
PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
|
||||||
{
|
|
||||||
ThrowArgumentNullException(handle, nameof(handle));
|
|
||||||
|
|
||||||
if(handle.IsDone)
|
|
||||||
{
|
|
||||||
return UniTask.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UniTask(
|
|
||||||
AsyncOperationBaserConfiguredSource.Create(
|
|
||||||
handle,
|
|
||||||
timing,
|
|
||||||
progress,
|
|
||||||
out var token
|
|
||||||
),
|
|
||||||
token
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class AsyncOperationBaserConfiguredSource : IUniTaskSource,
|
|
||||||
IPlayerLoopItem,
|
|
||||||
ITaskPoolNode<AsyncOperationBaserConfiguredSource>
|
|
||||||
{
|
|
||||||
private static TaskPool<AsyncOperationBaserConfiguredSource> pool;
|
|
||||||
|
|
||||||
private AsyncOperationBaserConfiguredSource nextNode;
|
|
||||||
|
|
||||||
public ref AsyncOperationBaserConfiguredSource NextNode => ref nextNode;
|
|
||||||
|
|
||||||
static AsyncOperationBaserConfiguredSource()
|
|
||||||
{
|
|
||||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationBaserConfiguredSource), () => pool.Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Action<AsyncOperationBase> continuationAction;
|
|
||||||
private AsyncOperationBase handle;
|
|
||||||
private IProgress<float> progress;
|
|
||||||
private bool completed;
|
|
||||||
private UniTaskCompletionSourceCore<AsyncUnit> core;
|
|
||||||
|
|
||||||
AsyncOperationBaserConfiguredSource() { continuationAction = Continuation; }
|
|
||||||
|
|
||||||
public static IUniTaskSource Create(AsyncOperationBase handle,
|
|
||||||
PlayerLoopTiming timing,
|
|
||||||
IProgress<float> progress,
|
|
||||||
out short token)
|
|
||||||
{
|
|
||||||
if(!pool.TryPop(out var result))
|
|
||||||
{
|
|
||||||
result = new AsyncOperationBaserConfiguredSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
result.handle = handle;
|
|
||||||
result.progress = progress;
|
|
||||||
result.completed = false;
|
|
||||||
TaskTracker.TrackActiveTask(result, 3);
|
|
||||||
|
|
||||||
if(progress != null)
|
|
||||||
{
|
|
||||||
PlayerLoopHelper.AddAction(timing, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle.Completed += result.continuationAction;
|
|
||||||
|
|
||||||
token = result.core.Version;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Continuation(AsyncOperationBase _)
|
|
||||||
{
|
|
||||||
handle.Completed -= continuationAction;
|
|
||||||
|
|
||||||
if(completed)
|
|
||||||
{
|
|
||||||
TryReturn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
completed = true;
|
|
||||||
if(handle.Status == EOperationStatus.Failed)
|
|
||||||
{
|
|
||||||
core.TrySetException(new Exception(handle.Error));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
core.TrySetResult(AsyncUnit.Default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryReturn()
|
|
||||||
{
|
|
||||||
TaskTracker.RemoveTracking(this);
|
|
||||||
core.Reset();
|
|
||||||
handle = default;
|
|
||||||
progress = default;
|
|
||||||
return pool.TryPush(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniTaskStatus GetStatus(short token) => core.GetStatus(token);
|
|
||||||
|
|
||||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
|
||||||
{
|
|
||||||
core.OnCompleted(continuation, state, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetResult(short token) { core.GetResult(token); }
|
|
||||||
|
|
||||||
public UniTaskStatus UnsafeGetStatus() => core.UnsafeGetStatus();
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if(completed)
|
|
||||||
{
|
|
||||||
TryReturn();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!handle.IsDone)
|
|
||||||
{
|
|
||||||
progress?.Report(handle.Progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 2cceff5ec1f84bd0a6a9b4ed7719527c
|
|
||||||
timeCreated: 1651978895
|
|
|
@ -1,215 +0,0 @@
|
||||||
#if UNITY_2020_1_OR_NEWER && ! UNITY_2021
|
|
||||||
#define UNITY_2020_BUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using YooAsset;
|
|
||||||
using static Cysharp.Threading.Tasks.Internal.Error;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Cysharp.Threading.Tasks
|
|
||||||
{
|
|
||||||
public static class OperationHandleBaseExtensions
|
|
||||||
{
|
|
||||||
public static UniTask.Awaiter GetAwaiter(this OperationHandleBase handle)
|
|
||||||
{
|
|
||||||
return ToUniTask(handle).GetAwaiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask ToUniTask(this OperationHandleBase handle,
|
|
||||||
IProgress<float> progress = null,
|
|
||||||
PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
|
||||||
{
|
|
||||||
ThrowArgumentNullException(handle, nameof(handle));
|
|
||||||
|
|
||||||
if(!handle.IsValid)
|
|
||||||
{
|
|
||||||
return UniTask.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UniTask(
|
|
||||||
OperationHandleBaserConfiguredSource.Create(
|
|
||||||
handle,
|
|
||||||
timing,
|
|
||||||
progress,
|
|
||||||
out var token
|
|
||||||
),
|
|
||||||
token
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class OperationHandleBaserConfiguredSource : IUniTaskSource,
|
|
||||||
IPlayerLoopItem,
|
|
||||||
ITaskPoolNode<OperationHandleBaserConfiguredSource>
|
|
||||||
{
|
|
||||||
private static TaskPool<OperationHandleBaserConfiguredSource> pool;
|
|
||||||
|
|
||||||
private OperationHandleBaserConfiguredSource nextNode;
|
|
||||||
|
|
||||||
public ref OperationHandleBaserConfiguredSource NextNode => ref nextNode;
|
|
||||||
|
|
||||||
static OperationHandleBaserConfiguredSource()
|
|
||||||
{
|
|
||||||
TaskPool.RegisterSizeGetter(typeof(OperationHandleBaserConfiguredSource), () => pool.Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Action<OperationHandleBase> continuationAction;
|
|
||||||
private OperationHandleBase handle;
|
|
||||||
private IProgress<float> progress;
|
|
||||||
private bool completed;
|
|
||||||
private UniTaskCompletionSourceCore<AsyncUnit> core;
|
|
||||||
|
|
||||||
OperationHandleBaserConfiguredSource() { continuationAction = Continuation; }
|
|
||||||
|
|
||||||
public static IUniTaskSource Create(OperationHandleBase handle,
|
|
||||||
PlayerLoopTiming timing,
|
|
||||||
IProgress<float> progress,
|
|
||||||
out short token)
|
|
||||||
{
|
|
||||||
if(!pool.TryPop(out var result))
|
|
||||||
{
|
|
||||||
result = new OperationHandleBaserConfiguredSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
result.handle = handle;
|
|
||||||
result.progress = progress;
|
|
||||||
result.completed = false;
|
|
||||||
TaskTracker.TrackActiveTask(result, 3);
|
|
||||||
|
|
||||||
if(progress != null)
|
|
||||||
{
|
|
||||||
PlayerLoopHelper.AddAction(timing, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUG 在 Unity 2020.3.36 版本测试中, IL2Cpp 会报 如下错误
|
|
||||||
// BUG ArgumentException: Incompatible Delegate Types. First is System.Action`1[[YooAsset.AssetOperationHandle, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]] second is System.Action`1[[YooAsset.OperationHandleBase, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
|
|
||||||
// BUG 也可能报的是 Action '1' Action '1' 的 InvalidCastException
|
|
||||||
// BUG 此处不得不这么修改, 如果后续 Unity 修复了这个问题, 可以恢复之前的写法
|
|
||||||
#if UNITY_2020_BUG
|
|
||||||
switch(handle)
|
|
||||||
{
|
|
||||||
case AssetOperationHandle asset_handle:
|
|
||||||
asset_handle.Completed += result.AssetContinuation;
|
|
||||||
break;
|
|
||||||
case SceneOperationHandle scene_handle:
|
|
||||||
scene_handle.Completed += result.SceneContinuation;
|
|
||||||
break;
|
|
||||||
case SubAssetsOperationHandle sub_asset_handle:
|
|
||||||
sub_asset_handle.Completed += result.SubContinuation;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
switch(handle)
|
|
||||||
{
|
|
||||||
case AssetOperationHandle asset_handle:
|
|
||||||
asset_handle.Completed += result.continuationAction;
|
|
||||||
break;
|
|
||||||
case SceneOperationHandle scene_handle:
|
|
||||||
scene_handle.Completed += result.continuationAction;
|
|
||||||
break;
|
|
||||||
case SubAssetsOperationHandle sub_asset_handle:
|
|
||||||
sub_asset_handle.Completed += result.continuationAction;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
token = result.core.Version;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#if UNITY_2020_BUG
|
|
||||||
private void AssetContinuation(AssetOperationHandle handle)
|
|
||||||
{
|
|
||||||
handle.Completed -= AssetContinuation;
|
|
||||||
BaseContinuation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SceneContinuation(SceneOperationHandle handle)
|
|
||||||
{
|
|
||||||
handle.Completed -= SceneContinuation;
|
|
||||||
BaseContinuation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SubContinuation(SubAssetsOperationHandle handle)
|
|
||||||
{
|
|
||||||
handle.Completed -= SubContinuation;
|
|
||||||
BaseContinuation();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void BaseContinuation()
|
|
||||||
{
|
|
||||||
if(completed)
|
|
||||||
{
|
|
||||||
TryReturn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
completed = true;
|
|
||||||
if(handle.Status == EOperationStatus.Failed)
|
|
||||||
{
|
|
||||||
core.TrySetException(new Exception(handle.LastError));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
core.TrySetResult(AsyncUnit.Default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Continuation(OperationHandleBase _)
|
|
||||||
{
|
|
||||||
switch(handle)
|
|
||||||
{
|
|
||||||
case AssetOperationHandle asset_handle:
|
|
||||||
asset_handle.Completed -= continuationAction;
|
|
||||||
break;
|
|
||||||
case SceneOperationHandle scene_handle:
|
|
||||||
scene_handle.Completed -= continuationAction;
|
|
||||||
break;
|
|
||||||
case SubAssetsOperationHandle sub_asset_handle:
|
|
||||||
sub_asset_handle.Completed -= continuationAction;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseContinuation();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryReturn()
|
|
||||||
{
|
|
||||||
TaskTracker.RemoveTracking(this);
|
|
||||||
core.Reset();
|
|
||||||
handle = default;
|
|
||||||
progress = default;
|
|
||||||
return pool.TryPush(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniTaskStatus GetStatus(short token) => core.GetStatus(token);
|
|
||||||
|
|
||||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
|
||||||
{
|
|
||||||
core.OnCompleted(continuation, state, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetResult(short token) { core.GetResult(token); }
|
|
||||||
|
|
||||||
public UniTaskStatus UnsafeGetStatus() => core.UnsafeGetStatus();
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if(completed)
|
|
||||||
{
|
|
||||||
TryReturn();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(handle.IsValid)
|
|
||||||
{
|
|
||||||
progress?.Report(handle.Progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: e1c9a3a6de2246bf88547a6b59b99b9f
|
|
||||||
timeCreated: 1650851321
|
|
|
@ -1,20 +0,0 @@
|
||||||
# UniTask 扩展
|
|
||||||
|
|
||||||
[仓库链接](https://github.com/Cysharp/UniTask)
|
|
||||||
- 请去下载对应的源码,并删除此目录最后的波浪线
|
|
||||||
- 在项目的 `asmdef` 文件中添加对 `UniTask.YooAsset` 的引用
|
|
||||||
- 在 UniTask `_InternalVisibleTo.cs` 文件中增加 `[assembly: InternalsVisibleTo("UniTask.YooAsset")]` 后即可使用
|
|
||||||
|
|
||||||
## 代码示例
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
var handle = YooAssets.LoadAssetAsync<GameObject>("Assets/Res/Prefabs/TestImg.prefab");
|
|
||||||
|
|
||||||
await handle.ToUniTask();
|
|
||||||
|
|
||||||
var obj = handle.AssetObject as GameObject;
|
|
||||||
var go = Instantiate(obj, transform);
|
|
||||||
|
|
||||||
go.transform.localPosition = Vector3.zero;
|
|
||||||
go.transform.localScale = Vector3.one;
|
|
||||||
```
|
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 6375cc739b170490fbc6c38181b2c600
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"name": "UniTask.YooAsset",
|
|
||||||
"rootNamespace": "",
|
|
||||||
"references": [
|
|
||||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
|
||||||
],
|
|
||||||
"includePlatforms": [],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": false,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": [],
|
|
||||||
"noEngineReferences": false
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: cf4f1d4730c114c48ab680458e5a2455
|
|
||||||
AssemblyDefinitionImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
Loading…
Reference in New Issue