Compare commits

...

10 Commits

Author SHA1 Message Date
neuecc
b64f31eb0b 2.0.28 2020-08-13 17:44:15 +09:00
neuecc
38d159b69e IEnumerator.ToUniTask() behave same as StartCoroutine #120 2020-08-13 17:44:06 +09:00
neuecc
d5455f3716 Merge remote-tracking branch 'origin/master' 2020-08-13 16:33:41 +09:00
neuecc
a72ceeba11 UNITASK_ASSETBUNDLE_SUPPORT #131 2020-08-13 16:33:32 +09:00
Yoshifumi Kawai
c6b7d332b2 Update README.md 2020-08-12 11:41:21 +09:00
neuecc
f37278f2a6 docs: update TOC 2020-08-12 02:23:09 +00:00
Yoshifumi Kawai
3f3e03b83d Update README.md 2020-08-12 11:22:52 +09:00
Yoshifumi Kawai
c99d3eb3c3 Update README.md 2020-08-05 15:55:09 +09:00
Yoshifumi Kawai
08d5183e7e Merge pull request #121 from Cysharp/chore/unity_activation
chore: remove generate unity alf (activation license file)
2020-08-04 14:54:50 +09:00
Ikiru Yoshizaki
51769b2224 chore: remove generate unity alf (activation license file) 2020-08-04 13:20:33 +09:00
10 changed files with 193 additions and 24 deletions

View File

@@ -42,13 +42,6 @@ jobs:
steps:
- run: apt update && apt install git -y
- 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
env:
UNITY_LICENSE: ${{ secrets[matrix.license] }}

View File

@@ -34,6 +34,7 @@ Techinical details, see blog post: [UniTask v2 — Zero Allocation async/await f
- [For Unit Testing](#for-unit-testing)
- [Compare with Standard Task API](#compare-with-standard-task-api)
- [Pooling Configuration](#pooling-configuration)
- [Allocation on Profiler](#allocation-on-profiler)
- [UniTaskSynchronizationContext](#unitasksynchronizationcontext)
- [API References](#api-references)
- [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: 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.
```csharp
public class SceneAssets
public async UniTaskVoid LoadManyAsync()
{
public SceneAssets()
{
// parallel load.
var (a, b, c) = await UniTask.WhenAll(
LoadAsSprite("foo"),
LoadAsSprite("bar"),
LoadAsSprite("baz"));
}
// parallel load.
var (a, b, c) = await UniTask.WhenAll(
LoadAsSprite("foo"),
LoadAsSprite("bar"),
LoadAsSprite("baz"));
}
async UniTask<Sprite> LoadAsSprite(string path)
{
var resource = await Resources.LoadAsync<Sprite>(path);
return (resource as Sprite);
}
async UniTask<Sprite> LoadAsSprite(string path)
{
var resource = await Resources.LoadAsync<Sprite>(path);
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).
![](https://user-images.githubusercontent.com/46207/89967342-2f944600-dc8c-11ea-99fc-0b74527a16f6.png)
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
---

View File

@@ -44,6 +44,7 @@ namespace Cysharp.Threading.Tasks
IEnumerator innerEnumerator;
CancellationToken cancellationToken;
int initialFrame;
UniTaskCompletionSourceCore<object> core;
@@ -66,10 +67,13 @@ namespace Cysharp.Threading.Tasks
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
result.cancellationToken = cancellationToken;
result.initialFrame = -1;
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
result.MoveNext(); // run immediately.
return result;
}
@@ -108,6 +112,19 @@ namespace Cysharp.Threading.Tasks
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
{
if (innerEnumerator.MoveNext())

View File

@@ -10,6 +10,11 @@
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.modules.assetbundle",
"expression": "",
"define": "UNITASK_ASSETBUNDLE_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@@ -1,6 +1,7 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#if UNITY_2018_4 || UNITY_2019_4_OR_NEWER
#if UNITASK_ASSETBUNDLE_SUPPORT
using Cysharp.Threading.Tasks.Internal;
using System;
@@ -312,4 +313,5 @@ namespace Cysharp.Threading.Tasks
}
}
#endif
#endif

View File

@@ -605,6 +605,7 @@ namespace Cysharp.Threading.Tasks
#endregion
#if UNITASK_ASSETBUNDLE_SUPPORT
#region AssetBundleRequest
public static AssetBundleRequestAwaiter GetAwaiter(this AssetBundleRequest asyncOperation)
@@ -906,7 +907,9 @@ namespace Cysharp.Threading.Tasks
}
#endregion
#endif
#if UNITASK_ASSETBUNDLE_SUPPORT
#region AssetBundleCreateRequest
public static AssetBundleCreateRequestAwaiter GetAwaiter(this AssetBundleCreateRequest asyncOperation)
@@ -1208,6 +1211,7 @@ namespace Cysharp.Threading.Tasks
}
#endregion
#endif
#if ENABLE_UNITYWEBREQUEST
#region UnityWebRequestAsyncOperation

View File

@@ -17,6 +17,7 @@
Func<string, string> ToUniTaskReturnType = x => (x == "void") ? "UniTask" : $"UniTask<{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> IsAssetBundleModule = x => x.typeName == "AssetBundleRequest" || x.typeName == "AssetBundleCreateRequest";
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
@@ -37,6 +38,8 @@ namespace Cysharp.Threading.Tasks
<# foreach(var t in types) { #>
<# if(IsUnityWebRequest(t)) { #>
#if ENABLE_UNITYWEBREQUEST
<# } else if(IsAssetBundleModule(t)) { #>
#if UNITASK_ASSETBUNDLE_SUPPORT
<# } #>
#region <#= t.typeName #>
@@ -422,7 +425,7 @@ namespace Cysharp.Threading.Tasks
}
#endregion
<# if(IsUnityWebRequest(t)) { #>
<# if(IsUnityWebRequest(t) || IsAssetBundleModule(t)) { #>
#endif
<# } #>

View File

@@ -1,7 +1,7 @@
{
"name": "com.cysharp.unitask",
"displayName": "UniTask",
"version": "2.0.27",
"version": "2.0.28",
"unity": "2018.4",
"description": "Provides an efficient async/await integration to Unity.",
"keywords": [ "async/await", "async", "Task", "UniTask" ],

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43ffb719370515746932af3732ce073e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: