Compare commits

...

17 Commits

Author SHA1 Message Date
dvsilch
12df2b2e35 Merge 16895054f1 into 06067cd4c8 2025-04-09 14:08:44 +00:00
dvsilch
16895054f1 fix: async lazy cannot use utcs auto reset version 2025-04-09 22:08:32 +08:00
dvsilch
d3e71502d6 perf: using AutoResetUniTaskCompletionSource instead of UniTaskCompletionSource 2025-04-09 21:20:36 +08:00
dvsilch
63708841f5 fix: typo 2025-04-09 21:14:13 +08:00
Ikiru Yoshizaki
06067cd4c8 ci: use Cysharp/Actions checkout instead of 3rd party directly 2025-03-19 15:44:16 +09:00
Ikiru Yoshizaki
d9983cfe27 Merge pull request #654 from Cysharp/feature/pin_action
ci: Pinning third party GitHub Actions sha
2025-03-18 17:33:39 +09:00
Ikiru Yoshizaki
70eb7cd3ee ci: Pinning third party GitHub Actions sha 2025-03-18 16:58:33 +09:00
Ikiru Yoshizaki
cc3c70af90 ci: update vault 2025-03-11 12:55:51 +09:00
Ikiru Yoshizaki
8042b29ff8 ci: extend timeout 2025-01-07 12:29:34 +09:00
Yoshifumi Kawai
b0d01ca75f Merge pull request #641 from hmkc/dev
Update README_CN.md
2024-12-12 16:35:32 +09:00
hmkc
7a63ab7088 Update README_CN.md
Re-translated the documentation.
2024-12-11 17:13:32 +08:00
Yoshifumi Kawai
bdf102f145 Merge pull request #639 from hmkc/dev
Update README_CN.md
2024-12-09 20:18:43 +09:00
hmkc
41cea030ab Update README_CN.md 2024-12-09 18:39:08 +08:00
Yoshifumi Kawai
f9fd769be7 Update README.md 2024-10-09 14:46:23 +09:00
neuecc
579304fe47 chore(docs): update TOC 2024-10-08 14:02:41 +00:00
Yoshifumi Kawai
740ca7ef01 Awaitable notes 2024-10-08 23:02:26 +09:00
github-actions[bot]
7c0f199fe0 feat: Update package.json to 2.5.10 2024-10-03 00:42:37 +00:00
14 changed files with 313 additions and 261 deletions

View File

@@ -5,3 +5,8 @@ updates:
directory: "/"
schedule:
interval: "weekly" # Check for updates to GitHub Actions every week
ignore:
# I just want update action when major/minor version is updated. patch updates are too noisy.
- dependency-name: '*'
update-types:
- version-update:semver-patch

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/checkout@main
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
- run: dotnet build -c Debug
- run: dotnet test -c Debug
@@ -26,20 +26,20 @@ jobs:
matrix:
unity: ["2022.3.39f1", "6000.0.12f1"] # Test with LTS
runs-on: ubuntu-latest
timeout-minutes: 20
timeout-minutes: 30 # Unity build takes more than 20min.
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@v2
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0
with:
export-env: false
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://GitHubActionsPublic/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://GitHubActionsPublic/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://GitHubActionsPublic/UNITY_LICENSE/serial"
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial"
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/checkout@main
# Execute scripts: Export Package
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
@@ -56,10 +56,6 @@ jobs:
targetPlatform: StandaloneLinux64
buildMethod: PackageExporter.Export
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Execute UnitTest
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend IL2CPP /BuildTarget StandaloneLinux64
- name: Build UnitTest (IL2CPP)
@@ -79,6 +75,10 @@ jobs:
- name: Execute UnitTest
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_IL2CPP/test
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Store artifacts.
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021

View File

@@ -11,21 +11,21 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/checkout@main
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
repository: Cysharp/DocfxTemplate
path: docs/_DocfxTemplate
- uses: Kirbyrawr/docfx-action@master
- uses: Kirbyrawr/docfx-action@db9a22c8fe1e8693a2a21be54cb0b87dfaa72cc4
name: Docfx metadata
with:
args: metadata docs/docfx.json
- uses: Kirbyrawr/docfx-action@master
- uses: Kirbyrawr/docfx-action@db9a22c8fe1e8693a2a21be54cb0b87dfaa72cc4
name: Docfx build
with:
args: build docs/docfx.json
- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site

View File

@@ -26,7 +26,7 @@ jobs:
timeout-minutes: 10
steps:
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
@@ -51,17 +51,17 @@ jobs:
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@v2
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0
with:
export-env: false
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://GitHubActionsPublic/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://GitHubActionsPublic/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://GitHubActionsPublic/UNITY_LICENSE/serial"
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial"
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
# Execute scripts: Export Package

