mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-16 20:20:45 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b64f31eb0b | ||
|
|
38d159b69e | ||
|
|
d5455f3716 | ||
|
|
a72ceeba11 | ||
|
|
c6b7d332b2 | ||
|
|
f37278f2a6 | ||
|
|
3f3e03b83d | ||
|
|
c99d3eb3c3 | ||
|
|
08d5183e7e | ||
|
|
51769b2224 |
7
.github/workflows/build-debug.yml
vendored
7
.github/workflows/build-debug.yml
vendored
@@ -42,13 +42,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- run: apt update && apt install git -y
|
- run: apt update && apt install git -y
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# create unity activation file and store to artifacts.
|
|
||||||
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0
|
|
||||||
- uses: actions/upload-artifact@v1
|
|
||||||
with:
|
|
||||||
name: Unity_v${{ matrix.unity }}.alf
|
|
||||||
path: ./Unity_v${{ matrix.unity }}.alf
|
|
||||||
# activate Unity from manual license file(ulf)
|
|
||||||
- run: echo -n "$UNITY_LICENSE" >> .Unity.ulf
|
- run: echo -n "$UNITY_LICENSE" >> .Unity.ulf
|
||||||
env:
|
env:
|
||||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
||||||
|
|||||||
38
README.md
38
README.md
@@ -34,6 +34,7 @@ Techinical details, see blog post: [UniTask v2 — Zero Allocation async/await f
|
|||||||
- [For Unit Testing](#for-unit-testing)
|
- [For Unit Testing](#for-unit-testing)
|
||||||
- [Compare with Standard Task API](#compare-with-standard-task-api)
|
- [Compare with Standard Task API](#compare-with-standard-task-api)
|
||||||
- [Pooling Configuration](#pooling-configuration)
|
- [Pooling Configuration](#pooling-configuration)
|
||||||
|
- [Allocation on Profiler](#allocation-on-profiler)
|
||||||
- [UniTaskSynchronizationContext](#unitasksynchronizationcontext)
|
- [UniTaskSynchronizationContext](#unitasksynchronizationcontext)
|
||||||
- [API References](#api-references)
|
- [API References](#api-references)
|
||||||
- [UPM Package](#upm-package)
|
- [UPM Package](#upm-package)
|
||||||
@@ -151,25 +152,24 @@ UniTask provides three pattern of extension methods.
|
|||||||
|
|
||||||
> Note: WithCancellation is returned from native timing of PlayerLoop but ToUniTask is returned from specified PlayerLoopTiming. Details of timing, see: [PlayerLoop](#playerloop) section.
|
> Note: WithCancellation is returned from native timing of PlayerLoop but ToUniTask is returned from specified PlayerLoopTiming. Details of timing, see: [PlayerLoop](#playerloop) section.
|
||||||
|
|
||||||
|
> Note: AssetBundleRequest has `asset` and `allAssets`, in default await returns `asset`. If you want to get `allAssets`, you can use `AwaitForAllAssets()` method.
|
||||||
|
|
||||||
The type of `UniTask` can use utility like `UniTask.WhenAll`, `UniTask.WhenAny`. It is like Task.WhenAll/WhenAny but return type is more useful, returns value tuple so can deconsrtuct each result and pass multiple type.
|
The type of `UniTask` can use utility like `UniTask.WhenAll`, `UniTask.WhenAny`. It is like Task.WhenAll/WhenAny but return type is more useful, returns value tuple so can deconsrtuct each result and pass multiple type.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public class SceneAssets
|
public async UniTaskVoid LoadManyAsync()
|
||||||
{
|
{
|
||||||
public SceneAssets()
|
// parallel load.
|
||||||
{
|
var (a, b, c) = await UniTask.WhenAll(
|
||||||
// parallel load.
|
LoadAsSprite("foo"),
|
||||||
var (a, b, c) = await UniTask.WhenAll(
|
LoadAsSprite("bar"),
|
||||||
LoadAsSprite("foo"),
|
LoadAsSprite("baz"));
|
||||||
LoadAsSprite("bar"),
|
}
|
||||||
LoadAsSprite("baz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
async UniTask<Sprite> LoadAsSprite(string path)
|
async UniTask<Sprite> LoadAsSprite(string path)
|
||||||
{
|
{
|
||||||
var resource = await Resources.LoadAsync<Sprite>(path);
|
var resource = await Resources.LoadAsync<Sprite>(path);
|
||||||
return (resource as Sprite);
|
return (resource as Sprite);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -835,7 +835,15 @@ foreach (var (type, size) in TaskPool.GetCacheSizeInfo())
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> In UnityEditor profiler shows allocation of compiler generated AsyncStateMachine but it only occurs in debug(development) build. C# Compiler generate AsyncStateMachine as class on Debug build and as struct on Release build.
|
Allocation on Profiler
|
||||||
|
---
|
||||||
|
In UnityEditor profiler shows allocation of compiler generated AsyncStateMachine but it only occurs in debug(development) build. C# Compiler generate AsyncStateMachine as class on Debug build and as struct on Release build.
|
||||||
|
|
||||||
|
After Unity 2020.1 supports Code Optimization option on UnityEditor(right, footer).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
You can change C# compiler optimization to release, it removes AsyncStateMachine allocation. Andalso optimization option can set via `Compilation.CompilationPipeline-codeOptimization`, and `Compilation.CodeOptimization`.
|
||||||
|
|
||||||
UniTaskSynchronizationContext
|
UniTaskSynchronizationContext
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
IEnumerator innerEnumerator;
|
IEnumerator innerEnumerator;
|
||||||
CancellationToken cancellationToken;
|
CancellationToken cancellationToken;
|
||||||
|
int initialFrame;
|
||||||
|
|
||||||
UniTaskCompletionSourceCore<object> core;
|
UniTaskCompletionSourceCore<object> core;
|
||||||
|
|
||||||
@@ -66,10 +67,13 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
|
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
|
||||||
result.cancellationToken = cancellationToken;
|
result.cancellationToken = cancellationToken;
|
||||||
|
result.initialFrame = -1;
|
||||||
|
|
||||||
PlayerLoopHelper.AddAction(timing, result);
|
PlayerLoopHelper.AddAction(timing, result);
|
||||||
|
|
||||||
token = result.core.Version;
|
token = result.core.Version;
|
||||||
|
|
||||||
|
result.MoveNext(); // run immediately.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +112,19 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initialFrame == -1)
|
||||||
|
{
|
||||||
|
// Time can not touch in threadpool.
|
||||||
|
if (PlayerLoopHelper.IsMainThread)
|
||||||
|
{
|
||||||
|
initialFrame = Time.frameCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (initialFrame == Time.frameCount)
|
||||||
|
{
|
||||||
|
return true; // already executed in first frame, skip.
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (innerEnumerator.MoveNext())
|
if (innerEnumerator.MoveNext())
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [
|
"versionDefines": [
|
||||||
|
{
|
||||||
|
"name": "com.unity.modules.assetbundle",
|
||||||
|
"expression": "",
|
||||||
|
"define": "UNITASK_ASSETBUNDLE_SUPPORT"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
|
||||||
#if UNITY_2018_4 || UNITY_2019_4_OR_NEWER
|
#if UNITY_2018_4 || UNITY_2019_4_OR_NEWER
|
||||||
|
#if UNITASK_ASSETBUNDLE_SUPPORT
|
||||||
|
|
||||||
using Cysharp.Threading.Tasks.Internal;
|
using Cysharp.Threading.Tasks.Internal;
|
||||||
using System;
|
using System;
|
||||||
@@ -312,4 +313,5 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -605,6 +605,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#if UNITASK_ASSETBUNDLE_SUPPORT
|
||||||
#region AssetBundleRequest
|
#region AssetBundleRequest
|
||||||
|
|
||||||
public static AssetBundleRequestAwaiter GetAwaiter(this AssetBundleRequest asyncOperation)
|
public static AssetBundleRequestAwaiter GetAwaiter(this AssetBundleRequest asyncOperation)
|
||||||
@@ -906,7 +907,9 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNITASK_ASSETBUNDLE_SUPPORT
|
||||||
#region AssetBundleCreateRequest
|
#region AssetBundleCreateRequest
|
||||||
|
|
||||||
public static AssetBundleCreateRequestAwaiter GetAwaiter(this AssetBundleCreateRequest asyncOperation)
|
public static AssetBundleCreateRequestAwaiter GetAwaiter(this AssetBundleCreateRequest asyncOperation)
|
||||||
@@ -1208,6 +1211,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLE_UNITYWEBREQUEST
|
#if ENABLE_UNITYWEBREQUEST
|
||||||
#region UnityWebRequestAsyncOperation
|
#region UnityWebRequestAsyncOperation
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
Func<string, string> ToUniTaskReturnType = x => (x == "void") ? "UniTask" : $"UniTask<{x}>";
|
Func<string, string> ToUniTaskReturnType = x => (x == "void") ? "UniTask" : $"UniTask<{x}>";
|
||||||
Func<string, string> ToIUniTaskSourceReturnType = x => (x == "void") ? "IUniTaskSource" : $"IUniTaskSource<{x}>";
|
Func<string, string> ToIUniTaskSourceReturnType = x => (x == "void") ? "IUniTaskSource" : $"IUniTaskSource<{x}>";
|
||||||
Func<(string typeName, string returnType, string returnField), bool> IsUnityWebRequest = x => x.returnType == "UnityWebRequest";
|
Func<(string typeName, string returnType, string returnField), bool> IsUnityWebRequest = x => x.returnType == "UnityWebRequest";
|
||||||
|
Func<(string typeName, string returnType, string returnField), bool> IsAssetBundleModule = x => x.typeName == "AssetBundleRequest" || x.typeName == "AssetBundleCreateRequest";
|
||||||
Func<(string typeName, string returnType, string returnField), bool> IsVoid = x => x.returnType == "void";
|
Func<(string typeName, string returnType, string returnField), bool> IsVoid = x => x.returnType == "void";
|
||||||
#>
|
#>
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
@@ -37,6 +38,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
<# foreach(var t in types) { #>
|
<# foreach(var t in types) { #>
|
||||||
<# if(IsUnityWebRequest(t)) { #>
|
<# if(IsUnityWebRequest(t)) { #>
|
||||||
#if ENABLE_UNITYWEBREQUEST
|
#if ENABLE_UNITYWEBREQUEST
|
||||||
|
<# } else if(IsAssetBundleModule(t)) { #>
|
||||||
|
#if UNITASK_ASSETBUNDLE_SUPPORT
|
||||||
<# } #>
|
<# } #>
|
||||||
#region <#= t.typeName #>
|
#region <#= t.typeName #>
|
||||||
|
|
||||||
@@ -422,7 +425,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
<# if(IsUnityWebRequest(t)) { #>
|
<# if(IsUnityWebRequest(t) || IsAssetBundleModule(t)) { #>
|
||||||
#endif
|
#endif
|
||||||
<# } #>
|
<# } #>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.cysharp.unitask",
|
"name": "com.cysharp.unitask",
|
||||||
"displayName": "UniTask",
|
"displayName": "UniTask",
|
||||||
"version": "2.0.27",
|
"version": "2.0.28",
|
||||||
"unity": "2018.4",
|
"unity": "2018.4",
|
||||||
"description": "Provides an efficient async/await integration to Unity.",
|
"description": "Provides an efficient async/await integration to Unity.",
|
||||||
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
||||||
|
|||||||
126
src/UniTask/Assets/Tests/CoroutineToUniTaskTest.cs
Normal file
126
src/UniTask/Assets/Tests/CoroutineToUniTaskTest.cs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.Scripting;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Unity.Collections;
|
||||||
|
using System.Threading;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
using FluentAssertions;
|
||||||
|
|
||||||
|
namespace Cysharp.Threading.TasksTests
|
||||||
|
{
|
||||||
|
public class CoroutineToUniTaskTest
|
||||||
|
{
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator EarlyUpdate() => UniTask.ToCoroutine(async () =>
|
||||||
|
{
|
||||||
|
await UniTask.Yield(PlayerLoopTiming.EarlyUpdate);
|
||||||
|
|
||||||
|
var l = new List<(int, int)>();
|
||||||
|
var currentFrame = Time.frameCount;
|
||||||
|
var t = Worker(l).ToUniTask();
|
||||||
|
|
||||||
|
l.Count.Should().Be(1);
|
||||||
|
l[0].Should().Be((0, currentFrame));
|
||||||
|
|
||||||
|
await t;
|
||||||
|
|
||||||
|
l[1].Should().Be((1, Time.frameCount));
|
||||||
|
l[1].Item2.Should().NotBe(currentFrame);
|
||||||
|
});
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator LateUpdate() => UniTask.ToCoroutine(async () =>
|
||||||
|
{
|
||||||
|
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||||
|
|
||||||
|
var l = new List<(int, int)>();
|
||||||
|
var currentFrame = Time.frameCount;
|
||||||
|
var t = Worker(l).ToUniTask();
|
||||||
|
|
||||||
|
l.Count.Should().Be(1);
|
||||||
|
l[0].Should().Be((0, currentFrame));
|
||||||
|
|
||||||
|
await t;
|
||||||
|
|
||||||
|
l[1].Should().Be((1, Time.frameCount));
|
||||||
|
l[1].Item2.Should().NotBe(currentFrame);
|
||||||
|
});
|
||||||
|
|
||||||
|
//[UnityTest]
|
||||||
|
//public IEnumerator TestCoroutine()
|
||||||
|
//{
|
||||||
|
// yield return UniTask.Yield(PlayerLoopTiming.EarlyUpdate).ToUniTask().ToCoroutine();
|
||||||
|
|
||||||
|
// var nanika = (UnityEngine.MonoBehaviour)GameObject.FindObjectOfType(typeof(UnityEngine.MonoBehaviour));
|
||||||
|
|
||||||
|
// var l = new List<(int, int)>();
|
||||||
|
// var currentFrame = Time.frameCount;
|
||||||
|
// var t = nanika.StartCoroutine(Worker(l));
|
||||||
|
|
||||||
|
// l.Count.Should().Be(1);
|
||||||
|
// l[0].Should().Be((0, currentFrame));
|
||||||
|
|
||||||
|
// yield return t;
|
||||||
|
|
||||||
|
// l[1].Should().Be((1, Time.frameCount));
|
||||||
|
// l[1].Item2.Should().NotBe(currentFrame);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//[UnityTest]
|
||||||
|
//public IEnumerator TestCoroutine2()
|
||||||
|
//{
|
||||||
|
// yield return UniTask.Yield(PlayerLoopTiming.PostLateUpdate).ToUniTask().ToCoroutine();
|
||||||
|
|
||||||
|
// var nanika = (UnityEngine.MonoBehaviour)GameObject.FindObjectOfType(typeof(UnityEngine.MonoBehaviour));
|
||||||
|
|
||||||
|
// var l = new List<(int, int)>();
|
||||||
|
// var currentFrame = Time.frameCount;
|
||||||
|
// var t = nanika.StartCoroutine(Worker(l));
|
||||||
|
|
||||||
|
// l.Count.Should().Be(1);
|
||||||
|
// l[0].Should().Be((0, currentFrame));
|
||||||
|
|
||||||
|
// yield return t;
|
||||||
|
|
||||||
|
// l[1].Should().Be((1, Time.frameCount));
|
||||||
|
// l[1].Item2.Should().NotBe(currentFrame);
|
||||||
|
//}
|
||||||
|
|
||||||
|
IEnumerator Worker(List<(int, int)> l)
|
||||||
|
{
|
||||||
|
l.Add((0, Time.frameCount));
|
||||||
|
yield return null;
|
||||||
|
l.Add((1, Time.frameCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTask Foo()
|
||||||
|
{
|
||||||
|
var tasks = new List<UniTask>();
|
||||||
|
var t = Bar<int>();
|
||||||
|
tasks.Add(t);
|
||||||
|
|
||||||
|
t = Bar<int>();
|
||||||
|
tasks.Add(t);
|
||||||
|
|
||||||
|
await UniTask.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTask<T> Bar<T>()
|
||||||
|
{
|
||||||
|
await UniTask.Yield();
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
11
src/UniTask/Assets/Tests/CoroutineToUniTaskTest.cs.meta
Normal file
11
src/UniTask/Assets/Tests/CoroutineToUniTaskTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 43ffb719370515746932af3732ce073e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user