Merge pull request #19 from LiuOcean/main

Fix Unity 2020 IL2Cpp UniTask Bug
pull/21/head
何冠峰 2022-07-02 15:28:12 +08:00 committed by GitHub
commit 63f90e1537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 19 deletions

View File

@ -71,7 +71,7 @@ namespace Cysharp.Threading.Tasks
result.completed = false; result.completed = false;
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
if(progress is not null) if(progress != null)
{ {
PlayerLoopHelper.AddAction(timing, result); PlayerLoopHelper.AddAction(timing, result);
} }

View File

@ -1,7 +1,13 @@
#if UNITY_2020_1_OR_NEWER && ! UNITY_2021
#define UNITY_2020_BUG
#endif
using System; using System;
using System.Runtime.CompilerServices;
using YooAsset; using YooAsset;
using static Cysharp.Threading.Tasks.Internal.Error; using static Cysharp.Threading.Tasks.Internal.Error;
namespace Cysharp.Threading.Tasks namespace Cysharp.Threading.Tasks
{ {
public static class OperationHandleBaseExtensions public static class OperationHandleBaseExtensions
@ -71,11 +77,29 @@ namespace Cysharp.Threading.Tasks
result.completed = false; result.completed = false;
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
if(progress is not null) if(progress != null)
{ {
PlayerLoopHelper.AddAction(timing, result); 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) switch(handle)
{ {
case AssetOperationHandle asset_handle: case AssetOperationHandle asset_handle:
@ -88,11 +112,50 @@ namespace Cysharp.Threading.Tasks
sub_asset_handle.Completed += result.continuationAction; sub_asset_handle.Completed += result.continuationAction;
break; break;
} }
#endif
token = result.core.Version; token = result.core.Version;
return result; 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 _) private void Continuation(OperationHandleBase _)
{ {
@ -109,22 +172,7 @@ namespace Cysharp.Threading.Tasks
break; break;
} }
if(completed) BaseContinuation();
{
TryReturn();
}
else
{
completed = true;
if(handle.Status == EOperationStatus.Failed)
{
core.TrySetException(new Exception(handle.LastError));
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
}
} }
bool TryReturn() bool TryReturn()