View File

@@ -8,8 +8,7 @@ on:
jobs:
generateTOC:
name: TOC Generator
runs-on: ubuntu-latest
steps:
- uses: technote-space/toc-generator@v4.3.1
with:
TOC_TITLE: "## Table of Contents"
uses: Cysharp/Actions/.github/workflows/toc-generator.yaml@main
with:
TOC_TITLE: "## Table of Contents"
secrets: inherit

View File

@@ -33,6 +33,7 @@ For advanced tips, see blog post: [Extends UnityWebRequest via async decorator p
- [AsyncEnumerable and Async LINQ](#asyncenumerable-and-async-linq)
- [Awaitable Events](#awaitable-events)
- [Channel](#channel)
- [vs Awaitable](#vs-awaitable)
- [For Unit Testing](#for-unit-testing)
- [ThreadPool limitation](#threadpool-limitation)
- [IEnumerator.ToUniTask limitation](#ienumeratortounitask-limitation)
@@ -67,6 +68,7 @@ async UniTask<string> DemoAsync()
await SceneManager.LoadSceneAsync("scene2");
// .WithCancellation enables Cancel, GetCancellationTokenOnDestroy synchornizes with lifetime of GameObject
// after Unity 2022.2, you can use `destroyCancellationToken` in MonoBehaviour
var asset2 = await Resources.LoadAsync<TextAsset>("bar").WithCancellation(this.GetCancellationTokenOnDestroy());
// .ToUniTask accepts progress callback(and all options), Progress.Create is a lightweight alternative of IProgress<T>
@@ -293,6 +295,8 @@ public class MyBehaviour : MonoBehaviour
}
```
After Unity 2022.2, Unity adds CancellationToken in [MonoBehaviour.destroyCancellationToken](https://docs.unity3d.com/ScriptReference/MonoBehaviour-destroyCancellationToken.html) and [Application.exitCancellationToken](https://docs.unity3d.com/ScriptReference/Application-exitCancellationToken.html).
When cancellation is detected, all methods throw `OperationCanceledException` and propagate upstream. When exception(not limited to `OperationCanceledException`) is not handled in async method, it is propagated finally to `UniTaskScheduler.UnobservedTaskException`. The default behaviour of received unhandled exception is to write log as exception. Log level can be changed using `UniTaskScheduler.UnobservedExceptionWriteLogType`. If you want to use custom behaviour, set an action to `UniTaskScheduler.UnobservedTaskException.`
And also `OperationCanceledException` is a special exception, this is silently ignored at `UnobservedTaskException`.
@@ -953,6 +957,14 @@ public class AsyncMessageBroker<T> : IDisposable
}
```
vs Awaitable
---
Unity 6 introduces the awaitable type, [Awaitable](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html). To put it simply, Awaitable can be considered a subset of UniTask, and in fact, Awaitable's design was influenced by UniTask. It should be able to handle PlayerLoop-based awaits, pooled Tasks, and support for cancellation with `CancellationToken` in a similar way. With its inclusion in the standard library, you may wonder whether to continue using UniTask or migrate to Awaitable. Here's a brief guide.
First, the functionality provided by Awaitable is equivalent to what coroutines offer. Instead of `yield return`, you use await; `await NextFrameAsync()` replaces `yield return null`; and there are equivalents for `WaitForSeconds` and `EndOfFrame`. However, that's the extent of it. Being coroutine-based in terms of functionality, it lacks Task-based features. In practical application development using async/await, operations like `WhenAll` are essential. Additionally, UniTask enables many frame-based operations (such as `DelayFrame`) and more flexible PlayerLoopTiming control, which are not available in Awaitable. Of course, there's no Tracker Window either.
Therefore, I recommend using UniTask for application development. UniTask is a superset of Awaitable and includes many essential features. For library development, where you want to avoid external dependencies, using Awaitable as a return type for methods would be appropriate. Awaitable can be converted to UniTask using `AsUniTask`, so there's no issue in handling Awaitable-based functionality within the UniTask library. Of course, if you don't need to worry about dependencies, using UniTask would be the best choice even for library development.
For Unit Testing
---
Unity's `[UnityTest]` attribute can test coroutine(IEnumerator) but can not test async. `UniTask.ToCoroutine` bridges async/await to coroutine so you can test async methods.

File diff suppressed because it is too large Load Diff

View File

@@ -67,13 +67,13 @@ namespace Cysharp.Threading.Tasks
return (UniTask.FromCanceled(cancellationToken), default(CancellationTokenRegistration));
}
var promise = new UniTaskCompletionSource();
var promise = AutoResetUniTaskCompletionSource.Create();
return (promise.Task, cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
static void Callback(object state)
{
var promise = (UniTaskCompletionSource)state;
var promise = (AutoResetUniTaskCompletionSource)state;
promise.TrySetResult();
}

View File

@@ -91,7 +91,7 @@ namespace Cysharp.Threading.Tasks
{
readonly Queue<T> items;
readonly SingleConsumerUnboundedChannelReader readerSource;
UniTaskCompletionSource completedTaskSource;
AutoResetUniTaskCompletionSource completedTaskSource;
UniTask completedTask;
Exception completionError;
@@ -208,7 +208,7 @@ namespace Cysharp.Threading.Tasks
return parent.completedTask;
}
parent.completedTaskSource = new UniTaskCompletionSource();
parent.completedTaskSource = AutoResetUniTaskCompletionSource.Create();
return parent.completedTaskSource.Task;
}
}

View File

@@ -36,11 +36,11 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
var tcs = new UniTaskCompletionSource<bool>();
var tcs = AutoResetUniTaskCompletionSource<bool>.Create();
cancellationToken.Register(state =>
{
var task = (UniTaskCompletionSource<bool>)state;
var task = (AutoResetUniTaskCompletionSource<bool>)state;
task.TrySetCanceled(cancellationToken);
}, tcs);

View File

@@ -18,13 +18,13 @@ namespace Cysharp.Threading.Tasks
#endif
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
/// <summary>This CancellationToken is canceled when the GameObject will be destroyed.</summary>
public static CancellationToken GetCancellationTokenOnDestroy(this GameObject gameObject)
{
return gameObject.GetAsyncDestroyTrigger().CancellationToken;
}
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
/// <summary>This CancellationToken is canceled when the Component will be destroyed.</summary>
public static CancellationToken GetCancellationTokenOnDestroy(this Component component)
{
#if UNITY_2022_2_OR_NEWER

View File

@@ -16,11 +16,11 @@ namespace Cysharp.Threading.Tasks
/// </summary>
public static UniTask<T> AsUniTask<T>(this Task<T> task, bool useCurrentSynchronizationContext = true)
{
var promise = new UniTaskCompletionSource<T>();
var promise = AutoResetUniTaskCompletionSource<T>.Create();
task.ContinueWith((x, state) =>
{
var p = (UniTaskCompletionSource<T>)state;
var p = (AutoResetUniTaskCompletionSource<T>)state;
switch (x.Status)
{
@@ -46,11 +46,11 @@ namespace Cysharp.Threading.Tasks
/// </summary>
public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
{
var promise = new UniTaskCompletionSource();
var promise = AutoResetUniTaskCompletionSource.Create();
task.ContinueWith((x, state) =>
{
var p = (UniTaskCompletionSource)state;
var p = (AutoResetUniTaskCompletionSource)state;
switch (x.Status)
{

View File

@@ -11,7 +11,7 @@ namespace Cysharp.Threading.Tasks
{
public static UniTask<T> ToUniTask<T>(this IObservable<T> source, bool useFirstValue = false, CancellationToken cancellationToken = default)
{
var promise = new UniTaskCompletionSource<T>();
var promise = AutoResetUniTaskCompletionSource<T>.Create();
var disposable = new SingleAssignmentDisposable();
var observer = useFirstValue
@@ -109,7 +109,7 @@ namespace Cysharp.Threading.Tasks
{
static readonly Action<object> callback = OnCanceled;
readonly UniTaskCompletionSource<T> promise;
readonly IPromise<T> promise;
readonly SingleAssignmentDisposable disposable;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration registration;
@@ -117,7 +117,7 @@ namespace Cysharp.Threading.Tasks
bool hasValue;
T latestValue;
public ToUniTaskObserver(UniTaskCompletionSource<T> promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken)
public ToUniTaskObserver(IPromise<T> promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken)
{
this.promise = promise;
this.disposable = disposable;
@@ -180,14 +180,14 @@ namespace Cysharp.Threading.Tasks
{
static readonly Action<object> callback = OnCanceled;
readonly UniTaskCompletionSource<T> promise;
readonly IPromise<T> promise;
readonly SingleAssignmentDisposable disposable;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration registration;
bool hasValue;
public FirstValueToUniTaskObserver(UniTaskCompletionSource<T> promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken)
public FirstValueToUniTaskObserver(IPromise<T> promise, SingleAssignmentDisposable disposable, CancellationToken cancellationToken)
{
this.promise = promise;
this.disposable = disposable;

View File

@@ -2,7 +2,7 @@
"name": "com.cysharp.unitask",
"displayName": "UniTask",
"author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" },
"version": "2.5.9",
"version": "2.5.10",
"unity": "2018.4",
"description": "Provides an efficient async/await integration to Unity.",
"keywords": [ "async/await", "async", "Task", "UniTask" ],