Compare commits

...

119 Commits
2.4.0 ... 2.5.7

Author SHA1 Message Date
github-actions[bot]
74bbe87b58 feat: Update package.json to 2.5.7 2024-09-26 06:24:48 +00:00
Yoshifumi Kawai
6f4131539b Merge pull request #619 from kochounoyume/add-state-argument
Add overload in UniTask.WaitUntil, UniTask.WaitWhile and UniTask.Defer
2024-09-26 12:52:56 +09:00
Kochoyume
06283f0ffb Add to the code that I forgot to write 2024-09-24 23:58:28 +09:00
Kochoyume
dfe5ee43c2 Add overload in UniTask.WaitUntil, UniTask.WaitWhile and UniTask.Defer to avoid closure allocation 2024-09-24 23:37:44 +09:00
github-actions[bot]
83d8a2b424 feat: Update package.json to 2.5.6 2024-09-24 09:20:07 +00:00
Yoshifumi Kawai
4d204e4aa6 Update build-debug.yml 2024-09-24 17:49:34 +09:00
Yoshifumi Kawai
87e164e275 Merge pull request #600 from Iblis/textmeshpro_unity6_adoptions
TextMeshPro Unity6 adoptions
2024-09-24 17:16:20 +09:00
Yoshifumi Kawai
b63eb8d090 Merge pull request #610 from LucianoPC/forget-ignored-task
Forget ignored task
2024-09-24 17:14:40 +09:00
neuecc
75119acb50 Fix WaitWhile(bool cancelImmediately = true) does not work correctly
, and when cancelImmediately = true and canceled task remove Trakcking immediately
2024-09-24 17:12:50 +09:00
Ikiru Yoshizaki
f7b3c2fbe1 ci: update release unity version to 2022.3.39f1 [skip ci] 2024-09-18 17:06:00 +09:00
Ikiru Yoshizaki
b317ecfa01 ci: set max-parallel to restrict up to 2 run [skip ci] 2024-09-18 16:27:42 +09:00
Ikiru Yoshizaki
7b05569ef7 ci: single job 2024-09-18 16:27:42 +09:00
Luciano Prestes Cavalcanti
e0465c6c2c Forget ignored task 2024-08-19 08:18:57 -03:00
Yoshifumi Kawai
9057452c86 Merge pull request #607 from Redpenguine/master
fix: incorrect download progress reporting
2024-08-14 19:54:15 +09:00
Mykyta Myronenko
a2f6f84bde fix: incorrect download progress reporting 2024-08-10 19:29:54 +03:00
Ikiru Yoshizaki
f057abff0f chore: remove Unity UserSettigs from git handling 2024-07-31 16:11:03 +09:00
Ikiru Yoshizaki
c61a7d9961 Merge pull request #605 from Cysharp/dependabot/github_actions/peaceiris/actions-gh-pages-4
chore(deps): bump peaceiris/actions-gh-pages from 3 to 4
2024-07-30 17:09:56 +09:00
Ikiru Yoshizaki
9587f2eeec Merge pull request #606 from Cysharp/dependabot/github_actions/technote-space/toc-generator-4.3.1
chore(deps): bump technote-space/toc-generator from 2.4.0 to 4.3.1
2024-07-30 17:09:49 +09:00
Ikiru Yoshizaki
550784f31c ci: check not dependabot 2024-07-30 17:07:43 +09:00
Ikiru Yoshizaki
11b3282b3d ci: Don't allow dependabot to run Unity CI 2024-07-30 17:01:09 +09:00
dependabot[bot]
b2532b0798 chore(deps): bump technote-space/toc-generator from 2.4.0 to 4.3.1
Bumps [technote-space/toc-generator](https://github.com/technote-space/toc-generator) from 2.4.0 to 4.3.1.
- [Release notes](https://github.com/technote-space/toc-generator/releases)
- [Changelog](https://github.com/technote-space/toc-generator/blob/main/.releasegarc)
- [Commits](https://github.com/technote-space/toc-generator/compare/v2.4.0...v4.3.1)

---
updated-dependencies:
- dependency-name: technote-space/toc-generator
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-30 06:42:27 +00:00
dependabot[bot]
4fc41ecb17 chore(deps): bump peaceiris/actions-gh-pages from 3 to 4
Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 3 to 4.
- [Release notes](https://github.com/peaceiris/actions-gh-pages/releases)
- [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md)
- [Commits](https://github.com/peaceiris/actions-gh-pages/compare/v3...v4)

---
updated-dependencies:
- dependency-name: peaceiris/actions-gh-pages
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-30 06:42:24 +00:00
Ikiru Yoshizaki
e52663cef6 Merge pull request #570 from Cysharp/ci/dependabot
ci: add depndabot.yaml to update github-actions
2024-07-30 15:41:57 +09:00
Ikiru Yoshizaki
1827be2de7 Merge pull request #603 from Cysharp/feature/test
ci: Change Unity UnitTest from Mono to IL2CPP and enabled on CI
2024-07-30 15:41:47 +09:00
Ikiru Yoshizaki
8560561ef3 chore: remove Layouts for Unity2022 2024-07-30 15:17:05 +09:00
Ikiru Yoshizaki
2019f1fa7f ci: update CI Unity 2024-07-30 15:16:54 +09:00
Ikiru Yoshizaki
9e2265d148 ci: split job for build and test 2024-07-30 14:46:59 +09:00
Ikiru Yoshizaki
9d02279822 ci: extend Unity Build timeout to 20m 2024-07-30 14:25:31 +09:00
Ikiru Yoshizaki
17ce06d93c chore: remove com.unity.ai.navigation as 2021.3.39f1 failed and not inuse 2024-07-30 14:07:59 +09:00
Ikiru Yoshizaki
7b810413fe fix: missing include Packages folder for Unity 2024-07-30 14:00:06 +09:00
Ikiru Yoshizaki
d78c0d6c02 ci: remove garbage folder 2024-07-30 12:36:34 +09:00
Ikiru Yoshizaki
d248acc7d1 chore: bump RuntimeUnitTestToolkit to 2.6.0 to adapt Unity 2022 Build API change 2024-07-30 12:34:46 +09:00
Ikiru Yoshizaki
4c0b1f753a chore: bump UniTask unity version to 2022.3.39f1 2024-07-24 20:11:26 +09:00
Ikiru Yoshizaki
7bb6feda55 chore: switch to src/UniTask/*.cproj 2024-07-24 20:10:17 +09:00
Ikiru Yoshizaki
f8a501290a chore: upload 2024-07-24 20:08:11 +09:00
Ikiru Yoshizaki
cb497c9eb5 ci: bump Unity version to LTS, Unity Unit Test with LTS. 2024-07-24 19:35:31 +09:00
Ikiru Yoshizaki
342a37a074 ci: add strategy.fail-fast: false 2024-07-24 17:44:49 +09:00
Ikiru Yoshizaki
c3146ec74f ci: change Unit Test to IL2CPP 2024-07-24 17:24:01 +09:00
Ikiru Yoshizaki
df16813fae ci: bump actions/checkout@v3 -> v4 2024-07-24 17:22:28 +09:00
Philipp Walser
8d98bbc7ba added version contraint, tmp is part of ugui since v2.0.0 2024-07-12 19:05:38 +02:00
Philipp Walser
bb095697f7 added versionDefine to set TMP support if ugui is found, too 2024-07-12 19:01:59 +02:00
github-actions[bot]
cdf88c6a6a feat: Update package.json to 2.5.5 2024-07-01 06:47:55 +00:00
Yoshifumi Kawai
4eee2c9270 Merge pull request #599 from xfvvvv/patch-1
Fix onTextSelection and onEndTextSelection stack overflow issue
2024-07-01 15:45:30 +09:00
Chelal
222b1401f5 Fix onTextSelection and onEndTextSelection stack overflow issue 2024-06-29 21:51:27 +08:00
Ikiru Yoshizaki
fbe0bf8515 Merge pull request #579 from Cysharp/feature/artifact
ci: change upload-artifact & download-artifact to Cysharp/Actions
2024-04-30 14:36:53 +09:00
Ikiru Yoshizaki
626685292c ci: set upload-artifact retention-period: 1 2024-04-30 14:06:49 +09:00
Ikiru Yoshizaki
67794f5cdd ci: change upload-artifact & download-artifact to Cysharp/Actions 2024-04-30 12:43:17 +09:00
Mayuki Sawatari
2e225fb841 Merge pull request #571 from Cysharp/feature/secret
feat: change load secret from op
2024-04-17 18:29:49 +09:00
Ikiru Yoshizaki
935523f25c feat: change load secret from op 2024-04-17 16:09:55 +09:00
Ikiru Yoshizaki
3b3f7ebd3e ci: add depndabot.yaml to update github-actions 2024-04-16 12:14:52 +09:00
Yoshifumi Kawai
88ecfa2992 Merge pull request #565 from divdeploy/master
chore: fix comment
2024-04-08 17:03:08 +09:00
divdeploy
aa70fe5c5a chore: fix comment
Signed-off-by: divdeploy <chenguangxue@outlook.com>
2024-04-05 23:28:56 +08:00
Yoshifumi Kawai
0c8057c668 Merge pull request #538 from kochounoyume/argument-allowed-factory
Factory method allowed argument
2024-04-05 13:30:39 +09:00
Kochoyume
28867646b0 Fix T state as the first argument 2024-03-31 00:05:18 +09:00
Kochoyume
ca60864021 Fix comment 2024-03-30 23:57:43 +09:00
Kochoyume
1e4561da22 Fix comment 2024-03-30 23:57:43 +09:00
Kochoyume
1496cc990a Fix misspelling 2024-03-30 23:57:43 +09:00
Kochoyume
7bb3bf8d0e Update UniTask.Create, Unitask.Action and UniTask.UnityAction 2024-03-30 23:57:43 +09:00
github-actions[bot]
d057074f17 feat: Update package.json to 2.5.4 2024-03-28 06:22:15 +00:00
hadashiA
b724a2aa84 Merge pull request #557 from Cysharp/hadashiA/fix-cancel-immediate
Fix unintended returning to pool with cancelImmediately
2024-03-28 15:21:40 +09:00
hadashiA
938ddd5356 Tweaks 2024-03-28 15:15:55 +09:00
hadashiA
911c37d4d8 Tweaks 2024-03-28 15:14:10 +09:00
hadashiA
caccccb0b5 Fix timing to returning to pool 2024-03-28 15:00:41 +09:00
hadashiA
a48f11d31b Fix unintended returning to pool with cancelImmediately (WaitUntil,etc) 2024-03-28 14:46:37 +09:00
hadashiA
fcd93feb56 Fix unintended returning to pool with cancelImmediately (AsyncOperation) 2024-03-28 14:45:55 +09:00
hadashiA
b472b23773 Fix unintended returning to pool with cancelImmediately (UniTask.Delay) 2024-03-28 14:29:30 +09:00
Yoshifumi Kawai
01c8fada1f Merge pull request #542 from Cysharp/feature/new_release
ci: Cysharp/Actions/.github/workflows/create-release.yaml
2024-03-25 18:30:50 +09:00
Ikiru Yoshizaki
10cd137126 ci: Cysharp/Actions/.github/workflows/create-release.yaml 2024-02-07 21:04:48 +09:00
Yoshifumi Kawai
809d23edae Merge pull request #541 from TORISOUP/fix_ToArray
Optimization of ToArray in Merge method
2024-02-04 23:19:47 +09:00
TORISOUP
d38731bc44 fix call ToArray 2024-02-04 20:51:21 +09:00
github-actions[bot]
64792b672d feat: Update package.json to 2.5.3 2024-01-25 12:52:16 +00:00
neuecc
3892cc2299 Merge branch 'master' of https://github.com/Cysharp/UniTask 2024-01-25 21:51:45 +09:00
neuecc
5bfccaa3b6 autoReleaseWhenCancelled -> autoReleaseWhenCanceled 2024-01-25 21:51:40 +09:00
github-actions[bot]
b49b7332bb feat: Update package.json to 2.5.2 2024-01-25 11:43:24 +00:00
neuecc
08184af737 simplify UNITASK define 2024-01-25 20:42:42 +09:00
Yoshifumi Kawai
0ef6c59385 Merge pull request #535 from kochounoyume/valuetask-error-netframework
UniTask does not work in .NET Framework environment after adding UniTask.AsValueTask
2024-01-25 20:26:21 +09:00
Yoshifumi Kawai
4b0bd3b509 Merge pull request #536 from Cysharp/hadashiA/release-handle
Fix "Release handle when cancellation is requested"
2024-01-25 20:26:13 +09:00
Kochoyume
9a4720d180 Fix:Addressed generic parameter attributes error in the .Net Framework 2024-01-25 20:05:45 +09:00
hadashiA
b99646558c Add a flag autoReleaseWhenCancelled to addressable extensionhs 2024-01-25 19:03:00 +09:00
hadashiA
ee12dd9ae7 Fix omissions in Addressable.Release and IsValid checks 2024-01-25 17:47:06 +09:00
Kochoyume
006e0f2c81 Revert "Fix conditional compilation to work with .NET Framework"
This reverts commit 7d31299b5c.
2024-01-25 16:16:01 +09:00
Kochoyume
7d31299b5c Fix conditional compilation to work with .NET Framework 2024-01-25 01:02:57 +09:00
Yoshifumi Kawai
fe8bf834e6 Update README.md 2024-01-24 10:47:31 +09:00
github-actions[bot]
5843258e8c feat: Update package.json to 2.5.1 2024-01-24 01:44:21 +00:00
Yoshifumi Kawai
6cd002645e Merge pull request #533 from doyasu24/feature/add-unitask-asvaluetask-for-unity
add UniTask.AsValueTask for Unity
2024-01-24 10:41:39 +09:00
doyasu24
4fe0861714 fix: use UNITY_2018_3_OR_NEWER instead of UNITY_2018_1_OR_NEWER 2024-01-19 23:42:17 +09:00
doyasu24
fbbba061dd ValueTask is available in Unity 2021_2_OR_NEWER or .NET Core 2024-01-19 23:40:28 +09:00
doyasu24
81f2e37ea5 add UniTask.AsValueTask for Unity 2024-01-19 00:29:21 +09:00
Yoshifumi Kawai
66de0d3a58 Merge pull request #519 from Cysharp/guitarrapc-patch-1
Use Cysharp/Actions/setup-dotnet default version
2024-01-12 15:34:54 +09:00
Yoshifumi Kawai
beb10abbf7 Merge pull request #524 from Saismirk/master
Fixed typo in TimeoutWithoutException summary.
2024-01-12 15:22:35 +09:00
Saismirk
d60f64761b Fixed typo in TimeoutWithoutException summary. 2023-12-10 12:53:52 -05:00
Luciano Prestes Cavalcanti
36ac0863ad Release handle when cancellation is requested 2023-11-22 08:09:03 -03:00
Ikiru Yoshizaki
104f8e09ca Update build-release.yml 2023-11-15 12:09:34 +09:00
Ikiru Yoshizaki
cfbff008c4 Use Cysharp/Actions/setup-dotnet default version
## tl;dr;

It support both .NET 6,7 and 8. No need specify version.
2023-11-15 11:55:27 +09:00
Yoshifumi Kawai
5cc97c7f00 ReadMe 2023-11-02 18:23:43 +09:00
github-actions[bot]
5666292496 feat: Update package.json to 2.5.0 2023-11-02 05:03:47 +00:00
hadashiA
1288cbc128 Merge pull request #518 from Cysharp/hadashiA/awaitable-to-unitask
Add Awaitable.AsUniTask()
2023-11-02 14:02:36 +09:00
hadashiA
5f3aa18f38 Add Awaitable<T>.ToUniTask 2023-11-02 13:54:55 +09:00
hadashiA
0970ae8c31 Merge pull request #517 from Cysharp/hadashiA/cancel-immediately-flag
Add a flag to cancel immediately instead of player loop
2023-11-02 13:52:12 +09:00
hadashiA
ad23f7fb29 Fix #if directive that should be in .tt 2023-11-02 12:54:59 +09:00
hadashiA
a4be8f316e Add Awaitable.AsUniTask() 2023-11-02 12:35:05 +09:00
hadashiA
370425578f Fix AssetBundleRequestAll 2023-11-02 12:24:41 +09:00
hadashiA
1b76f77608 Add test 2023-11-02 12:24:41 +09:00
hadashiA
0579984355 Use AsyncOperation.completed callback usually 2023-11-02 12:24:41 +09:00
hadashiA
39cf81d2ab Add test for unity AsyncOperation 2023-11-02 12:24:41 +09:00
hadashiA
0a203c8db9 Cache Action in advance 2023-11-02 12:24:41 +09:00
hadashiA
55be4dba82 Add callback handler to AsyncOperationConfiguredSource instead to create other sources 2023-11-02 12:24:41 +09:00
hadashiA
f0adf36633 Use AsyncOperation.completed handler with new optional argument 2023-11-02 12:24:41 +09:00
hadashiA
24afc4f3eb Add cancelImmediately flag for assetbundle extensions 2023-11-02 12:24:41 +09:00
hadashiA
2cf06af433 Change AsyncEnumerable factory to use OperationCanceledException 2023-11-02 12:24:36 +09:00
hadashiA
94be2e748b Add cancelImmediately flag for addressable extensions 2023-10-27 15:06:12 +09:00
hadashiA
7f582e5e29 Update README 2023-10-27 14:52:58 +09:00
hadashiA
3f042c8886 Add cancel immediate flag 2023-10-27 12:42:12 +09:00
Yoshifumi Kawai
6f5d818544 Merge pull request #515 from ananttheant/fix/readme-typo
Fix typo in README.md
2023-10-26 13:11:42 +09:00
Anant Sharma
2ccb37cb02 Fix typo in README.md 2023-10-25 15:24:27 +01:00
github-actions[bot]
cfe509a556 feat: Update package.json to 2.4.1 2023-09-21 03:22:58 +00:00
hadashiA
a46a4cac01 Merge pull request #509 from Cysharp/ku/fix-dotween-registration
Fix a bug in Dotween after returning to the pool of `CancellationToken.Register`
2023-09-21 12:20:43 +09:00
hadashiA
3ed28e534a Tweaks 2023-09-21 10:00:27 +09:00
hadashiA
be8dbe8804 Fixed a bug in Dotween after returning to the pool of CancellationToken.Register 2023-09-20 17:35:04 +09:00
65 changed files with 2984 additions and 2434 deletions

7
.github/dependabot.yaml vendored Normal file
View File

@@ -0,0 +1,7 @@
# ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly" # Check for updates to GitHub Actions every week

View File

@@ -13,49 +13,43 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
with:
dotnet-version: |
6.0.x
7.0.x
- run: dotnet build -c Debug
- run: dotnet test -c Debug
build-unity:
if: "((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))"
if: ${{ ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:')) && github.triggering_actor != 'dependabot[bot]' }}
strategy:
fail-fast: false
max-parallel: 2
matrix:
unity: ["2019.3.9f1", "2019.4.13f1", "2020.1.12f1"]
unity: ["2021.3.41f1", "2022.3.39f1", "6000.0.12f1"] # Test with LTS
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
# Execute scripts: RuntimeUnitTestToolkit
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend mono /BuildTarget StandaloneLinux64
- name: Build UnitTest(Linux64, mono)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@v2
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
targetPlatform: StandaloneLinux64
buildMethod: UnitTestBuilder.BuildUnitTest
customParameters: /headless /ScriptBackend mono
- name: Execute UnitTest
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_Mono2x/test
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"
- uses: actions/checkout@v4
# Execute scripts: Export Package
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
- name: Build Unity (.unitypacakge)
if: ${{ startsWith(matrix.unity, '2021') }} # only execute once
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
@@ -66,8 +60,29 @@ jobs:
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)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
targetPlatform: StandaloneLinux64
buildMethod: UnitTestBuilder.BuildUnitTest
customParameters: "/headless /ScriptBackend IL2CPP"
- name: Check UnitTest file is generated
run: ls -lR ./src/UniTask/bin/UnitTest
- name: Execute UnitTest
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_IL2CPP/test
# Store artifacts.
- uses: actions/upload-artifact@v2
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021
with:
name: UniTask.unitypackage-${{ matrix.unity }}.zip
path: ./src/UniTask/*.unitypackage
retention-days: 1

View File

@@ -11,8 +11,8 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: Cysharp/DocfxTemplate
path: docs/_DocfxTemplate
@@ -25,7 +25,7 @@ jobs:
with:
args: build docs/docfx.json
- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site

View File

@@ -12,17 +12,13 @@ on:
default: false
type: boolean
env:
GIT_TAG: ${{ github.event.inputs.tag }}
DRY_RUN: ${{ github.event.inputs.dry-run }}
jobs:
update-packagejson:
uses: Cysharp/Actions/.github/workflows/update-packagejson.yaml@main
with:
file-path: ./src/UniTask/Assets/Plugins/UniTask/package.json
tag: ${{ github.event.inputs.tag }}
dry-run: ${{ fromJson(github.event.inputs.dry-run) }}
tag: ${{ inputs.tag }}
dry-run: ${{ inputs.dry-run }}
build-dotnet:
needs: [update-packagejson]
@@ -30,34 +26,42 @@ jobs:
timeout-minutes: 10
steps:
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
with:
dotnet-version: |
3.1.x
6.0.x
# build and pack
- run: dotnet build -c Release -p:Version=${{ env.GIT_TAG }}
- run: dotnet build -c Release -p:Version=${{ inputs.tag }}
- run: dotnet test -c Release --no-build
- run: dotnet pack ./src/UniTask.NetCore/UniTask.NetCore.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish
- run: dotnet pack ./src/UniTask.NetCore/UniTask.NetCore.csproj -c Release --no-build -p:Version=${{ inputs.tag }} -o ./publish
# Store artifacts.
- uses: actions/upload-artifact@v2
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
with:
name: nuget
path: ./publish/
retention-days: 1
build-unity:
needs: [update-packagejson]
strategy:
matrix:
unity: ["2019.3.9f1"]
unity: ["2022.3.39f1"]
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@v2
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"
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
# Execute scripts: Export Package
@@ -65,9 +69,9 @@ jobs:
- name: Build Unity (.unitypacakge)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
@@ -79,45 +83,27 @@ jobs:
directory: src/UniTask
# Store artifacts.
- uses: actions/upload-artifact@v2
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
with:
name: UniTask.${{ env.GIT_TAG }}.unitypackage
path: ./src/UniTask/UniTask.${{ env.GIT_TAG }}.unitypackage
name: UniTask.${{ inputs.tag }}.unitypackage
path: ./src/UniTask/UniTask.${{ inputs.tag }}.unitypackage
retention-days: 1
# release
create-release:
if: github.event.inputs.dry-run == 'false'
needs: [update-packagejson, build-dotnet, build-unity]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
# Create Releases
- uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.GIT_TAG }}
release_name: Ver.${{ env.GIT_TAG }}
commitish: ${{ needs.update-packagejson.outputs.sha }}
draft: true
prerelease: false
# Download(All) Artifacts to current directory
- uses: actions/download-artifact@v2
# Upload to NuGet
- run: dotnet nuget push "./nuget/*.nupkg" --skip-duplicate -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }}
# Upload to Releases(unitypackage)
- uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./UniTask.${{ env.GIT_TAG }}.unitypackage/UniTask.${{ env.GIT_TAG }}.unitypackage
asset_name: UniTask.${{ env.GIT_TAG }}.unitypackage
asset_content_type: application/octet-stream
uses: Cysharp/Actions/.github/workflows/create-release.yaml@main
with:
commit-id: ${{ needs.update-packagejson.outputs.sha }}
dry-run: ${{ inputs.dry-run }}
tag: ${{ inputs.tag }}
nuget-push: true
release-upload: true
release-asset-path: ./UniTask.${{ inputs.tag }}.unitypackage/UniTask.${{ inputs.tag }}.unitypackage
secrets: inherit
cleanup:
if: needs.update-packagejson.outputs.is-branch-created == 'true'
if: ${{ needs.update-packagejson.outputs.is-branch-created == 'true' }}
needs: [update-packagejson, build-dotnet, build-unity]
uses: Cysharp/Actions/.github/workflows/clean-packagejson-branch.yaml@main
with:

View File

@@ -10,6 +10,6 @@ jobs:
name: TOC Generator
runs-on: ubuntu-latest
steps:
- uses: technote-space/toc-generator@v2.4.0
- uses: technote-space/toc-generator@v4.3.1
with:
TOC_TITLE: "## Table of Contents"

145
.gitignore vendored
View File

@@ -80,7 +80,7 @@ _ReSharper*
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
@@ -130,134 +130,15 @@ UpgradeLog*.XML
Assets/WSATestCertificate.pfx
.vs/
Assembly-CSharp\.csproj
UniRx\.Async\.csproj
UniRx\.Async\.Editor\.csproj
UniRx\.Async\.Tests\.csproj
UniTask\.sln
RuntimeUnitTestToolkit\.csproj
Assembly-CSharp-Editor\.csproj
UniRx\.Async\.unitypackage
UniRx.Async.Tests.Editor.csproj
src/UniTask/UniTask.csproj
src/UniTask/UniTask.Editor.csproj
src/UniTask/UniTask.Tests.csproj
src/UniTask/UniTask.Tests.Editor.csproj
src/UniTask/UniTask.*.unitypackage
src/UniTask/UniTask.Linq.csproj
src/UniTask/DOTween.Modules.csproj
src/UniTask/Unity.Addressables.csproj
src/UniTask/Unity.Addressables.Editor.csproj
src/UniTask/Unity.Analytics.DataPrivacy.csproj
src/UniTask/Unity.Recorder.csproj
src/UniTask/Unity.Recorder.Editor.csproj
src/UniTask/Unity.ResourceManager.csproj
src/UniTask/Unity.Rider.Editor.csproj
src/UniTask/Unity.ScriptableBuildPipeline.csproj
src/UniTask/Unity.ScriptableBuildPipeline.Editor.csproj
src/UniTask/Unity.TextMeshPro.csproj
src/UniTask/Unity.TextMeshPro.Editor.csproj
src/UniTask/Unity.Timeline.csproj
src/UniTask/Unity.Timeline.Editor.csproj
src/UniTask/Unity.VisualStudio.Editor.csproj
src/UniTask/Unity.VSCode.Editor.csproj
src/UniTask/UnityEditor.CacheServer.csproj
src/UniTask/UnityEditor.TestRunner.csproj
src/UniTask/UnityEditor.UI.csproj
src/UniTask/UnityEngine.Advertisements.csproj
src/UniTask/UnityEngine.Monetization.csproj
src/UniTask/UnityEngine.TestRunner.csproj
src/UniTask/UnityEngine.UI.csproj
src/UniTask/TempAsm.csproj
src/UniTask/UniTask.Addressables.csproj
src/UniTask/UniTask.DOTween.csproj
src/UniTask/UniTask.TextMeshPro.csproj
src/UniTask/RuntimeUnitTestToolkit.Player.csproj
src/UniTask/TempAsm.Player.csproj
src/UniTask/UniTask.Addressables.Player.csproj
src/UniTask/UniTask.DOTween.Player.csproj
src/UniTask/UniTask.Linq.Player.csproj
src/UniTask/UniTask.Player.csproj
src/UniTask/UniTask.Tests.Player.csproj
src/UniTask/UniTask.TextMeshPro.Player.csproj
src/UniTask/Unity.Addressables.Player.csproj
src/UniTask/Unity.Analytics.DataPrivacy.Player.csproj
src/UniTask/Unity.ResourceManager.Player.csproj
src/UniTask/Unity.ScriptableBuildPipeline.Player.csproj
src/UniTask/Unity.TextMeshPro.Player.csproj
src/UniTask/Unity.Timeline.Player.csproj
src/UniTask/UnityEngine.Advertisements.Player.csproj
src/UniTask/UnityEngine.Monetization.Player.csproj
src/UniTask/UnityEngine.TestRunner.Player.csproj
src/UniTask/UnityEngine.UI.Player.csproj
src/UniTask/DOTween.Modules.Player.csproj
src/UniTask/Assembly-CSharp.Player.csproj
src/UniTask/Unity.EditorCoroutines.Editor.csproj
src/UniTask/.vsconfig
src/UniTask/Logs/ApiUpdaterCheck.txt
src/UniTask/Assembly-CSharp-firstpass.csproj
# Unity
# Unity
.vsconfig
src/UniTask/Library/*
src/UniTask/Temp/*
src/UniTask/Logs/*
src/UniTask/[Uu]ser[Ss]ettings/
src/UniTask/*.sln
src/UniTask/*.csproj
src/UniTask/*.unitypackage
!src/UniTask/Packages/

View File

@@ -51,7 +51,7 @@ For advanced tips, see blog post: [Extends UnityWebRequest via async decorator p
Getting started
---
Install via [UPM package](#upm-package) or asset package(`UniTask.*.*.*.unitypackage`) available in [UniTask/releases](https://github.com/Cysharp/UniTask/releases) page.
Install via [UPM package](#upm-package) with git reference or asset package(`UniTask.*.*.*.unitypackage`) available in [UniTask/releases](https://github.com/Cysharp/UniTask/releases).
```csharp
// extension awaiter/methods can be used by this namespace
@@ -295,7 +295,7 @@ public class MyBehaviour : MonoBehaviour
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.`
Andalso `OperationCanceledException` is a special exception, this is silently ignored at `UnobservedTaskException`.
And also `OperationCanceledException` is a special exception, this is silently ignored at `UnobservedTaskException`.
If you want to cancel behaviour in an async UniTask method, throw `OperationCanceledException` manually.
@@ -336,6 +336,18 @@ if (isCanceled)
Note: Only suppress throws if you call directly into the most source method. Otherwise, the return value will be converted, but the entire pipeline will not suppress throws.
Some features that use Unity's player loop, such as `UniTask.Yield` and `UniTask.Delay` etc, determines CancellationToken state on the player loop.
This means it does not cancel immediately upon `CancellationToken` fired.
If you want to change this behaviour, the cancellation to be immediate, set the `cancelImmediately` flag as an argument.
```csharp
await UniTask.Yield(cancellationToken, cancelImmediately: true);
```
Note: Setting `cancelImmediately` to true and detecting an immediate cancellation is more costly than the default behavior.
This is because it uses `CancellationToken.Register`; it is heavier than checking CancellationToken on the player loop.
Timeout handling
---
Timeout is a variation of cancellation. You can set timeout by `CancellationTokenSouce.CancelAfterSlim(TimeSpan)` and pass CancellationToken to async methods.
@@ -363,7 +375,7 @@ If you want to use timeout with other source of cancellation, use `CancellationT
```csharp
var cancelToken = new CancellationTokenSource();
cancelButton.onClick.AddListener(()=>
cancelButton.onClick.AddListener(() =>
{
cancelToken.Cancel(); // cancel from button click.
});
@@ -688,7 +700,7 @@ Unity 2020.2 supports C# 8.0 so you can use `await foreach`. This is the new Upd
```csharp
// Unity 2020.2, C# 8.0
await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate(token))
await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate().WithCancellation(token))
{
Debug.Log("Update() " + Time.frameCount);
}
@@ -698,10 +710,10 @@ In a C# 7.3 environment, you can use the `ForEachAsync` method to work in almost
```csharp
// C# 7.3(Unity 2018.3~)
await UniTaskAsyncEnumerable.EveryUpdate(token).ForEachAsync(_ =>
await UniTaskAsyncEnumerable.EveryUpdate().ForEachAsync(_ =>
{
Debug.Log("Update() " + Time.frameCount);
});
}, token);
```
UniTaskAsyncEnumerable implements asynchronous LINQ, similar to LINQ in `IEnumerable<T>` or Rx in `IObservable<T>`. All standard LINQ query operators can be applied to asynchronous streams. For example, the following code shows how to apply a Where filter to a button-click asynchronous stream that runs once every two clicks.

View File

@@ -685,7 +685,7 @@ Unity 2020.2 支持 C# 8.0,因此您可以使用`await foreach`. 这是异步
```csharp
// Unity 2020.2, C# 8.0
await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate(token))
await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate().WithCancellation(token))
{
Debug.Log("Update() " + Time.frameCount);
}
@@ -695,10 +695,10 @@ await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate(token))
```csharp
// C# 7.3(Unity 2018.3~)
await UniTaskAsyncEnumerable.EveryUpdate(token).ForEachAsync(_ =>
await UniTaskAsyncEnumerable.EveryUpdate().ForEachAsync(_ =>
{
Debug.Log("Update() " + Time.frameCount);
});
}, token);
```
UniTaskAsyncEnumerable 实现异步 LINQ类似于 LINQ 的`IEnumerable<T>`或 Rx 的 `IObservable<T>`。所有标准 LINQ 查询运算符都可以应用于异步流。例如,以下代码表示如何将 Where 过滤器应用于每两次单击运行一次的按钮单击异步流。

View File

@@ -1,42 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<AssemblyName>UniTask</AssemblyName>
<LangVersion>8.0</LangVersion>
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<AssemblyName>UniTask</AssemblyName>
<LangVersion>8.0</LangVersion>
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
<DefineConstants>UNITASK_NETCORE</DefineConstants>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<!-- NuGet Packaging -->
<Id>UniTask</Id>
<PackageVersion>$(Version)</PackageVersion>
<Company>Cysharp</Company>
<Authors>Cysharp</Authors>
<Copyright>© Cysharp, Inc.</Copyright>
<PackageTags>task;async</PackageTags>
<Description>Provides an efficient async/await integration to Unity and .NET Core.</Description>
<PackageProjectUrl>https://github.com/Cysharp/UniTask</PackageProjectUrl>
<RepositoryUrl>$(PackageProjectUrl)</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Icon.png</PackageIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>opensource.snk</AssemblyOriginatorKeyFile>
<IsPackable>true</IsPackable>
</PropertyGroup>
<!-- NuGet Packaging -->
<Id>UniTask</Id>
<PackageVersion>$(Version)</PackageVersion>
<Company>Cysharp</Company>
<Authors>Cysharp</Authors>
<Copyright>© Cysharp, Inc.</Copyright>
<PackageTags>task;async</PackageTags>
<Description>Provides an efficient async/await integration to Unity and .NET Core.</Description>
<PackageProjectUrl>https://github.com/Cysharp/UniTask</PackageProjectUrl>
<RepositoryUrl>$(PackageProjectUrl)</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Icon.png</PackageIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>opensource.snk</AssemblyOriginatorKeyFile>
<IsPackable>true</IsPackable>
</PropertyGroup>
<ItemGroup>
<None Include="Icon.png" Pack="true" PackagePath="/" />
</ItemGroup>
<ItemGroup>
<None Include="Icon.png" Pack="true" PackagePath="/" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\UniTask\Assets\Plugins\UniTask\Runtime\**\*.cs" Exclude="&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Triggers\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Linq\UnityExtensions\*.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityEqualityComparer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\DiagnosticsExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\PlayerLoopRunner.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\ContinuationQueue.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityWebRequestExtensions.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTaskSynchronizationContext.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\CancellationTokenSourceExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\EnumeratorAsyncExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\TimeoutController.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopHelper.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopTimer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Delay.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Run.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Bridge.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.WaitUntil.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.*;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityBindingExtensions.cs;&#xD;&#xA;" />
<Compile Remove="..\UniTask\Assets\Plugins\UniTask\Runtime\_InternalVisibleTo.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\UniTask\Assets\Plugins\UniTask\Runtime\**\*.cs" Exclude="&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Triggers\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Linq\UnityExtensions\*.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityEqualityComparer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\DiagnosticsExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\PlayerLoopRunner.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\ContinuationQueue.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityWebRequestExtensions.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTaskSynchronizationContext.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\CancellationTokenSourceExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\EnumeratorAsyncExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\TimeoutController.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopHelper.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopTimer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Delay.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Run.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Bridge.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.WaitUntil.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.*;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityBindingExtensions.cs;&#xD;&#xA;" />
<Compile Remove="..\UniTask\Assets\Plugins\UniTask\Runtime\_InternalVisibleTo.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>
</Project>

View File

@@ -1,3 +1,5 @@
#pragma warning disable CS1998
using System;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,3 +1,5 @@
#pragma warning disable CS1998
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;

View File

@@ -7,6 +7,7 @@ using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace Cysharp.Threading.Tasks
@@ -20,12 +21,12 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(handle).GetAwaiter();
}
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken)
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken);
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
@@ -44,7 +45,7 @@ namespace Cysharp.Threading.Tasks
return UniTask.CompletedTask;
}
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token);
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
@@ -103,20 +104,23 @@ namespace Cysharp.Threading.Tasks
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size);
}
readonly Action<AsyncOperationHandle> continuationAction;
readonly Action<AsyncOperationHandle> completedCallback;
AsyncOperationHandle handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncOperationHandleConfiguredSource()
{
continuationAction = Continuation;
completedCallback = HandleCompleted;
}
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -131,47 +135,81 @@ namespace Cysharp.Threading.Tasks
result.handle = handle;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.completed = false;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.continuationAction;
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void Continuation(AsyncOperationHandle _)
void HandleCompleted(AsyncOperationHandle _)
{
handle.Completed -= continuationAction;
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
TryReturn();
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
core.TrySetResult(AsyncUnit.Default);
}
}
public void GetResult(short token)
{
core.GetResult(token);
try
{
core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
public UniTaskStatus GetStatus(short token)
@@ -193,20 +231,23 @@ namespace Cysharp.Threading.Tasks
{
if (completed)
{
TryReturn();
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.PercentComplete);
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
@@ -219,6 +260,7 @@ namespace Cysharp.Threading.Tasks
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
@@ -232,12 +274,12 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(handle).GetAwaiter();
}
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken)
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken);
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
@@ -255,7 +297,7 @@ namespace Cysharp.Threading.Tasks
return UniTask.FromResult(handle.Result);
}
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, out var token), token);
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
@@ -269,20 +311,23 @@ namespace Cysharp.Threading.Tasks
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource<T>), () => pool.Size);
}
readonly Action<AsyncOperationHandle<T>> continuationAction;
readonly Action<AsyncOperationHandle<T>> completedCallback;
AsyncOperationHandle<T> handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<T> core;
AsyncOperationHandleConfiguredSource()
{
continuationAction = Continuation;
completedCallback = HandleCompleted;
}
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -298,46 +343,79 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken;
result.completed = false;
result.progress = progress;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource<T>)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.continuationAction;
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void Continuation(AsyncOperationHandle<T> argHandle)
void HandleCompleted(AsyncOperationHandle<T> argHandle)
{
handle.Completed -= continuationAction;
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
TryReturn();
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (argHandle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(argHandle.OperationException);
}
else
{
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else if (argHandle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(argHandle.OperationException);
}
else
{
core.TrySetResult(argHandle.Result);
}
core.TrySetResult(argHandle.Result);
}
}
public T GetResult(short token)
{
return core.GetResult(token);
try
{
return core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
void IUniTaskSource.GetResult(short token)
@@ -364,20 +442,23 @@ namespace Cysharp.Threading.Tasks
{
if (completed)
{
TryReturn();
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.PercentComplete);
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
@@ -390,6 +471,7 @@ namespace Cysharp.Threading.Tasks
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}

View File

@@ -2,7 +2,8 @@
"name": "UniTask.Addressables",
"references": [
"UniTask",
"Unity.ResourceManager"
"Unity.ResourceManager",
"Unity.Addressables"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -148,6 +148,7 @@ namespace Cysharp.Threading.Tasks
Tween tween;
TweenCancelBehaviour cancelBehaviour;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationRegistration;
CallbackType callbackType;
bool canceled;
@@ -207,7 +208,7 @@ namespace Cysharp.Threading.Tasks
default:
break;
}
if (result.originalCompleteAction == result.onCompleteCallbackDelegate)
{
result.originalCompleteAction = null;
@@ -215,7 +216,7 @@ namespace Cysharp.Threading.Tasks
if (cancellationToken.CanBeCanceled)
{
cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
result.cancellationRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
{
var source = (TweenConfiguredSource)x;
switch (source.cancelBehaviour)
@@ -250,30 +251,7 @@ namespace Cysharp.Threading.Tasks
source.tween.Complete(true);
break;
case TweenCancelBehaviour.CancelAwait:
// restore to original callback
switch (callbackType)
{
case CallbackType.Kill:
tween.onKill = source.originalCompleteAction;
break;
case CallbackType.Complete:
tween.onComplete = source.originalCompleteAction;
break;
case CallbackType.Pause:
tween.onPause = source.originalCompleteAction;
break;
case CallbackType.Play:
tween.onPlay = source.originalCompleteAction;
break;
case CallbackType.Rewind:
tween.onRewind = source.originalCompleteAction;
break;
case CallbackType.StepComplete:
tween.onStepComplete = source.originalCompleteAction;
break;
default:
break;
}
source.RestoreOriginalCallback();
source.core.TrySetCanceled(source.cancellationToken);
break;
}
@@ -376,7 +354,18 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationRegistration.Dispose();
RestoreOriginalCallback();
tween = default;
cancellationToken = default;
originalCompleteAction = default;
return pool.TryPush(this);
}
void RestoreOriginalCallback()
{
switch (callbackType)
{
case CallbackType.Kill:
@@ -400,11 +389,6 @@ namespace Cysharp.Threading.Tasks
default:
break;
}
tween = default;
cancellationToken = default;
originalCompleteAction = default;
return pool.TryPush(this);
}
}
}

View File

@@ -16,7 +16,12 @@
"name": "com.unity.textmeshpro",
"expression": "",
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
},
{
"name": "com.unity.ugui",
"expression": "2.0.0",
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
}
],
"noEngineReferences": false
}
}

View File

@@ -1,4 +1,9 @@
#pragma warning disable CS1591
#pragma warning disable CS0108
#if (UNITASK_NETCORE && !NETSTANDARD2_0) || UNITY_2022_3_OR_NEWER
#define SUPPORT_VALUETASK
#endif
using System;
using System.Runtime.CompilerServices;
@@ -19,9 +24,8 @@ namespace Cysharp.Threading.Tasks
// similar as IValueTaskSource
public interface IUniTaskSource
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
#if SUPPORT_VALUETASK
: System.Threading.Tasks.Sources.IValueTaskSource
#pragma warning disable CS0108
#endif
{
UniTaskStatus GetStatus(short token);
@@ -30,8 +34,7 @@ namespace Cysharp.Threading.Tasks
UniTaskStatus UnsafeGetStatus(); // only for debug use.
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
#pragma warning restore CS0108
#if SUPPORT_VALUETASK
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token)
{
@@ -53,13 +56,13 @@ namespace Cysharp.Threading.Tasks
}
public interface IUniTaskSource<out T> : IUniTaskSource
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
#if SUPPORT_VALUETASK
, System.Threading.Tasks.Sources.IValueTaskSource<T>
#endif
{
new T GetResult(short token);
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
#if SUPPORT_VALUETASK
new public UniTaskStatus GetStatus(short token)
{

View File

@@ -27,7 +27,9 @@ namespace Cysharp.Threading.Tasks.Linq
public static IUniTaskAsyncEnumerable<T> Merge<T>(this IEnumerable<IUniTaskAsyncEnumerable<T>> sources)
{
return new Merge<T>(sources.ToArray());
return sources is IUniTaskAsyncEnumerable<T>[] array
? new Merge<T>(array)
: new Merge<T>(sources.ToArray());
}
public static IUniTaskAsyncEnumerable<T> Merge<T>(params IUniTaskAsyncEnumerable<T>[] sources)

View File

@@ -4,38 +4,50 @@ namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
{
return new EveryUpdate(updateTiming);
return new EveryUpdate(updateTiming, cancelImmediately);
}
}
internal class EveryUpdate : IUniTaskAsyncEnumerable<AsyncUnit>
{
readonly PlayerLoopTiming updateTiming;
readonly bool cancelImmediately;
public EveryUpdate(PlayerLoopTiming updateTiming)
public EveryUpdate(PlayerLoopTiming updateTiming, bool cancelImmediately)
{
this.updateTiming = updateTiming;
this.cancelImmediately = cancelImmediately;
}
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _EveryUpdate(updateTiming, cancellationToken);
return new _EveryUpdate(updateTiming, cancellationToken, cancelImmediately);
}
class _EveryUpdate : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
{
readonly PlayerLoopTiming updateTiming;
CancellationToken cancellationToken;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
bool disposed;
public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken)
public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken, bool cancelImmediately)
{
this.updateTiming = updateTiming;
this.cancellationToken = cancellationToken;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (_EveryUpdate)state;
source.completionSource.TrySetCanceled(source.cancellationToken);
}, this);
}
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(updateTiming, this);
}
@@ -44,10 +56,14 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
if (disposed) return CompletedTasks.False;
completionSource.Reset();
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
}
return new UniTask<bool>(this, completionSource.Version);
}
@@ -55,6 +71,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
if (!disposed)
{
cancellationTokenRegistration.Dispose();
disposed = true;
TaskTracker.RemoveTracking(this);
}
@@ -63,7 +80,13 @@ namespace Cysharp.Threading.Tasks.Linq
public bool MoveNext()
{
if (disposed || cancellationToken.IsCancellationRequested)
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return false;
}
if (disposed)
{
completionSource.TrySetResult(false);
return false;

View File

@@ -7,7 +7,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<TProperty> EveryValueChanged<TTarget, TProperty>(TTarget target, Func<TTarget, TProperty> propertySelector, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<TProperty> equalityComparer = null)
public static IUniTaskAsyncEnumerable<TProperty> EveryValueChanged<TTarget, TProperty>(TTarget target, Func<TTarget, TProperty> propertySelector, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<TProperty> equalityComparer = null, bool cancelImmediately = false)
where TTarget : class
{
var unityObject = target as UnityEngine.Object;
@@ -15,11 +15,11 @@ namespace Cysharp.Threading.Tasks.Linq
if (isUnityObject)
{
return new EveryValueChangedUnityObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming);
return new EveryValueChangedUnityObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming, cancelImmediately);
}
else
{
return new EveryValueChangedStandardObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming);
return new EveryValueChangedStandardObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming, cancelImmediately);
}
}
}
@@ -30,18 +30,20 @@ namespace Cysharp.Threading.Tasks.Linq
readonly Func<TTarget, TProperty> propertySelector;
readonly IEqualityComparer<TProperty> equalityComparer;
readonly PlayerLoopTiming monitorTiming;
readonly bool cancelImmediately;
public EveryValueChangedUnityObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming)
public EveryValueChangedUnityObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, bool cancelImmediately)
{
this.target = target;
this.propertySelector = propertySelector;
this.equalityComparer = equalityComparer;
this.monitorTiming = monitorTiming;
this.cancelImmediately = cancelImmediately;
}
public IUniTaskAsyncEnumerator<TProperty> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken);
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken, cancelImmediately);
}
sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator<TProperty>, IPlayerLoopItem
@@ -50,13 +52,14 @@ namespace Cysharp.Threading.Tasks.Linq
readonly UnityEngine.Object targetAsUnityObject;
readonly IEqualityComparer<TProperty> equalityComparer;
readonly Func<TTarget, TProperty> propertySelector;
CancellationToken cancellationToken;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
bool first;
TProperty currentValue;
bool disposed;
public _EveryValueChanged(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken)
public _EveryValueChanged(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken, bool cancelImmediately)
{
this.target = target;
this.targetAsUnityObject = target as UnityEngine.Object;
@@ -64,6 +67,16 @@ namespace Cysharp.Threading.Tasks.Linq
this.equalityComparer = equalityComparer;
this.cancellationToken = cancellationToken;
this.first = true;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (_EveryValueChanged)state;
source.completionSource.TrySetCanceled(source.cancellationToken);
}, this);
}
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(monitorTiming, this);
}
@@ -72,8 +85,15 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
if (disposed) return CompletedTasks.False;
completionSource.Reset();
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return new UniTask<bool>(this, completionSource.Version);
}
if (first)
{
@@ -86,7 +106,6 @@ namespace Cysharp.Threading.Tasks.Linq
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
@@ -94,6 +113,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
if (!disposed)
{
cancellationTokenRegistration.Dispose();
disposed = true;
TaskTracker.RemoveTracking(this);
}
@@ -102,13 +122,18 @@ namespace Cysharp.Threading.Tasks.Linq
public bool MoveNext()
{
if (disposed || cancellationToken.IsCancellationRequested || targetAsUnityObject == null) // destroyed = cancel.
if (disposed || targetAsUnityObject == null)
{
completionSource.TrySetResult(false);
DisposeAsync().Forget();
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return false;
}
TProperty nextValue = default(TProperty);
try
{
@@ -139,18 +164,20 @@ namespace Cysharp.Threading.Tasks.Linq
readonly Func<TTarget, TProperty> propertySelector;
readonly IEqualityComparer<TProperty> equalityComparer;
readonly PlayerLoopTiming monitorTiming;
readonly bool cancelImmediately;
public EveryValueChangedStandardObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming)
public EveryValueChangedStandardObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, bool cancelImmediately)
{
this.target = new WeakReference<TTarget>(target, false);
this.propertySelector = propertySelector;
this.equalityComparer = equalityComparer;
this.monitorTiming = monitorTiming;
this.cancelImmediately = cancelImmediately;
}
public IUniTaskAsyncEnumerator<TProperty> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken);
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken, cancelImmediately);
}
sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator<TProperty>, IPlayerLoopItem
@@ -158,19 +185,30 @@ namespace Cysharp.Threading.Tasks.Linq
readonly WeakReference<TTarget> target;
readonly IEqualityComparer<TProperty> equalityComparer;
readonly Func<TTarget, TProperty> propertySelector;
CancellationToken cancellationToken;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
bool first;
TProperty currentValue;
bool disposed;
public _EveryValueChanged(WeakReference<TTarget> target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken)
public _EveryValueChanged(WeakReference<TTarget> target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken, bool cancelImmediately)
{
this.target = target;
this.propertySelector = propertySelector;
this.equalityComparer = equalityComparer;
this.cancellationToken = cancellationToken;
this.first = true;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (_EveryValueChanged)state;
source.completionSource.TrySetCanceled(source.cancellationToken);
}, this);
}
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(monitorTiming, this);
}
@@ -179,8 +217,16 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
if (disposed) return CompletedTasks.False;
completionSource.Reset();
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return new UniTask<bool>(this, completionSource.Version);
}
if (first)
{
first = false;
@@ -192,7 +238,6 @@ namespace Cysharp.Threading.Tasks.Linq
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
@@ -200,6 +245,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
if (!disposed)
{
cancellationTokenRegistration.Dispose();
disposed = true;
TaskTracker.RemoveTracking(this);
}
@@ -208,13 +254,19 @@ namespace Cysharp.Threading.Tasks.Linq
public bool MoveNext()
{
if (disposed || cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t))
if (disposed || !target.TryGetTarget(out var t))
{
completionSource.TrySetResult(false);
DisposeAsync().Forget();
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return false;
}
TProperty nextValue = default(TProperty);
try
{

View File

@@ -6,32 +6,32 @@ namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
{
return new Timer(dueTime, null, updateTiming, ignoreTimeScale);
return new Timer(dueTime, null, updateTiming, ignoreTimeScale, cancelImmediately);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
{
return new Timer(dueTime, period, updateTiming, ignoreTimeScale);
return new Timer(dueTime, period, updateTiming, ignoreTimeScale, cancelImmediately);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
public static IUniTaskAsyncEnumerable<AsyncUnit> Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
{
return new Timer(period, period, updateTiming, ignoreTimeScale);
return new Timer(period, period, updateTiming, ignoreTimeScale, cancelImmediately);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
{
if (dueTimeFrameCount < 0)
{
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
}
return new TimerFrame(dueTimeFrameCount, null, updateTiming);
return new TimerFrame(dueTimeFrameCount, null, updateTiming, cancelImmediately);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
{
if (dueTimeFrameCount < 0)
{
@@ -42,16 +42,16 @@ namespace Cysharp.Threading.Tasks.Linq
throw new ArgumentOutOfRangeException("Delay does not allow minus periodFrameCount. periodFrameCount:" + dueTimeFrameCount);
}
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming);
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancelImmediately);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
{
if (intervalFrameCount < 0)
{
throw new ArgumentOutOfRangeException("Delay does not allow minus intervalFrameCount. intervalFrameCount:" + intervalFrameCount);
}
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming);
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming, cancelImmediately);
}
}
@@ -61,18 +61,20 @@ namespace Cysharp.Threading.Tasks.Linq
readonly TimeSpan dueTime;
readonly TimeSpan? period;
readonly bool ignoreTimeScale;
readonly bool cancelImmediately;
public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale)
public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, bool cancelImmediately)
{
this.updateTiming = updateTiming;
this.dueTime = dueTime;
this.period = period;
this.ignoreTimeScale = ignoreTimeScale;
this.cancelImmediately = cancelImmediately;
}
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _Timer(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken);
return new _Timer(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken, cancelImmediately);
}
class _Timer : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
@@ -81,7 +83,8 @@ namespace Cysharp.Threading.Tasks.Linq
readonly float? period;
readonly PlayerLoopTiming updateTiming;
readonly bool ignoreTimeScale;
CancellationToken cancellationToken;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
int initialFrame;
float elapsed;
@@ -89,7 +92,7 @@ namespace Cysharp.Threading.Tasks.Linq
bool completed;
bool disposed;
public _Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken)
public _Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken, bool cancelImmediately)
{
this.dueTime = (float)dueTime.TotalSeconds;
this.period = (period == null) ? null : (float?)period.Value.TotalSeconds;
@@ -105,6 +108,16 @@ namespace Cysharp.Threading.Tasks.Linq
this.updateTiming = updateTiming;
this.ignoreTimeScale = ignoreTimeScale;
this.cancellationToken = cancellationToken;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (_Timer)state;
source.completionSource.TrySetCanceled(source.cancellationToken);
}, this);
}
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(updateTiming, this);
}
@@ -114,12 +127,16 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False;
if (disposed || completed) return CompletedTasks.False;
// reset value here.
this.elapsed = 0;
completionSource.Reset();
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
}
return new UniTask<bool>(this, completionSource.Version);
}
@@ -127,6 +144,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
if (!disposed)
{
cancellationTokenRegistration.Dispose();
disposed = true;
TaskTracker.RemoveTracking(this);
}
@@ -135,11 +153,16 @@ namespace Cysharp.Threading.Tasks.Linq
public bool MoveNext()
{
if (disposed || cancellationToken.IsCancellationRequested)
if (disposed)
{
completionSource.TrySetResult(false);
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return false;
}
if (dueTimePhase)
{
@@ -187,24 +210,27 @@ namespace Cysharp.Threading.Tasks.Linq
readonly PlayerLoopTiming updateTiming;
readonly int dueTimeFrameCount;
readonly int? periodFrameCount;
readonly bool cancelImmediately;
public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming)
public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, bool cancelImmediately)
{
this.updateTiming = updateTiming;
this.dueTimeFrameCount = dueTimeFrameCount;
this.periodFrameCount = periodFrameCount;
this.cancelImmediately = cancelImmediately;
}
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken);
return new _TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken, cancelImmediately);
}
class _TimerFrame : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
{
readonly int dueTimeFrameCount;
readonly int? periodFrameCount;
CancellationToken cancellationToken;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
int initialFrame;
int currentFrame;
@@ -212,7 +238,7 @@ namespace Cysharp.Threading.Tasks.Linq
bool completed;
bool disposed;
public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken)
public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken, bool cancelImmediately)
{
if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0;
if (periodFrameCount != null)
@@ -225,6 +251,15 @@ namespace Cysharp.Threading.Tasks.Linq
this.dueTimeFrameCount = dueTimeFrameCount;
this.periodFrameCount = periodFrameCount;
this.cancellationToken = cancellationToken;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (_TimerFrame)state;
source.completionSource.TrySetCanceled(source.cancellationToken);
}, this);
}
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(updateTiming, this);
@@ -234,13 +269,15 @@ namespace Cysharp.Threading.Tasks.Linq
public UniTask<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False;
if (disposed || completed) return CompletedTasks.False;
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
}
// reset value here.
this.currentFrame = 0;
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
@@ -249,6 +286,7 @@ namespace Cysharp.Threading.Tasks.Linq
{
if (!disposed)
{
cancellationTokenRegistration.Dispose();
disposed = true;
TaskTracker.RemoveTracking(this);
}
@@ -257,7 +295,12 @@ namespace Cysharp.Threading.Tasks.Linq
public bool MoveNext()
{
if (disposed || cancellationToken.IsCancellationRequested)
if (cancellationToken.IsCancellationRequested)
{
completionSource.TrySetCanceled(cancellationToken);
return false;
}
if (disposed)
{
completionSource.TrySetResult(false);
return false;

View File

@@ -1,5 +1,11 @@
#pragma warning disable 0649
#if UNITASK_NETCORE || UNITY_2022_3_OR_NEWER
#define SUPPORT_VALUETASK
#endif
#if SUPPORT_VALUETASK
using System;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
@@ -10,7 +16,7 @@ namespace Cysharp.Threading.Tasks
{
public static ValueTask AsValueTask(this in UniTask task)
{
#if NETSTANDARD2_0
#if (UNITASK_NETCORE && NETSTANDARD2_0)
return new ValueTask(new UniTaskValueTaskSource(task), 0);
#else
return task;
@@ -19,7 +25,7 @@ namespace Cysharp.Threading.Tasks
public static ValueTask<T> AsValueTask<T>(this in UniTask<T> task)
{
#if NETSTANDARD2_0
#if (UNITASK_NETCORE && NETSTANDARD2_0)
return new ValueTask<T>(new UniTaskValueTaskSource<T>(task), 0);
#else
return task;
@@ -36,7 +42,7 @@ namespace Cysharp.Threading.Tasks
await task;
}
#if NETSTANDARD2_0
#if (UNITASK_NETCORE && NETSTANDARD2_0)
class UniTaskValueTaskSource : IValueTaskSource
{
@@ -95,3 +101,4 @@ namespace Cysharp.Threading.Tasks
#endif
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 12bdad0556e999f4aa82da29415d361f
guid: d38f0478933be42d895c37b862540a1c
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -33,14 +33,14 @@ namespace Cysharp.Threading.Tasks
return new YieldAwaitable(timing);
}
public static UniTask Yield(CancellationToken cancellationToken)
public static UniTask Yield(CancellationToken cancellationToken, bool cancelImmediately = false)
{
return new UniTask(YieldPromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token);
return new UniTask(YieldPromise.Create(PlayerLoopTiming.Update, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken)
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately = false)
{
return new UniTask(YieldPromise.Create(timing, cancellationToken, out var token), token);
return new UniTask(YieldPromise.Create(timing, cancellationToken, cancelImmediately, out var token), token);
}
/// <summary>
@@ -48,7 +48,7 @@ namespace Cysharp.Threading.Tasks
/// </summary>
public static UniTask NextFrame()
{
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, CancellationToken.None, out var token), token);
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, CancellationToken.None, false, out var token), token);
}
/// <summary>
@@ -56,23 +56,23 @@ namespace Cysharp.Threading.Tasks
/// </summary>
public static UniTask NextFrame(PlayerLoopTiming timing)
{
return new UniTask(NextFramePromise.Create(timing, CancellationToken.None, out var token), token);
return new UniTask(NextFramePromise.Create(timing, CancellationToken.None, false, out var token), token);
}
/// <summary>
/// Similar as UniTask.Yield but guaranteed run on next frame.
/// </summary>
public static UniTask NextFrame(CancellationToken cancellationToken)
public static UniTask NextFrame(CancellationToken cancellationToken, bool cancelImmediately = false)
{
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token);
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, cancellationToken, cancelImmediately, out var token), token);
}
/// <summary>
/// Similar as UniTask.Yield but guaranteed run on next frame.
/// </summary>
public static UniTask NextFrame(PlayerLoopTiming timing, CancellationToken cancellationToken)
public static UniTask NextFrame(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately = false)
{
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
return new UniTask(NextFramePromise.Create(timing, cancellationToken, cancelImmediately, out var token), token);
}
#if UNITY_2023_1_OR_NEWER
@@ -88,15 +88,21 @@ namespace Cysharp.Threading.Tasks
}
[Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")]
public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken)
public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken, bool cancelImmediately = false)
{
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken, cancelImmediately);
}
#endif
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default)
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner)
{
var source = WaitForEndOfFramePromise.Create(coroutineRunner, cancellationToken, out var token);
var source = WaitForEndOfFramePromise.Create(coroutineRunner, CancellationToken.None, false, out var token);
return new UniTask(source, token);
}
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, bool cancelImmediately = false)
{
var source = WaitForEndOfFramePromise.Create(coroutineRunner, cancellationToken, cancelImmediately, out var token);
return new UniTask(source, token);
}
@@ -113,50 +119,50 @@ namespace Cysharp.Threading.Tasks
/// <summary>
/// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken).
/// </summary>
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken)
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken, bool cancelImmediately = false)
{
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken);
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken, cancelImmediately);
}
public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken);
return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
}
public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken);
return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
}
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
if (delayFrameCount < 0)
{
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
}
return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, out var token), token);
return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken);
return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
}
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
var delayType = ignoreTimeScale ? DelayType.UnscaledDeltaTime : DelayType.DeltaTime;
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken, cancelImmediately);
}
public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken, cancelImmediately);
}
public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
if (delayTimeSpan < TimeSpan.Zero)
{
@@ -175,16 +181,16 @@ namespace Cysharp.Threading.Tasks
{
case DelayType.UnscaledDeltaTime:
{
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
}
case DelayType.Realtime:
{
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
}
case DelayType.DeltaTime:
default:
{
return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
}
}
}
@@ -201,13 +207,15 @@ namespace Cysharp.Threading.Tasks
}
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
YieldPromise()
{
}
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -219,8 +227,17 @@ namespace Cysharp.Threading.Tasks
result = new YieldPromise();
}
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (YieldPromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -238,7 +255,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -274,6 +298,8 @@ namespace Cysharp.Threading.Tasks
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -290,14 +316,16 @@ namespace Cysharp.Threading.Tasks
}
int frameCount;
CancellationToken cancellationToken;
UniTaskCompletionSourceCore<AsyncUnit> core;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
NextFramePromise()
{
}
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -311,6 +339,16 @@ namespace Cysharp.Threading.Tasks
result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (NextFramePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -328,7 +366,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -369,6 +414,7 @@ namespace Cysharp.Threading.Tasks
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
@@ -384,14 +430,16 @@ namespace Cysharp.Threading.Tasks
TaskPool.RegisterSizeGetter(typeof(WaitForEndOfFramePromise), () => pool.Size);
}
CancellationToken cancellationToken;
UniTaskCompletionSourceCore<object> core;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
WaitForEndOfFramePromise()
{
}
public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -404,6 +452,16 @@ namespace Cysharp.Threading.Tasks
}
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitForEndOfFramePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -421,7 +479,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -446,6 +511,7 @@ namespace Cysharp.Threading.Tasks
core.Reset();
Reset(); // Reset Enumerator
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
@@ -494,6 +560,8 @@ namespace Cysharp.Threading.Tasks
int initialFrame;
int delayFrameCount;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
int currentFrameCount;
UniTaskCompletionSourceCore<AsyncUnit> core;
@@ -502,7 +570,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -517,6 +585,16 @@ namespace Cysharp.Threading.Tasks
result.delayFrameCount = delayFrameCount;
result.cancellationToken = cancellationToken;
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (DelayFramePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -534,7 +612,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -604,6 +689,8 @@ namespace Cysharp.Threading.Tasks
currentFrameCount = default;
delayFrameCount = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -623,6 +710,8 @@ namespace Cysharp.Threading.Tasks
float delayTimeSpan;
float elapsed;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
@@ -630,7 +719,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -646,6 +735,16 @@ namespace Cysharp.Threading.Tasks
result.delayTimeSpan = (float)delayTimeSpan.TotalSeconds;
result.cancellationToken = cancellationToken;
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (DelayPromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -663,7 +762,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -715,6 +821,8 @@ namespace Cysharp.Threading.Tasks
delayTimeSpan = default;
elapsed = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -734,6 +842,8 @@ namespace Cysharp.Threading.Tasks
float elapsed;
int initialFrame;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
@@ -741,7 +851,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -757,6 +867,16 @@ namespace Cysharp.Threading.Tasks
result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (DelayIgnoreTimeScalePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -774,7 +894,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -826,6 +953,8 @@ namespace Cysharp.Threading.Tasks
delayFrameTimeSpan = default;
elapsed = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -844,6 +973,8 @@ namespace Cysharp.Threading.Tasks
long delayTimeSpanTicks;
ValueStopwatch stopwatch;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<AsyncUnit> core;
@@ -851,7 +982,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -866,6 +997,16 @@ namespace Cysharp.Threading.Tasks
result.stopwatch = ValueStopwatch.StartNew();
result.delayTimeSpanTicks = delayTimeSpan.Ticks;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (DelayRealtimePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -883,7 +1024,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -931,6 +1079,8 @@ namespace Cysharp.Threading.Tasks
core.Reset();
stopwatch = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}

View File

@@ -81,6 +81,16 @@ namespace Cysharp.Threading.Tasks
return factory();
}
public static UniTask Create(Func<CancellationToken, UniTask> factory, CancellationToken cancellationToken)
{
return factory(cancellationToken);
}
public static UniTask Create<T>(T state, Func<T, UniTask> factory)
{
return factory(state);
}
public static UniTask<T> Create<T>(Func<UniTask<T>> factory)
{
return factory();
@@ -137,11 +147,19 @@ namespace Cysharp.Threading.Tasks
return () => asyncAction(cancellationToken).Forget();
}
/// <summary>
/// helper of create add UniTaskVoid to delegate.
/// </summary>
public static Action Action<T>(T state, Func<T, UniTaskVoid> asyncAction)
{
return () => asyncAction(state).Forget();
}
#if UNITY_2018_3_OR_NEWER
/// <summary>
/// Create async void(UniTaskVoid) UnityAction.
/// For exampe: onClick.AddListener(UniTask.UnityAction(async () => { /* */ } ))
/// For example: onClick.AddListener(UniTask.UnityAction(async () => { /* */ } ))
/// </summary>
public static UnityEngine.Events.UnityAction UnityAction(Func<UniTaskVoid> asyncAction)
{
@@ -150,13 +168,22 @@ namespace Cysharp.Threading.Tasks
/// <summary>
/// Create async void(UniTaskVoid) UnityAction.
/// For exampe: onClick.AddListener(UniTask.UnityAction(FooAsync, this.GetCancellationTokenOnDestroy()))
/// For example: onClick.AddListener(UniTask.UnityAction(FooAsync, this.GetCancellationTokenOnDestroy()))
/// </summary>
public static UnityEngine.Events.UnityAction UnityAction(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
{
return () => asyncAction(cancellationToken).Forget();
}
/// <summary>
/// Create async void(UniTaskVoid) UnityAction.
/// For example: onClick.AddListener(UniTask.UnityAction(FooAsync, Argument))
/// </summary>
public static UnityEngine.Events.UnityAction UnityAction<T>(T state, Func<T, UniTaskVoid> asyncAction)
{
return () => asyncAction(state).Forget();
}
#endif
/// <summary>
@@ -175,6 +202,22 @@ namespace Cysharp.Threading.Tasks
return new UniTask<T>(new DeferPromise<T>(factory), 0);
}
/// <summary>
/// Defer the task creation just before call await.
/// </summary>
public static UniTask Defer<TState>(TState state, Func<TState, UniTask> factory)
{
return new UniTask(new DeferPromiseWithState<TState>(state, factory), 0);
}
/// <summary>
/// Defer the task creation just before call await.
/// </summary>
public static UniTask<TResult> Defer<TState, TResult>(TState state, Func<TState, UniTask<TResult>> factory)
{
return new UniTask<TResult>(new DeferPromiseWithState<TState, TResult>(state, factory), 0);
}
/// <summary>
/// Never complete.
/// </summary>
@@ -438,6 +481,93 @@ namespace Cysharp.Threading.Tasks
}
}
sealed class DeferPromiseWithState<TState> : IUniTaskSource
{
Func<TState, UniTask> factory;
TState argument;
UniTask task;
UniTask.Awaiter awaiter;
public DeferPromiseWithState(TState argument, Func<TState, UniTask> factory)
{
this.argument = argument;
this.factory = factory;
}
public void GetResult(short token)
{
awaiter.GetResult();
}
public UniTaskStatus GetStatus(short token)
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
task = f(argument);
awaiter = task.GetAwaiter();
}
return task.Status;
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
awaiter.SourceOnCompleted(continuation, state);
}
public UniTaskStatus UnsafeGetStatus()
{
return task.Status;
}
}
sealed class DeferPromiseWithState<TState, TResult> : IUniTaskSource<TResult>
{
Func<TState, UniTask<TResult>> factory;
TState argument;
UniTask<TResult> task;
UniTask<TResult>.Awaiter awaiter;
public DeferPromiseWithState(TState argument, Func<TState, UniTask<TResult>> factory)
{
this.argument = argument;
this.factory = factory;
}
public TResult GetResult(short token)
{
return awaiter.GetResult();
}
void IUniTaskSource.GetResult(short token)
{
awaiter.GetResult();
}
public UniTaskStatus GetStatus(short token)
{
var f = Interlocked.Exchange(ref factory, null);
if (f != null)
{
task = f(argument);
awaiter = task.GetAwaiter();
}
return task.Status;
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
awaiter.SourceOnCompleted(continuation, state);
}
public UniTaskStatus UnsafeGetStatus()
{
return task.Status;
}
}
sealed class NeverPromise<T> : IUniTaskSource<T>
{
static readonly Action<object> cancellationCallback = CancellationCallback;

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Threading;
using Cysharp.Threading.Tasks.Internal;
@@ -9,30 +10,40 @@ namespace Cysharp.Threading.Tasks
{
public partial struct UniTask
{
public static UniTask WaitUntil(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WaitUntil(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, out var token), token);
return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask WaitWhile(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WaitUntil<T>(T state, Func<T, bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, out var token), token);
return new UniTask(WaitUntilPromise<T>.Create(state, predicate, timing, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update)
public static UniTask WaitWhile(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, out var token), token);
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WaitWhile<T>(T state, Func<T, bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
return new UniTask(WaitWhilePromise<T>.Create(state, predicate, timing, cancellationToken, cancelImmediately, out var token), token);
}
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool completeImmediately = false)
{
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, completeImmediately, out var token), token);
}
public static UniTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
where T : class
{
var unityObject = target as UnityEngine.Object;
var isUnityObject = target is UnityEngine.Object; // don't use (unityObject == null)
return new UniTask<U>(isUnityObject
? WaitUntilValueChangedUnityObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token)
: WaitUntilValueChangedStandardObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out token), token);
? WaitUntilValueChangedUnityObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, cancelImmediately, out var token)
: WaitUntilValueChangedStandardObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, cancelImmediately, out token), token);
}
sealed class WaitUntilPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilPromise>
@@ -48,6 +59,8 @@ namespace Cysharp.Threading.Tasks
Func<bool> predicate;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
@@ -55,7 +68,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -69,6 +82,16 @@ namespace Cysharp.Threading.Tasks
result.predicate = predicate;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitUntilPromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -86,7 +109,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -136,31 +166,36 @@ namespace Cysharp.Threading.Tasks
core.Reset();
predicate = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
sealed class WaitWhilePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitWhilePromise>
sealed class WaitUntilPromise<T> : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilPromise<T>>
{
static TaskPool<WaitWhilePromise> pool;
WaitWhilePromise nextNode;
public ref WaitWhilePromise NextNode => ref nextNode;
static TaskPool<WaitUntilPromise<T>> pool;
WaitUntilPromise<T> nextNode;
public ref WaitUntilPromise<T> NextNode => ref nextNode;
static WaitWhilePromise()
static WaitUntilPromise()
{
TaskPool.RegisterSizeGetter(typeof(WaitWhilePromise), () => pool.Size);
TaskPool.RegisterSizeGetter(typeof(WaitUntilPromise<T>), () => pool.Size);
}
Func<bool> predicate;
Func<T, bool> predicate;
T argument;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
WaitWhilePromise()
WaitUntilPromise()
{
}
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(T argument, Func<T, bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -169,11 +204,22 @@ namespace Cysharp.Threading.Tasks
if (!pool.TryPop(out var result))
{
result = new WaitWhilePromise();
result = new WaitUntilPromise<T>();
}
result.predicate = predicate;
result.argument = argument;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitUntilPromise<T>)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -191,7 +237,141 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
return false;
}
try
{
if (!predicate(argument))
{
return true;
}
}
catch (Exception ex)
{
core.TrySetException(ex);
return false;
}
core.TrySetResult(null);
return false;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
predicate = default;
argument = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
sealed class WaitWhilePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitWhilePromise>
{
static TaskPool<WaitWhilePromise> pool;
WaitWhilePromise nextNode;
public ref WaitWhilePromise NextNode => ref nextNode;
static WaitWhilePromise()
{
TaskPool.RegisterSizeGetter(typeof(WaitWhilePromise), () => pool.Size);
}
Func<bool> predicate;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
WaitWhilePromise()
{
}
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitWhilePromise();
}
result.predicate = predicate;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitWhilePromise)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
return result;
}
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -241,30 +421,36 @@ namespace Cysharp.Threading.Tasks
core.Reset();
predicate = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
sealed class WaitUntilCanceledPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilCanceledPromise>
sealed class WaitWhilePromise<T> : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitWhilePromise<T>>
{
static TaskPool<WaitUntilCanceledPromise> pool;
WaitUntilCanceledPromise nextNode;
public ref WaitUntilCanceledPromise NextNode => ref nextNode;
static TaskPool<WaitWhilePromise<T>> pool;
WaitWhilePromise<T> nextNode;
public ref WaitWhilePromise<T> NextNode => ref nextNode;
static WaitUntilCanceledPromise()
static WaitWhilePromise()
{
TaskPool.RegisterSizeGetter(typeof(WaitUntilCanceledPromise), () => pool.Size);
TaskPool.RegisterSizeGetter(typeof(WaitWhilePromise<T>), () => pool.Size);
}
Func<T, bool> predicate;
T argument;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
WaitUntilCanceledPromise()
WaitWhilePromise()
{
}
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, out short token)
public static IUniTaskSource Create(T argument, Func<T, bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -273,10 +459,22 @@ namespace Cysharp.Threading.Tasks
if (!pool.TryPop(out var result))
{
result = new WaitUntilCanceledPromise();
result = new WaitWhilePromise<T>();
}
result.predicate = predicate;
result.argument = argument;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitWhilePromise<T>)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -294,7 +492,139 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
return false;
}
try
{
if (predicate(argument))
{
return true;
}
}
catch (Exception ex)
{
core.TrySetException(ex);
return false;
}
core.TrySetResult(null);
return false;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
predicate = default;
argument = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
sealed class WaitUntilCanceledPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilCanceledPromise>
{
static TaskPool<WaitUntilCanceledPromise> pool;
WaitUntilCanceledPromise nextNode;
public ref WaitUntilCanceledPromise NextNode => ref nextNode;
static WaitUntilCanceledPromise()
{
TaskPool.RegisterSizeGetter(typeof(WaitUntilCanceledPromise), () => pool.Size);
}
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<object> core;
WaitUntilCanceledPromise()
{
}
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitUntilCanceledPromise();
}
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitUntilCanceledPromise)state;
promise.core.TrySetResult(null);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
return result;
}
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -329,6 +659,8 @@ namespace Cysharp.Threading.Tasks
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -351,6 +683,8 @@ namespace Cysharp.Threading.Tasks
Func<T, U> monitorFunction;
IEqualityComparer<U> equalityComparer;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<U> core;
@@ -358,7 +692,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -376,6 +710,16 @@ namespace Cysharp.Threading.Tasks
result.currentValue = monitorFunction(target);
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitUntilValueChangedUnityObjectPromise<T, U>)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -393,7 +737,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -453,6 +804,8 @@ namespace Cysharp.Threading.Tasks
monitorFunction = default;
equalityComparer = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}
@@ -474,6 +827,8 @@ namespace Cysharp.Threading.Tasks
Func<T, U> monitorFunction;
IEqualityComparer<U> equalityComparer;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<U> core;
@@ -481,7 +836,7 @@ namespace Cysharp.Threading.Tasks
{
}
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -498,6 +853,16 @@ namespace Cysharp.Threading.Tasks
result.currentValue = monitorFunction(target);
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (WaitUntilValueChangedStandardObjectPromise<T, U>)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -515,7 +880,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -575,6 +947,8 @@ namespace Cysharp.Threading.Tasks
monitorFunction = default;
equalityComparer = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}

View File

@@ -1,6 +1,10 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable CS0436
#if UNITASK_NETCORE || UNITY_2022_3_OR_NEWER
#define SUPPORT_VALUETASK
#endif
using Cysharp.Threading.Tasks.CompilerServices;
using System;
using System.Diagnostics;
@@ -69,7 +73,7 @@ namespace Cysharp.Threading.Tasks
return new UniTask<bool>(new IsCanceledSource(source), token);
}
#if !UNITY_2018_3_OR_NEWER
#if SUPPORT_VALUETASK
public static implicit operator System.Threading.Tasks.ValueTask(in UniTask self)
{
@@ -78,7 +82,7 @@ namespace Cysharp.Threading.Tasks
return default;
}
#if NETSTANDARD2_0
#if (UNITASK_NETCORE && NETSTANDARD2_0)
return self.AsValueTask();
#else
return new System.Threading.Tasks.ValueTask(self.source, self.token);
@@ -118,7 +122,7 @@ namespace Cysharp.Threading.Tasks
this.source.GetResult(this.token);
return CompletedTasks.AsyncUnit;
}
else if(this.source is IUniTaskSource<AsyncUnit> asyncUnitSource)
else if (this.source is IUniTaskSource<AsyncUnit> asyncUnitSource)
{
return new UniTask<AsyncUnit>(asyncUnitSource, this.token);
}
@@ -440,7 +444,7 @@ namespace Cysharp.Threading.Tasks
return self.AsUniTask();
}
#if !UNITY_2018_3_OR_NEWER
#if SUPPORT_VALUETASK
public static implicit operator System.Threading.Tasks.ValueTask<T>(in UniTask<T> self)
{
@@ -449,7 +453,7 @@ namespace Cysharp.Threading.Tasks
return new System.Threading.Tasks.ValueTask<T>(self.result);
}
#if NETSTANDARD2_0
#if (UNITASK_NETCORE && NETSTANDARD2_0)
return self.AsValueTask();
#else
return new System.Threading.Tasks.ValueTask<T>(self.source, self.token);

View File

@@ -201,6 +201,7 @@ namespace Cysharp.Threading.Tasks
if (cancellationToken.IsCancellationRequested)
{
task.Forget();
return UniTask.FromCanceled(cancellationToken);
}
@@ -224,6 +225,7 @@ namespace Cysharp.Threading.Tasks
if (cancellationToken.IsCancellationRequested)
{
task.Forget();
return UniTask.FromCanceled<T>(cancellationToken);
}
@@ -454,7 +456,7 @@ namespace Cysharp.Threading.Tasks
}
/// <summary>
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled).
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCanceled).
/// </summary>
public static async UniTask<bool> TimeoutWithoutException(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
{

View File

@@ -24,12 +24,17 @@ namespace Cysharp.Threading.Tasks
return AwaitForAllAssets(asyncOperation, null, PlayerLoopTiming.Update, cancellationToken: cancellationToken);
}
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return AwaitForAllAssets(asyncOperation, progress: null, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object[]>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.allAssets);
return new UniTask<UnityEngine.Object[]>(AssetBundleRequestAllAssetsConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask<UnityEngine.Object[]>(AssetBundleRequestAllAssetsConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct AssetBundleRequestAllAssetsAwaiter : ICriticalNotifyCompletion
@@ -95,15 +100,20 @@ namespace Cysharp.Threading.Tasks
AssetBundleRequest asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<UnityEngine.Object[]> core;
Action<AsyncOperation> continuationAction;
AssetBundleRequestAllAssetsConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource<UnityEngine.Object[]> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<UnityEngine.Object[]> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -118,6 +128,19 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (AssetBundleRequestAllAssetsConfiguredSource)state;
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -135,7 +158,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -161,6 +191,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
@@ -188,8 +224,28 @@ namespace Cysharp.Threading.Tasks
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else
{
core.TrySetResult(asyncOperation.allAssets);
}
}
}
}
}

View File

@@ -20,12 +20,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask<AsyncGPUReadbackRequest> ToUniTask(this AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<AsyncGPUReadbackRequest> WithCancellation(this AsyncGPUReadbackRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
if (asyncOperation.done) return UniTask.FromResult(asyncOperation);
return new UniTask<AsyncGPUReadbackRequest>(AsyncGPUReadbackRequestAwaiterConfiguredSource.Create(asyncOperation, timing, cancellationToken, out var token), token);
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<AsyncGPUReadbackRequest> ToUniTask(this AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
if (asyncOperation.done) return UniTask.FromResult(asyncOperation);
return new UniTask<AsyncGPUReadbackRequest>(AsyncGPUReadbackRequestAwaiterConfiguredSource.Create(asyncOperation, timing, cancellationToken, cancelImmediately, out var token), token);
}
sealed class AsyncGPUReadbackRequestAwaiterConfiguredSource : IUniTaskSource<AsyncGPUReadbackRequest>, IPlayerLoopItem, ITaskPoolNode<AsyncGPUReadbackRequestAwaiterConfiguredSource>
{
static TaskPool<AsyncGPUReadbackRequestAwaiterConfiguredSource> pool;
@@ -39,15 +44,15 @@ namespace Cysharp.Threading.Tasks
AsyncGPUReadbackRequest asyncOperation;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
UniTaskCompletionSourceCore<AsyncGPUReadbackRequest> core;
AsyncGPUReadbackRequestAwaiterConfiguredSource()
{
}
public static IUniTaskSource<AsyncGPUReadbackRequest> Create(AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<AsyncGPUReadbackRequest> Create(AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -61,6 +66,16 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncGPUReadbackRequestAwaiterConfiguredSource)state;
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -78,7 +93,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -131,6 +153,8 @@ namespace Cysharp.Threading.Tasks
core.Reset();
asyncOperation = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
}

View File

@@ -17,7 +17,6 @@ namespace Cysharp.Threading.Tasks
#if !UNITY_2023_1_OR_NEWER
// from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine.
public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
@@ -30,12 +29,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
if (asyncOperation.isDone) return UniTask.CompletedTask;
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct AsyncOperationAwaiter : ICriticalNotifyCompletion
@@ -92,15 +96,20 @@ namespace Cysharp.Threading.Tasks
AsyncOperation asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<AsyncUnit> core;
Action<AsyncOperation> continuationAction;
AsyncOperationConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -115,6 +124,19 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (AsyncOperationConfiguredSource)state;
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -132,7 +154,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -154,6 +183,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
@@ -178,11 +213,31 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
}
}
#endregion
@@ -200,12 +255,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<UnityEngine.Object> WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct ResourceRequestAwaiter : ICriticalNotifyCompletion
@@ -266,15 +326,20 @@ namespace Cysharp.Threading.Tasks
ResourceRequest asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<UnityEngine.Object> core;
Action<AsyncOperation> continuationAction;
ResourceRequestConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -289,6 +354,19 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (ResourceRequestConfiguredSource)state;
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -306,7 +384,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -332,6 +417,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
@@ -356,11 +447,31 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else
{
core.TrySetResult(asyncOperation.asset);
}
}
}
#endregion
@@ -379,12 +490,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<UnityEngine.Object> WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion
@@ -445,15 +561,20 @@ namespace Cysharp.Threading.Tasks
AssetBundleRequest asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<UnityEngine.Object> core;
Action<AsyncOperation> continuationAction;
AssetBundleRequestConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -468,6 +589,19 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (AssetBundleRequestConfiguredSource)state;
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -485,7 +619,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -511,6 +652,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
@@ -535,11 +682,31 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else
{
core.TrySetResult(asyncOperation.asset);
}
}
}
#endregion
@@ -559,12 +726,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<AssetBundle> WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<AssetBundle>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle);
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion
@@ -625,15 +797,20 @@ namespace Cysharp.Threading.Tasks
AssetBundleCreateRequest asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<AssetBundle> core;
Action<AsyncOperation> continuationAction;
AssetBundleCreateRequestConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -648,6 +825,19 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (AssetBundleCreateRequestConfiguredSource)state;
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -665,7 +855,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -691,6 +888,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
@@ -715,11 +918,31 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else
{
core.TrySetResult(asyncOperation.assetBundle);
}
}
}
#endregion
@@ -739,7 +962,12 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask<UnityWebRequest> WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityWebRequest>(cancellationToken);
@@ -751,7 +979,7 @@ namespace Cysharp.Threading.Tasks
}
return UniTask.FromResult(asyncOperation.webRequest);
}
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion
@@ -820,15 +1048,20 @@ namespace Cysharp.Threading.Tasks
UnityWebRequestAsyncOperation asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<UnityWebRequest> core;
Action<AsyncOperation> continuationAction;
UnityWebRequestAsyncOperationConfiguredSource()
{
continuationAction = Continuation;
}
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -843,6 +1076,20 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (UnityWebRequestAsyncOperationConfiguredSource)state;
source.asyncOperation.webRequest.Abort();
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -860,7 +1107,14 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
@@ -886,6 +1140,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
asyncOperation.webRequest.Abort();
@@ -900,11 +1160,7 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone)
{
if (asyncOperation.webRequest == null)
{
core.TrySetException(new ObjectDisposedException("The webRequest has been destroyed."));
}
else if (asyncOperation.webRequest.IsError())
if (asyncOperation.webRequest.IsError())
{
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
}
@@ -922,11 +1178,35 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
else if (asyncOperation.webRequest.IsError())
{
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
}
else
{
core.TrySetResult(asyncOperation.webRequest);
}
}
}
#endregion

View File

@@ -16,6 +16,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> IsAsyncOperationBase = x => x.typeName == "AsyncOperation";
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";
@@ -43,18 +44,30 @@ namespace Cysharp.Threading.Tasks
<# } #>
#region <#= t.typeName #>
<# if (IsAsyncOperationBase(t)) { #>
#if !UNITY_2023_1_OR_NEWER
// from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine.
<# } #>
public static <#= t.typeName #>Awaiter GetAwaiter(this <#= t.typeName #> asyncOperation)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
return new <#= t.typeName #>Awaiter(asyncOperation);
}
<# if (IsAsyncOperationBase(t)) { #>
#endif
<# } #>
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
}
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
}
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<#= IsVoid(t) ? "" : "<" + t.returnType + ">" #>(cancellationToken);
@@ -70,7 +83,7 @@ namespace Cysharp.Threading.Tasks
<# } else { #>
if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>;
<# } #>
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
}
public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion
@@ -151,15 +164,20 @@ namespace Cysharp.Threading.Tasks
<#= t.typeName #> asyncOperation;
IProgress<float> progress;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<<#= IsVoid(t) ? "AsyncUnit" : t.returnType #>> core;
Action<AsyncOperation> continuationAction;
<#= t.typeName #>ConfiguredSource()
{
continuationAction = Continuation;
}
public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -174,6 +192,22 @@ namespace Cysharp.Threading.Tasks
result.asyncOperation = asyncOperation;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.completed = false;
asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var source = (<#= t.typeName #>ConfiguredSource)state;
<# if(IsUnityWebRequest(t)) { #>
source.asyncOperation.webRequest.Abort();
<# } #>
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
@@ -195,7 +229,10 @@ namespace Cysharp.Threading.Tasks
}
finally
{
TryReturn();
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
}
}
@@ -223,6 +260,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
// Already completed
if (completed || asyncOperation == null)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
<# if(IsUnityWebRequest(t)) { #>
@@ -261,11 +304,42 @@ namespace Cysharp.Threading.Tasks
{
TaskTracker.RemoveTracking(this);
core.Reset();
asyncOperation.completed -= continuationAction;
asyncOperation = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default;
return pool.TryPush(this);
}
void Continuation(AsyncOperation _)
{
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
}
<# if(IsUnityWebRequest(t)) { #>
else if (asyncOperation.webRequest.IsError())
{
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
}
else
{
core.TrySetResult(asyncOperation.webRequest);
}
<# } else { #>
else
{
core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>);
}
<# } #>
}
}
#endregion

View File

@@ -339,7 +339,7 @@ namespace Cysharp.Threading.Tasks
void InvokeCore(string item1, int item2, int item3)
{
innerEvent.Invoke(item1, item2, item3);
Invoke((item1, item2, item3));
}
public void Dispose()
@@ -855,4 +855,4 @@ namespace Cysharp.Threading.Tasks
}
}
#endif
#endif

View File

@@ -0,0 +1,17 @@
#if UNITY_2023_1_OR_NEWER
namespace Cysharp.Threading.Tasks
{
public static class UnityAwaitableExtensions
{
public static async UniTask AsUniTask(this UnityEngine.Awaitable awaitable)
{
await awaitable;
}
public static async UniTask<T> AsUniTask<T>(this UnityEngine.Awaitable<T> awaitable)
{
return await awaitable;
}
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c29533c9e4284dee914b71a6579ea274
timeCreated: 1698895807

View File

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

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 959c1472a5d812843bedf9341e87af3b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,133 +0,0 @@
#if UNITY_EDITOR
using System;
using UnityEngine;
namespace RuntimeUnitTestToolkit.Editor
{
// functional declarative construction like flutter.
internal interface IBuilder
{
GameObject GameObject { get; }
T GetComponent<T>();
}
internal class Builder<T> : IBuilder
where T : Component
{
public T Component1 { get; private set; }
public GameObject GameObject { get; private set; }
public Transform Transform { get { return GameObject.transform; } }
public RectTransform RectTransform { get { return GameObject.GetComponent<RectTransform>(); } }
public Action<GameObject> SetTarget
{
set
{
value(this.GameObject);
}
}
public IBuilder Child
{
set
{
value.GameObject.transform.SetParent(GameObject.transform);
}
}
public IBuilder[] Children
{
set
{
foreach (var item in value)
{
item.GameObject.transform.SetParent(GameObject.transform);
}
}
}
public Builder(string name)
{
this.GameObject = new GameObject(name);
this.Component1 = GameObject.AddComponent<T>();
}
public Builder(string name, out T referenceSelf) // out primary reference.
{
this.GameObject = new GameObject(name);
this.Component1 = GameObject.AddComponent<T>();
referenceSelf = this.Component1;
}
public TComponent GetComponent<TComponent>()
{
return this.GameObject.GetComponent<TComponent>();
}
}
internal class Builder<T1, T2> : Builder<T1>
where T1 : Component
where T2 : Component
{
public T2 Component2 { get; private set; }
public Builder(string name)
: base(name)
{
this.Component2 = GameObject.AddComponent<T2>();
}
public Builder(string name, out T1 referenceSelf)
: base(name, out referenceSelf)
{
this.Component2 = GameObject.AddComponent<T2>();
}
}
internal class Builder<T1, T2, T3> : Builder<T1, T2>
where T1 : Component
where T2 : Component
where T3 : Component
{
public T3 Component3 { get; private set; }
public Builder(string name)
: base(name)
{
this.Component3 = GameObject.AddComponent<T3>();
}
public Builder(string name, out T1 referenceSelf)
: base(name, out referenceSelf)
{
this.Component3 = GameObject.AddComponent<T3>();
}
}
internal class Builder<T1, T2, T3, T4> : Builder<T1, T2, T3>
where T1 : Component
where T2 : Component
where T3 : Component
where T4 : Component
{
public T4 Component4 { get; private set; }
public Builder(string name)
: base(name)
{
this.Component4 = GameObject.AddComponent<T4>();
}
public Builder(string name, out T1 referenceSelf)
: base(name, out referenceSelf)
{
this.Component4 = GameObject.AddComponent<T4>();
}
}
}
#endif

View File

@@ -1,345 +0,0 @@
#if UNITY_EDITOR
using UnityEditor;
// Settings MenuItems.
public static partial class UnitTestBuilder
{
[MenuItem("Test/Settings/ScriptBackend/Mono", validate = true, priority = 1)]
static bool ValidateScriptBackendMono()
{
Menu.SetChecked("Test/Settings/ScriptBackend/Mono", LoadOrGetDefaultSettings().ScriptBackend == ScriptingImplementation.Mono2x);
return true;
}
[MenuItem("Test/Settings/ScriptBackend/Mono", validate = false, priority = 1)]
static void ScriptBackendMono()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentScriptBackend = false;
settings.ScriptBackend = ScriptingImplementation.Mono2x;
SaveSettings(settings);
}
[MenuItem("Test/Settings/ScriptBackend/IL2CPP", validate = true, priority = 2)]
static bool ValidateScriptBackendIL2CPP()
{
Menu.SetChecked("Test/Settings/ScriptBackend/IL2CPP", LoadOrGetDefaultSettings().ScriptBackend == ScriptingImplementation.IL2CPP);
return true;
}
[MenuItem("Test/Settings/ScriptBackend/IL2CPP", validate = false, priority = 2)]
static void ScriptBackendIL2CPP()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentScriptBackend = false;
settings.ScriptBackend = ScriptingImplementation.IL2CPP;
SaveSettings(settings);
}
[MenuItem("Test/Settings/AutoRunPlayer", validate = true, priority = 3)]
static bool ValidateAutoRun()
{
Menu.SetChecked("Test/Settings/AutoRunPlayer", LoadOrGetDefaultSettings().AutoRunPlayer);
return true;
}
[MenuItem("Test/Settings/AutoRunPlayer", validate = false, priority = 3)]
static void AutoRun()
{
var settings = LoadOrGetDefaultSettings();
settings.AutoRunPlayer = !settings.AutoRunPlayer;
SaveSettings(settings);
}
[MenuItem("Test/Settings/Headless", validate = true, priority = 4)]
static bool ValidateHeadless()
{
Menu.SetChecked("Test/Settings/Headless", LoadOrGetDefaultSettings().Headless);
return true;
}
[MenuItem("Test/Settings/Headless", validate = false, priority = 4)]
static void Headless()
{
var settings = LoadOrGetDefaultSettings();
settings.Headless = !settings.Headless;
SaveSettings(settings);
}
[MenuItem("Test/Settings/DisableAutoClose", validate = true, priority = 5)]
static bool ValidateDisableAutoClose()
{
Menu.SetChecked("Test/Settings/DisableAutoClose", LoadOrGetDefaultSettings().DisableAutoClose);
return true;
}
[MenuItem("Test/Settings/DisableAutoClose", validate = false, priority = 5)]
static void DisableAutoClose()
{
var settings = LoadOrGetDefaultSettings();
settings.DisableAutoClose = !settings.DisableAutoClose;
SaveSettings(settings);
}
// generated
/*
*
void Main()
{
var sb = new StringBuilder();
var p = 1;
foreach (var target in Enum.GetNames(typeof(BuildTarget)))
{
var path = $"Test/Settings/BuildTarget/{target}";
var priority = p++;
var template = $@"
[MenuItem(""{path}"", validate = true, priority = {priority})]
static bool ValidateBuildTarget{target}()
{{
Menu.SetChecked(""{path}"", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.{target});
return true;
}}
[MenuItem(""{path}"", validate = false, priority = {priority})]
static void BuildTarget{target}()
{{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.{target};
SaveSettings(settings);
}}";
sb.AppendLine(template);
}
sb.ToString().Dump();
}
public enum BuildTarget
{
StandaloneWindows,
StandaloneWindows64,
StandaloneLinux,
StandaloneLinux64,
StandaloneOSX,
WebGL,
iOS,
Android,
WSAPlayer,
PS4,
XboxOne,
Switch,
}
*/
[MenuItem("Test/Settings/BuildTarget/StandaloneWindows", validate = true, priority = 1)]
static bool ValidateBuildTargetStandaloneWindows()
{
Menu.SetChecked("Test/Settings/BuildTarget/StandaloneWindows", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.StandaloneWindows);
return true;
}
[MenuItem("Test/Settings/BuildTarget/StandaloneWindows", validate = false, priority = 1)]
static void BuildTargetStandaloneWindows()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.StandaloneWindows;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/StandaloneWindows64", validate = true, priority = 2)]
static bool ValidateBuildTargetStandaloneWindows64()
{
Menu.SetChecked("Test/Settings/BuildTarget/StandaloneWindows64", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.StandaloneWindows64);
return true;
}
[MenuItem("Test/Settings/BuildTarget/StandaloneWindows64", validate = false, priority = 2)]
static void BuildTargetStandaloneWindows64()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.StandaloneWindows64;
SaveSettings(settings);
}
#if !UNITY_2019_2_OR_NEWER
[MenuItem("Test/Settings/BuildTarget/StandaloneLinux", validate = true, priority = 3)]
static bool ValidateBuildTargetStandaloneLinux()
{
Menu.SetChecked("Test/Settings/BuildTarget/StandaloneLinux", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.StandaloneLinux);
return true;
}
[MenuItem("Test/Settings/BuildTarget/StandaloneLinux", validate = false, priority = 3)]
static void BuildTargetStandaloneLinux()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.StandaloneLinux;
SaveSettings(settings);
}
#endif
[MenuItem("Test/Settings/BuildTarget/StandaloneLinux64", validate = true, priority = 4)]
static bool ValidateBuildTargetStandaloneLinux64()
{
Menu.SetChecked("Test/Settings/BuildTarget/StandaloneLinux64", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.StandaloneLinux64);
return true;
}
[MenuItem("Test/Settings/BuildTarget/StandaloneLinux64", validate = false, priority = 4)]
static void BuildTargetStandaloneLinux64()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.StandaloneLinux64;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/StandaloneOSX", validate = true, priority = 5)]
static bool ValidateBuildTargetStandaloneOSX()
{
Menu.SetChecked("Test/Settings/BuildTarget/StandaloneOSX", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.StandaloneOSX);
return true;
}
[MenuItem("Test/Settings/BuildTarget/StandaloneOSX", validate = false, priority = 5)]
static void BuildTargetStandaloneOSX()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.StandaloneOSX;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/WebGL", validate = true, priority = 6)]
static bool ValidateBuildTargetWebGL()
{
Menu.SetChecked("Test/Settings/BuildTarget/WebGL", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.WebGL);
return true;
}
[MenuItem("Test/Settings/BuildTarget/WebGL", validate = false, priority = 6)]
static void BuildTargetWebGL()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.WebGL;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/iOS", validate = true, priority = 7)]
static bool ValidateBuildTargetiOS()
{
Menu.SetChecked("Test/Settings/BuildTarget/iOS", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.iOS);
return true;
}
[MenuItem("Test/Settings/BuildTarget/iOS", validate = false, priority = 7)]
static void BuildTargetiOS()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.iOS;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/Android", validate = true, priority = 8)]
static bool ValidateBuildTargetAndroid()
{
Menu.SetChecked("Test/Settings/BuildTarget/Android", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.Android);
return true;
}
[MenuItem("Test/Settings/BuildTarget/Android", validate = false, priority = 8)]
static void BuildTargetAndroid()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.Android;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/WSAPlayer", validate = true, priority = 9)]
static bool ValidateBuildTargetWSAPlayer()
{
Menu.SetChecked("Test/Settings/BuildTarget/WSAPlayer", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.WSAPlayer);
return true;
}
[MenuItem("Test/Settings/BuildTarget/WSAPlayer", validate = false, priority = 9)]
static void BuildTargetWSAPlayer()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.WSAPlayer;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/PS4", validate = true, priority = 10)]
static bool ValidateBuildTargetPS4()
{
Menu.SetChecked("Test/Settings/BuildTarget/PS4", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.PS4);
return true;
}
[MenuItem("Test/Settings/BuildTarget/PS4", validate = false, priority = 10)]
static void BuildTargetPS4()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.PS4;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/XboxOne", validate = true, priority = 11)]
static bool ValidateBuildTargetXboxOne()
{
Menu.SetChecked("Test/Settings/BuildTarget/XboxOne", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.XboxOne);
return true;
}
[MenuItem("Test/Settings/BuildTarget/XboxOne", validate = false, priority = 11)]
static void BuildTargetXboxOne()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.XboxOne;
SaveSettings(settings);
}
[MenuItem("Test/Settings/BuildTarget/Switch", validate = true, priority = 12)]
static bool ValidateBuildTargetSwitch()
{
Menu.SetChecked("Test/Settings/BuildTarget/Switch", LoadOrGetDefaultSettings().BuildTarget == BuildTarget.Switch);
return true;
}
[MenuItem("Test/Settings/BuildTarget/Switch", validate = false, priority = 12)]
static void BuildTargetSwitch()
{
var settings = LoadOrGetDefaultSettings();
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = BuildTarget.Switch;
SaveSettings(settings);
}
}
#endif

View File

@@ -1,546 +0,0 @@
#if UNITY_EDITOR
using RuntimeUnitTestToolkit;
using RuntimeUnitTestToolkit.Editor;
using System;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
internal class RuntimeUnitTestSettings
{
public ScriptingImplementation ScriptBackend;
public bool UseCurrentScriptBackend;
public BuildTarget BuildTarget;
public bool UseCurrentBuildTarget;
public bool Headless;
public bool AutoRunPlayer;
public bool DisableAutoClose;
public RuntimeUnitTestSettings()
{
UseCurrentBuildTarget = true;
UseCurrentScriptBackend = true;
Headless = false;
AutoRunPlayer = true;
DisableAutoClose = false;
}
public override string ToString()
{
return $"{ScriptBackend} {BuildTarget} Headless:{Headless} AutoRunPlayer:{AutoRunPlayer} DisableAutoClose:{DisableAutoClose}";
}
}
// no namespace(because invoke from commandline)
public static partial class UnitTestBuilder
{
const string SettingsKeyBase = "RuntimeUnitTest.Settings.";
[MenuItem("Test/BuildUnitTest")]
public static void BuildUnitTest()
{
var settings = new RuntimeUnitTestSettings(); // default
string buildPath = null;
if (Application.isBatchMode) // from commandline
{
settings.AutoRunPlayer = false;
settings.DisableAutoClose = false;
var cmdArgs = Environment.GetCommandLineArgs();
for (int i = 0; i < cmdArgs.Length; i++)
{
if (string.Equals(cmdArgs[i].Trim('-', '/'), "ScriptBackend", StringComparison.OrdinalIgnoreCase))
{
settings.UseCurrentScriptBackend = false;
var str = cmdArgs[++i];
if (str.StartsWith("mono", StringComparison.OrdinalIgnoreCase))
{
settings.ScriptBackend = ScriptingImplementation.Mono2x;
}
else if (str.StartsWith("IL2CPP", StringComparison.OrdinalIgnoreCase))
{
settings.ScriptBackend = ScriptingImplementation.IL2CPP;
}
else
{
settings.ScriptBackend = (ScriptingImplementation)Enum.Parse(typeof(ScriptingImplementation), str, true);
}
}
else if (string.Equals(cmdArgs[i].Trim('-', '/'), "BuildTarget", StringComparison.OrdinalIgnoreCase))
{
settings.UseCurrentBuildTarget = false;
settings.BuildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), cmdArgs[++i], true);
}
else if (string.Equals(cmdArgs[i].Trim('-', '/'), "Headless", StringComparison.OrdinalIgnoreCase))
{
settings.Headless = true;
}
else if (string.Equals(cmdArgs[i].Trim('-', '/'), "buildPath", StringComparison.OrdinalIgnoreCase))
{
buildPath = cmdArgs[++i];
}
}
}
else
{
var key = SettingsKeyBase + Application.productName;
var settingsValue = EditorPrefs.GetString(key, null);
try
{
if (!string.IsNullOrWhiteSpace(settingsValue))
{
settings = JsonUtility.FromJson<RuntimeUnitTestSettings>(settingsValue);
}
}
catch
{
UnityEngine.Debug.LogError("Fail to load RuntimeUnitTest settings");
EditorPrefs.SetString(key, null);
}
}
if (settings.UseCurrentBuildTarget)
{
settings.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
}
if (settings.UseCurrentScriptBackend)
{
settings.ScriptBackend = PlayerSettings.GetScriptingBackend(ToBuildTargetGroup(settings.BuildTarget));
}
if (buildPath == null)
{
buildPath = $"bin/UnitTest/{settings.BuildTarget}_{settings.ScriptBackend}/test" + GetExtensionForBuildTarget(settings.BuildTarget);
}
var originalScene = SceneManager.GetActiveScene().path;
BuildUnitTest(buildPath, settings.ScriptBackend, settings.BuildTarget, settings.Headless, settings.AutoRunPlayer, settings.DisableAutoClose);
// reopen original scene
if (!string.IsNullOrWhiteSpace(originalScene))
{
EditorSceneManager.OpenScene(originalScene, OpenSceneMode.Single);
}
else
{
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
}
}
[MenuItem("Test/LoadUnitTestScene")]
public static void LoadUnitTestScene()
{
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
BuildUnitTestRunnerScene();
EditorSceneManager.MarkSceneDirty(scene);
}
static RuntimeUnitTestSettings LoadOrGetDefaultSettings()
{
var key = SettingsKeyBase + Application.productName;
var settingsValue = EditorPrefs.GetString(key, null);
RuntimeUnitTestSettings settings = null;
try
{
if (!string.IsNullOrWhiteSpace(settingsValue))
{
settings = JsonUtility.FromJson<RuntimeUnitTestSettings>(settingsValue);
}
}
catch
{
UnityEngine.Debug.LogError("Fail to load RuntimeUnitTest settings");
EditorPrefs.SetString(key, null);
settings = null;
}
if (settings == null)
{
// default
settings = new RuntimeUnitTestSettings
{
UseCurrentBuildTarget = true,
UseCurrentScriptBackend = true,
Headless = false,
AutoRunPlayer = true,
};
}
return settings;
}
static void SaveSettings(RuntimeUnitTestSettings settings)
{
var key = SettingsKeyBase + Application.productName;
EditorPrefs.SetString(key, JsonUtility.ToJson(settings));
}
public static void BuildUnitTest(string buildPath, ScriptingImplementation scriptBackend, BuildTarget buildTarget, bool headless, bool autoRunPlayer, bool disableAutoClose)
{
var sceneName = "Assets/TempRuntimeUnitTestScene_" + DateTimeOffset.UtcNow.ToUnixTimeSeconds();
if (disableAutoClose)
{
sceneName += "_DisableAutoClose";
}
sceneName += ".unity";
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
BuildUnitTestRunnerScene();
EditorSceneManager.MarkSceneDirty(scene);
AssetDatabase.SaveAssets();
EditorSceneManager.SaveScene(scene, sceneName, false);
try
{
Build(sceneName, buildPath, new RuntimeUnitTestSettings { ScriptBackend = scriptBackend, BuildTarget = buildTarget, Headless = headless, AutoRunPlayer = autoRunPlayer, DisableAutoClose = disableAutoClose });
}
finally
{
AssetDatabase.DeleteAsset(sceneName);
}
}
public static UnitTestRunner BuildUnitTestRunnerScene()
{
const string kStandardSpritePath = "UI/Skin/UISprite.psd";
const string kBackgroundSpritePath = "UI/Skin/Background.psd";
var uisprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
var background = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpritePath);
ScrollRect buttonList;
VerticalLayoutGroup listLayout;
Scrollbar refListScrollbar;
ScrollRect logList;
Scrollbar refLogScrollbar;
Button clearButton;
Text logText;
// Flutter like coded build utility
var rootObject = new Builder<Camera>("SceneRoot")
{
Children = new IBuilder[] {
new Builder<EventSystem, StandaloneInputModule>("EventSystem"),
new Builder<Canvas, CanvasScaler, GraphicRaycaster>("Canvas") {
Component1 = { renderMode = RenderMode.ScreenSpaceOverlay },
Children = new IBuilder[] {
new Builder<HorizontalLayoutGroup, CanvasRenderer>("HorizontalSplitter") {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1) },
Component1 = { childControlWidth = true, childControlHeight = true, spacing = 10 },
Children = new IBuilder[] {
new Builder<ScrollRect, CanvasRenderer>("ButtonList", out buttonList) {
RectTransform = { pivot = new Vector2(0.5f, 0.5f) },
Component1 = { horizontal =false, vertical = true, movementType = ScrollRect.MovementType.Clamped },
Children = new IBuilder[] {
new Builder<VerticalLayoutGroup, ContentSizeFitter>("ListLayoutToAttach", out listLayout) {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1), pivot = new Vector2(0, 1) },
Component1 = { childControlWidth = true, childControlHeight = true, childForceExpandWidth = true, childForceExpandHeight = false, spacing = 10, padding = new RectOffset(10,20,10,10) },
Component2 = { horizontalFit = ContentSizeFitter.FitMode.Unconstrained, verticalFit = ContentSizeFitter.FitMode.PreferredSize },
SetTarget = self => { buttonList.content = self.GetComponent<RectTransform>(); },
Child = new Builder<Button, Image, LayoutElement>("ClearButton", out clearButton) {
Component2 = { sprite = uisprite, type = Image.Type.Sliced },
Component3 = { minHeight = 50 },
SetTarget = self => { self.GetComponent<Button>().targetGraphic = self.GetComponent<Graphic>(); },
Child = new Builder<Text>("ButtonText") {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1), pivot = new Vector2(0.5f, 0.5f) },
Component1 = { text = "Clear", color = FromRGB(50, 50, 50), alignment = TextAnchor.MiddleCenter, fontSize = 24, lineSpacing = 1 }
}
}
},
new Builder<Scrollbar,Image>("ListScrollbar", out refListScrollbar) {
RectTransform = { anchorMin = new Vector2(1, 0), anchorMax = new Vector2(1, 1) },
Component1 = { navigation = new Navigation{ mode = Navigation.Mode.None }, direction = Scrollbar.Direction.BottomToTop, size = 1.0f },
Component2 = { sprite = background, type = Image.Type.Sliced },
SetTarget = self => { buttonList.verticalScrollbar = self.GetComponent<Scrollbar>(); },
Child = new Builder<RectTransform>("Sliding Area") {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1) },
Child = new Builder<Image>("Handle") {
Component1 = { sprite = uisprite, type = Image.Type.Sliced },
SetTarget = self =>
{
refListScrollbar.targetGraphic = self.GetComponent<Graphic>();
refListScrollbar.handleRect = self.GetComponent<RectTransform>();
}
}
}
}
}
},
new Builder<ScrollRect, CanvasRenderer>("ScrollableText", out logList) {
RectTransform = { pivot = new Vector2(0.5f, 0.5f) },
Component1 = { horizontal =false, vertical = true, movementType = ScrollRect.MovementType.Elastic, elasticity = 0.1f },
Children = new IBuilder[] {
new Builder<Text, ContentSizeFitter>("Log", out logText) {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1), pivot = new Vector2(0, 1) },
Component1 = { fontSize = 24, lineSpacing = 1, supportRichText = true, alignment = TextAnchor.UpperLeft, horizontalOverflow = HorizontalWrapMode.Wrap, verticalOverflow = VerticalWrapMode.Truncate },
Component2 = { horizontalFit = ContentSizeFitter.FitMode.Unconstrained, verticalFit = ContentSizeFitter.FitMode.PreferredSize },
SetTarget = self => { logList.content = self.GetComponent<RectTransform>(); }
},
new Builder<Scrollbar,Image>("LogScrollbar", out refLogScrollbar) {
RectTransform = { anchorMin = new Vector2(1, 0), anchorMax = new Vector2(1, 1) },
Component1 = { navigation = new Navigation{ mode = Navigation.Mode.None }, direction = Scrollbar.Direction.BottomToTop, size = 1.0f },
Component2 = { sprite = background, type = Image.Type.Sliced },
SetTarget = self => { logList.verticalScrollbar = self.GetComponent<Scrollbar>(); },
Child = new Builder<RectTransform>("Sliding Area2") {
RectTransform = { anchorMin = new Vector2(0, 0), anchorMax = new Vector2(1, 1) },
Child = new Builder<Image>("Handle2") {
Component1 = { sprite = uisprite, type = Image.Type.Sliced },
SetTarget = self =>
{
refLogScrollbar.targetGraphic = self.GetComponent<Graphic>();
refLogScrollbar.handleRect = self.GetComponent<RectTransform>();
}
}
}
}
}
},
}
}
}
}
}
};
// size modify after build complete:)
{
var rect = GameObject.Find("HorizontalSplitter").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
}
{
var rect = GameObject.Find("ListLayoutToAttach").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
}
{
var rect = GameObject.Find("ListScrollbar").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(30, 0);
}
{
var rect = GameObject.Find("ClearButton").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
}
{
var rect = GameObject.Find("Sliding Area").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(-20, -20);
}
{
var rect = GameObject.Find("Handle").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(20, 20);
}
{
var rect = GameObject.Find("ButtonText").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
}
{
var rect = GameObject.Find("Log").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(15, 0);
rect.offsetMax = new Vector2(-20, 0);
}
{
var rect = GameObject.Find("LogScrollbar").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(-30, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(30, 0);
}
{
var rect = GameObject.Find("Sliding Area2").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(-20, -20);
}
{
var rect = GameObject.Find("Handle2").GetComponent<RectTransform>();
rect.offsetMin = new Vector2(0, 0);
rect.offsetMax = new Vector2(0, 0);
rect.sizeDelta = new Vector2(20, 20);
}
// add test script
var runner = rootObject.GameObject.AddComponent<UnitTestRunner>();
runner.clearButton = clearButton;
runner.list = listLayout.gameObject.GetComponent<RectTransform>();
runner.listScrollBar = refListScrollbar;
runner.logText = logText;
runner.logScrollBar = refLogScrollbar;
return runner;
}
static void Build(string sceneName, string buildPath, RuntimeUnitTestSettings settings)
{
var options = BuildOptions.BuildScriptsOnly | BuildOptions.IncludeTestAssemblies;
if (settings.AutoRunPlayer)
{
options |= BuildOptions.AutoRunPlayer;
}
if (settings.Headless)
{
options |= BuildOptions.EnableHeadlessMode;
}
var targetGroup = ToBuildTargetGroup(settings.BuildTarget);
var currentBackend = PlayerSettings.GetScriptingBackend(targetGroup);
if (currentBackend != settings.ScriptBackend)
{
UnityEngine.Debug.Log("Modify ScriptBackend to " + settings.ScriptBackend);
PlayerSettings.SetScriptingBackend(targetGroup, settings.ScriptBackend);
}
var buildOptions = new BuildPlayerOptions
{
target = settings.BuildTarget,
targetGroup = targetGroup,
options = options,
scenes = new[] { sceneName },
locationPathName = buildPath
};
UnityEngine.Debug.Log("UnitTest Build Start, " + settings.ToString());
var buildReport = BuildPipeline.BuildPlayer(buildOptions);
if (currentBackend != settings.ScriptBackend)
{
UnityEngine.Debug.Log("Restore ScriptBackend to " + currentBackend);
PlayerSettings.SetScriptingBackend(targetGroup, currentBackend);
}
if (buildReport.summary.result != BuildResult.Succeeded)
{
// Note: show error summary?
// Debug.LogError(buildReport.SummarizeErrors());
UnityEngine.Debug.LogError("UnitTest Build Failed.");
}
else
{
UnityEngine.Debug.Log("UnitTest Build Completed, binary located: " + buildOptions.locationPathName);
}
}
static Color FromRGB(int r, int g, int b)
{
return new Color(r / 255f, g / 255f, b / 255f);
}
static bool IsWindows(BuildTarget buildTarget)
{
switch (buildTarget)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
case BuildTarget.WSAPlayer:
return true;
default:
return false;
}
}
static string GetExtensionForBuildTarget(BuildTarget buildTarget)
{
switch (buildTarget)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
case BuildTarget.WSAPlayer:
return ".exe";
case BuildTarget.StandaloneOSX:
return ".app";
case BuildTarget.Android:
return ".apk";
default:
return "";
}
}
static BuildTargetGroup ToBuildTargetGroup(BuildTarget buildTarget)
{
#pragma warning disable CS0618
switch (buildTarget)
{
#if UNITY_2017_3_OR_NEWER
case BuildTarget.StandaloneOSX:
#else
case BuildTarget.StandaloneOSXIntel:
case BuildTarget.StandaloneOSXIntel64:
case BuildTarget.StandaloneOSXUniversal:
#endif // UNITY_2017_3_OR_NEWER
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
case BuildTarget.StandaloneLinux64:
#if !UNITY_2019_2_OR_NEWER
case BuildTarget.StandaloneLinux:
case BuildTarget.StandaloneLinuxUniversal:
#endif // !UNITY_2019_2_OR_NEWER
return BuildTargetGroup.Standalone;
case (BuildTarget)6:
case (BuildTarget)7:
case BuildTarget.WebGL:
return BuildTargetGroup.WebGL;
case BuildTarget.iOS:
return BuildTargetGroup.iOS;
case BuildTarget.PS3:
return BuildTargetGroup.PS3;
case BuildTarget.PS4:
return BuildTargetGroup.PS4;
case BuildTarget.XBOX360:
return BuildTargetGroup.XBOX360;
case BuildTarget.Android:
return BuildTargetGroup.Android;
case BuildTarget.WSAPlayer:
return BuildTargetGroup.WSA;
case BuildTarget.WP8Player:
return BuildTargetGroup.WP8;
case BuildTarget.Tizen:
return BuildTargetGroup.Tizen;
case BuildTarget.PSP2:
return BuildTargetGroup.PSP2;
case BuildTarget.PSM:
return BuildTargetGroup.PSM;
case BuildTarget.XboxOne:
return BuildTargetGroup.XboxOne;
case BuildTarget.SamsungTV:
return BuildTargetGroup.SamsungTV;
case BuildTarget.N3DS:
return BuildTargetGroup.N3DS;
case BuildTarget.WiiU:
return BuildTargetGroup.WiiU;
case BuildTarget.tvOS:
return BuildTargetGroup.tvOS;
case BuildTarget.Switch:
return BuildTargetGroup.Switch;
case BuildTarget.Lumin:
return BuildTargetGroup.Lumin;
case BuildTarget.BlackBerry:
return BuildTargetGroup.BlackBerry;
case BuildTarget.NoTarget:
default:
return BuildTargetGroup.Unknown;
}
#pragma warning restore CS0618
}
}
#endif

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 3518da33b6245d341a0ef3670ee9268b
timeCreated: 1488689723
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,16 +0,0 @@
{
"name": "RuntimeUnitTestToolkit",
"references": [
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 14c4fea4b238088479114ba2ffe195f9
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,684 +0,0 @@
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.TestTools;
using UnityEngine.UI;
namespace RuntimeUnitTestToolkit
{
public class UnitTestRunner : MonoBehaviour
{
// object is IEnumerator or Func<IEnumerator>
Dictionary<string, List<TestKeyValuePair>> tests = new Dictionary<string, List<TestKeyValuePair>>();
List<Pair> additionalActionsOnFirst = new List<Pair>();
public Button clearButton;
public RectTransform list;
public Scrollbar listScrollBar;
public Text logText;
public Scrollbar logScrollBar;
readonly Color passColor = new Color(0f, 1f, 0f, 1f); // green
readonly Color failColor = new Color(1f, 0f, 0f, 1f); // red
readonly Color normalColor = new Color(1f, 1f, 1f, 1f); // white
bool allTestGreen = true;
bool logClear = false;
void Start()
{
try
{
UnityEngine.Application.logMessageReceived += (a, b, c) =>
{
if (a.Contains("Mesh can not have more than 65000 vertices"))
{
logClear = true;
}
else
{
AppendToGraphicText("[" + c + "]" + a + "\n");
WriteToConsole("[" + c + "]" + a);
}
};
// register all test types
foreach (var item in GetTestTargetTypes())
{
RegisterAllMethods(item);
}
var executeAll = new List<Func<Coroutine>>();
foreach (var ___item in tests)
{
var actionList = ___item; // be careful, capture in lambda
executeAll.Add(() => StartCoroutine(RunTestInCoroutine(actionList)));
Add(actionList.Key, () => StartCoroutine(RunTestInCoroutine(actionList)));
}
var executeAllButton = Add("Run All Tests", () => StartCoroutine(ExecuteAllInCoroutine(executeAll)));
clearButton.gameObject.GetComponent<Image>().color = new Color(170 / 255f, 170 / 255f, 170 / 255f, 1);
executeAllButton.gameObject.GetComponent<Image>().color = new Color(250 / 255f, 150 / 255f, 150 / 255f, 1);
executeAllButton.transform.SetSiblingIndex(1);
additionalActionsOnFirst.Reverse();
foreach (var item in additionalActionsOnFirst)
{
var newButton = GameObject.Instantiate(clearButton);
newButton.name = item.Name;
newButton.onClick.RemoveAllListeners();
newButton.GetComponentInChildren<Text>().text = item.Name;
newButton.onClick.AddListener(item.Action);
newButton.transform.SetParent(list);
newButton.transform.SetSiblingIndex(1);
}
clearButton.onClick.AddListener(() =>
{
logText.text = "";
foreach (var btn in list.GetComponentsInChildren<Button>())
{
btn.interactable = true;
btn.GetComponent<Image>().color = normalColor;
}
executeAllButton.gameObject.GetComponent<Image>().color = new Color(250 / 255f, 150 / 255f, 150 / 255f, 1);
});
listScrollBar.value = 1;
logScrollBar.value = 1;
if (Application.isBatchMode)
{
// run immediately in player
StartCoroutine(ExecuteAllInCoroutine(executeAll));
}
}
catch (Exception ex)
{
if (Application.isBatchMode)
{
// when failed(can not start runner), quit immediately.
WriteToConsole(ex.ToString());
Application.Quit(1);
}
else
{
throw;
}
}
}
Button Add(string title, UnityAction test)
{
var newButton = GameObject.Instantiate(clearButton);
newButton.name = title;
newButton.onClick.RemoveAllListeners();
newButton.GetComponentInChildren<Text>().text = title;
newButton.onClick.AddListener(test);
newButton.transform.SetParent(list);
return newButton;
}
static IEnumerable<Type> GetTestTargetTypes()
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var n = assembly.FullName;
if (n.StartsWith("UnityEngine")) continue;
if (n.StartsWith("mscorlib")) continue;
if (n.StartsWith("System")) continue;
foreach (var item in assembly.GetTypes())
{
foreach (var method in item.GetMethods())
{
TestAttribute t1 = null;
try
{
t1 = method.GetCustomAttribute<TestAttribute>(true);
}
catch (Exception ex)
{
Debug.Log("TestAttribute Load Fail, Assembly:" + assembly.FullName);
Debug.LogException(ex);
goto NEXT_ASSEMBLY;
}
if (t1 != null)
{
yield return item;
break;
}
UnityTestAttribute t2 = null;
try
{
t2 = method.GetCustomAttribute<UnityTestAttribute>(true);
}
catch (Exception ex)
{
Debug.Log("UnityTestAttribute Load Fail, Assembly:" + assembly.FullName);
Debug.LogException(ex);
goto NEXT_ASSEMBLY;
}
if (t2 != null)
{
yield return item;
break;
}
}
}
NEXT_ASSEMBLY:
continue;
}
}
public void AddTest(string group, string title, Action test, List<Action> setups, List<Action> teardowns)
{
List<TestKeyValuePair> list;
if (!tests.TryGetValue(group, out list))
{
list = new List<TestKeyValuePair>();
tests[group] = list;
}
list.Add(new TestKeyValuePair(title, test, setups, teardowns));
}
public void AddAsyncTest(string group, string title, Func<IEnumerator> asyncTestCoroutine, List<Action> setups, List<Action> teardowns)
{
List<TestKeyValuePair> list;
if (!tests.TryGetValue(group, out list))
{
list = new List<TestKeyValuePair>();
tests[group] = list;
}
list.Add(new TestKeyValuePair(title, asyncTestCoroutine, setups, teardowns));
}
public void AddCutomAction(string name, UnityAction action)
{
additionalActionsOnFirst.Add(new Pair { Name = name, Action = action });
}
public void RegisterAllMethods<T>()
where T : new()
{
RegisterAllMethods(typeof(T));
}
public void RegisterAllMethods(Type testType)
{
try
{
var test = Activator.CreateInstance(testType);
var methods = testType.GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
List<Action> setups = new List<Action>();
List<Action> teardowns = new List<Action>();
foreach (var item in methods)
{
try
{
var setup = item.GetCustomAttribute<NUnit.Framework.SetUpAttribute>(true);
if (setup != null)
{
setups.Add((Action)Delegate.CreateDelegate(typeof(Action), test, item));
}
var teardown = item.GetCustomAttribute<NUnit.Framework.TearDownAttribute>(true);
if (teardown != null)
{
teardowns.Add((Action)Delegate.CreateDelegate(typeof(Action), test, item));
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(testType.Name + "." + item.Name + " failed to register setup/teardown method, exception: " + e.ToString());
}
}
foreach (var item in methods)
{
try
{
var iteratorTest = item.GetCustomAttribute<UnityEngine.TestTools.UnityTestAttribute>(true);
if (iteratorTest != null)
{
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(IEnumerator))
{
var factory = (Func<IEnumerator>)Delegate.CreateDelegate(typeof(Func<IEnumerator>), test, item);
AddAsyncTest(factory.Target.GetType().Name, factory.Method.Name, factory, setups, teardowns);
}
else
{
var testData = GetTestData(item);
if (testData.Count != 0)
{
foreach (var item2 in testData)
{
Func<IEnumerator> factory;
if (item.IsGenericMethod)
{
var method2 = InferGenericType(item, item2);
factory = () => (IEnumerator)method2.Invoke(test, item2);
}
else
{
factory = () => (IEnumerator)item.Invoke(test, item2);
}
var name = item.Name + "(" + string.Join(", ", item2.Select(x => x?.ToString() ?? "null")) + ")";
name = name.Replace(Char.MinValue, ' ').Replace(Char.MaxValue, ' ').Replace("<", "[").Replace(">", "]");
AddAsyncTest(test.GetType().Name, name, factory, setups, teardowns);
}
}
else
{
UnityEngine.Debug.Log(testType.Name + "." + item.Name + " currently does not supported in RuntumeUnitTestToolkit(multiple parameter without TestCase or return type is invalid).");
}
}
}
var standardTest = item.GetCustomAttribute<NUnit.Framework.TestAttribute>(true);
if (standardTest != null)
{
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(void))
{
var invoke = (Action)Delegate.CreateDelegate(typeof(Action), test, item);
AddTest(invoke.Target.GetType().Name, invoke.Method.Name, invoke, setups, teardowns);
}
else
{
var testData = GetTestData(item);
if (testData.Count != 0)
{
foreach (var item2 in testData)
{
Action invoke = null;
if (item.IsGenericMethod)
{
var method2 = InferGenericType(item, item2);
invoke = () => method2.Invoke(test, item2);
}
else
{
invoke = () => item.Invoke(test, item2);
}
var name = item.Name + "(" + string.Join(", ", item2.Select(x => x?.ToString() ?? "null")) + ")";
name = name.Replace(Char.MinValue, ' ').Replace(Char.MaxValue, ' ').Replace("<", "[").Replace(">", "]");
AddTest(test.GetType().Name, name, invoke, setups, teardowns);
}
}
else
{
UnityEngine.Debug.Log(testType.Name + "." + item.Name + " currently does not supported in RuntumeUnitTestToolkit(multiple parameter without TestCase or return type is invalid).");
}
}
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(testType.Name + "." + item.Name + " failed to register method, exception: " + e.ToString());
}
}
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}
List<object[]> GetTestData(MethodInfo methodInfo)
{
List<object[]> testCases = new List<object[]>();
var inlineData = methodInfo.GetCustomAttributes<NUnit.Framework.TestCaseAttribute>(true);
foreach (var item in inlineData)
{
testCases.Add(item.Arguments);
}
var sourceData = methodInfo.GetCustomAttributes<NUnit.Framework.TestCaseSourceAttribute>(true);
foreach (var item in sourceData)
{
var enumerator = GetTestCaseSource(methodInfo, item.SourceType, item.SourceName, item.MethodParams);
foreach (var item2 in enumerator)
{
var item3 = item2 as IEnumerable; // object[][]
if (item3 != null)
{
var l = new List<object>();
foreach (var item4 in item3)
{
l.Add(item4);
}
testCases.Add(l.ToArray());
}
}
}
return testCases;
}
IEnumerable GetTestCaseSource(MethodInfo method, Type sourceType, string sourceName, object[] methodParams)
{
Type type = sourceType ?? method.DeclaringType;
MemberInfo[] member = type.GetMember(sourceName, BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
if (member.Length == 1)
{
MemberInfo memberInfo = member[0];
FieldInfo fieldInfo = memberInfo as FieldInfo;
if ((object)fieldInfo != null)
{
return (!fieldInfo.IsStatic) ? ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.") : ((methodParams == null) ? ((IEnumerable)fieldInfo.GetValue(null)) : ReturnErrorAsParameter("You have specified a data source field but also given a set of parameters. Fields cannot take parameters, please revise the 3rd parameter passed to the TestCaseSourceAttribute and either remove it or specify a method."));
}
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if ((object)propertyInfo != null)
{
return (!propertyInfo.GetGetMethod(nonPublic: true).IsStatic) ? ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.") : ((methodParams == null) ? ((IEnumerable)propertyInfo.GetValue(null, null)) : ReturnErrorAsParameter("You have specified a data source property but also given a set of parameters. Properties cannot take parameters, please revise the 3rd parameter passed to the TestCaseSource attribute and either remove it or specify a method."));
}
MethodInfo methodInfo = memberInfo as MethodInfo;
if ((object)methodInfo != null)
{
return (!methodInfo.IsStatic) ? ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.") : ((methodParams == null || methodInfo.GetParameters().Length == methodParams.Length) ? ((IEnumerable)methodInfo.Invoke(null, methodParams)) : ReturnErrorAsParameter("You have given the wrong number of arguments to the method in the TestCaseSourceAttribute, please check the number of parameters passed in the object is correct in the 3rd parameter for the TestCaseSourceAttribute and this matches the number of parameters in the target method and try again."));
}
}
return null;
}
MethodInfo InferGenericType(MethodInfo methodInfo, object[] parameters)
{
var set = new HashSet<Type>();
List<Type> genericParameters = new List<Type>();
foreach (var item in methodInfo.GetParameters()
.Select((x, i) => new { x.ParameterType, i })
.Where(x => x.ParameterType.IsGenericParameter)
.OrderBy(x => x.ParameterType.GenericParameterPosition))
{
if (set.Add(item.ParameterType)) // DistinctBy
{
genericParameters.Add(parameters[item.i].GetType());
}
}
return methodInfo.MakeGenericMethod(genericParameters.ToArray());
}
IEnumerable ReturnErrorAsParameter(string name)
{
throw new Exception(name);
}
System.Collections.IEnumerator ScrollLogToEndNextFrame()
{
yield return null;
yield return null;
logScrollBar.value = 0;
}
IEnumerator RunTestInCoroutine(KeyValuePair<string, List<TestKeyValuePair>> actionList)
{
Button self = null;
foreach (var btn in list.GetComponentsInChildren<Button>())
{
btn.interactable = false;
if (btn.name == actionList.Key) self = btn;
}
if (self != null)
{
self.GetComponent<Image>().color = normalColor;
}
var allGreen = true;
AppendToGraphicText("<color=yellow>" + actionList.Key + "</color>\n");
WriteToConsole("Begin Test Class: " + actionList.Key);
yield return null;
var totalExecutionTime = new List<double>();
foreach (var item2 in actionList.Value)
{
// setup
try
{
foreach (var setup in item2.Setups)
{
setup();
}
// before start, cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
AppendToGraphicText("<color=teal>" + item2.Key + "</color>\n");
yield return null;
var v = item2.Value;
var methodStopwatch = System.Diagnostics.Stopwatch.StartNew();
Exception exception = null;
if (v is Action)
{
try
{
((Action)v).Invoke();
}
catch (Exception ex)
{
exception = ex;
}
}
else
{
var coroutineFactory = (Func<IEnumerator>)v;
IEnumerator coroutine = null;
try
{
coroutine = coroutineFactory();
}
catch (Exception ex)
{
exception = ex;
}
if (exception == null)
{
yield return StartCoroutine(UnwrapEnumerator(coroutine, ex =>
{
exception = ex;
}));
}
}
methodStopwatch.Stop();
totalExecutionTime.Add(methodStopwatch.Elapsed.TotalMilliseconds);
if (exception == null)
{
AppendToGraphicText("OK, " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms\n");
WriteToConsoleResult(item2.Key + ", " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms", true);
}
else
{
AppendToGraphicText("<color=red>" + exception.ToString() + "</color>\n");
WriteToConsoleResult(item2.Key + ", " + exception.ToString(), false);
allGreen = false;
allTestGreen = false;
}
}
finally
{
foreach (var teardown in item2.Teardowns)
{
teardown();
}
}
}
AppendToGraphicText("[" + actionList.Key + "]" + totalExecutionTime.Sum().ToString("0.00") + "ms\n\n");
foreach (var btn in list.GetComponentsInChildren<Button>()) btn.interactable = true;
if (self != null)
{
self.GetComponent<Image>().color = allGreen ? passColor : failColor;
}
yield return StartCoroutine(ScrollLogToEndNextFrame());
}
IEnumerator ExecuteAllInCoroutine(List<Func<Coroutine>> tests)
{
allTestGreen = true;
foreach (var item in tests)
{
yield return item();
}
if (Application.isBatchMode)
{
var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
bool disableAutoClose = (scene.name.Contains("DisableAutoClose"));
if (allTestGreen)
{
WriteToConsole("Test Complete Successfully");
if (!disableAutoClose)
{
Application.Quit();
}
}
else
{
WriteToConsole("Test Failed, please see [NG] log.");
if (!disableAutoClose)
{
Application.Quit(1);
}
}
}
}
IEnumerator UnwrapEnumerator(IEnumerator enumerator, Action<Exception> exceptionCallback)
{
var hasNext = true;
while (hasNext)
{
try
{
hasNext = enumerator.MoveNext();
}
catch (Exception ex)
{
exceptionCallback(ex);
hasNext = false;
}
if (hasNext)
{
// unwrap self for bug of Unity
// https://issuetracker.unity3d.com/issues/does-not-stop-coroutine-when-it-throws-exception-in-movenext-at-first-frame
var moreCoroutine = enumerator.Current as IEnumerator;
if (moreCoroutine != null)
{
yield return StartCoroutine(UnwrapEnumerator(moreCoroutine, ex =>
{
exceptionCallback(ex);
hasNext = false;
}));
}
else
{
yield return enumerator.Current;
}
}
}
}
static void WriteToConsole(string msg)
{
if (Application.isBatchMode)
{
Console.WriteLine(msg);
}
}
void AppendToGraphicText(string msg)
{
if (!Application.isBatchMode)
{
if (logClear)
{
logText.text = "";
logClear = false;
}
try
{
logText.text += msg;
}
catch
{
logClear = true;
}
}
}
static void WriteToConsoleResult(string msg, bool green)
{
if (Application.isBatchMode)
{
if (!green)
{
var currentForeground = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("[NG]");
Console.ForegroundColor = currentForeground;
}
else
{
var currentForeground = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("[OK]");
Console.ForegroundColor = currentForeground;
}
System.Console.WriteLine(msg);
}
}
struct Pair
{
public string Name;
public UnityAction Action;
}
}
public class TestKeyValuePair
{
public string Key;
/// <summary>IEnumerator or Func[IEnumerator]</summary>
public object Value;
public List<Action> Setups;
public List<Action> Teardowns;
public TestKeyValuePair(string key, object value, List<Action> setups, List<Action> teardowns)
{
this.Key = key;
this.Value = value;
this.Setups = setups;
this.Teardowns = teardowns;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 660baed073888b8438569f57e42679b2
timeCreated: 1476793308
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
{
"name": "com.cysharp.runtimeunittesttoolkit",
"displayName": "RuntimeUnitTestToolkit",
"version": "2.3.0",
"unity": "2018.3",
"description": "CLI/GUI Frontend of Unity Test Runner to test on any platform.",
"keywords": ["test"],
"category": "Tests",
"dependencies": {
}
}

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: b7883c7ac5d6ea4409a229aeab14e796
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -216,7 +216,7 @@
// RETRY:
// try
// {
// context.RequestHeaders["x-accesss-token"] = token;
// context.RequestHeaders["x-access-token"] = token;
// return await next(context, cancellationToken);
// }
// catch (UnityWebRequestException ex)

View File

@@ -20,8 +20,11 @@ using System.IO;
using System.Linq.Expressions;
// using DG.Tweening;
public struct MyJob : IJob
{
public int loopCount;

View File

@@ -38,12 +38,11 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
@@ -98,13 +97,14 @@ LightmapSettings:
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
m_LightingSettings: {fileID: 4890085278179872738, guid: 814185d368762ed45a2298d112780689,
type: 2}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
@@ -117,7 +117,9 @@ NavMeshSettings:
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
@@ -150,10 +152,10 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1584557232}
m_Father: {fileID: 1556045508}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@@ -174,6 +176,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
@@ -218,6 +221,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
@@ -270,9 +275,17 @@ Camera:
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
@@ -306,12 +319,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 518730348}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 488, y: 418, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &519420028
GameObject:
@@ -352,9 +366,11 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: f0bc6c75abb2e0b47a25aa49bfd488ed, type: 3}
m_Name:
m_EditorClassIdentifier:
camera: {fileID: 518730349}
mycamera: {fileID: 0}
okButton: {fileID: 16537672}
cancelButton: {fileID: 628393011}
RP1:
latestValue: 0
text: {fileID: 2101290655}
button: {fileID: 0}
--- !u!20 &519420031
@@ -371,9 +387,17 @@ Camera:
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
@@ -407,12 +431,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &628393009
GameObject:
@@ -443,10 +468,10 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 865871445}
m_Father: {fileID: 1556045508}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@@ -467,6 +492,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
@@ -511,6 +537,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
@@ -560,9 +588,9 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 628393010}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -584,6 +612,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
@@ -639,6 +669,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
@@ -668,12 +699,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 872009839}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1556045504
GameObject:
@@ -687,6 +719,7 @@ GameObject:
- component: {fileID: 1556045507}
- component: {fileID: 1556045506}
- component: {fileID: 1556045505}
- component: {fileID: 1556045509}
m_Layer: 0
m_Name: Canvas
m_TagString: Untagged
@@ -733,6 +766,7 @@ MonoBehaviour:
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &1556045507
Canvas:
m_ObjectHideFlags: 0
@@ -750,7 +784,9 @@ Canvas:
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
@@ -764,18 +800,30 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 16537671}
- {fileID: 628393010}
- {fileID: 2101290654}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1556045509
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1556045504}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a478e5f6126dc184ca902adfb35401b4, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1584557231
GameObject:
m_ObjectHideFlags: 0
@@ -804,9 +852,9 @@ RectTransform:
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 16537671}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -828,6 +876,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
@@ -883,9 +933,9 @@ RectTransform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1556045508}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
@@ -907,6 +957,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
@@ -932,3 +984,11 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2101290653}
m_CullTransparentMesh: 0
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 519420032}
- {fileID: 518730350}
- {fileID: 872009842}
- {fileID: 1556045508}

View File

@@ -0,0 +1,74 @@
using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
// https://github.com/Cysharp/UniTask/issues/617
public class WaitWhileTest : MonoBehaviour
{
private const float c_CallInterval = 0.3f;
private float m_JustBeforeCallTime;
private TaskObj m_TestObj;
// Start is called before the first frame update
void Start()
{
m_JustBeforeCallTime = Time.unscaledTime;
m_TestObj = new TaskObj();
// m_TestObj.Test(CancellationToken.None).Forget();
}
// Update is called once per frame
void Update()
{
if (Time.unscaledTime - m_JustBeforeCallTime > c_CallInterval)
{
m_JustBeforeCallTime = Time.unscaledTime;
m_TestObj.Test(CancellationToken.None).Forget();
}
}
}
public class TaskObj
{
private CancellationTokenSource m_CancelTokenSource;
private const float c_FinishElapsedTime = 0.1f;
private float m_StartTime;
public async UniTask Test(CancellationToken token)
{
try
{
CancelAndDisposeTokenSource();
m_CancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
m_StartTime = Time.unscaledTime;
await UniTask.WaitWhile(IsContinued, cancellationToken: m_CancelTokenSource.Token, cancelImmediately: true);
Debug.Log("Task Finished");
}
catch (OperationCanceledException)
{
Debug.LogWarning("Task Canceled");
}
finally
{
CancelAndDisposeTokenSource();
}
}
private void CancelAndDisposeTokenSource()
{
m_CancelTokenSource?.Cancel();
m_CancelTokenSource?.Dispose();
m_CancelTokenSource = null;
}
private bool IsContinued()
{
return Time.unscaledTime - m_StartTime > c_FinishElapsedTime;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8760bbbab905a534eb6fb7b61b736926
guid: a478e5f6126dc184ca902adfb35401b4
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,90 @@
using System.Collections;
using System.Threading;
using Cysharp.Threading.Tasks;
using FluentAssertions;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.TestTools;
#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
namespace Cysharp.Threading.TasksTests
{
public class AsyncOperationTest
{
[UnityTest]
public IEnumerator ResourcesLoad_Completed() => UniTask.ToCoroutine(async () =>
{
var asyncOperation = Resources.LoadAsync<Texture2D>("sample_texture");
await asyncOperation.ToUniTask();
asyncOperation.isDone.Should().BeTrue();
asyncOperation.asset.GetType().Should().Be(typeof(Texture2D));
});
[UnityTest]
public IEnumerator ResourcesLoad_CancelOnPlayerLoop() => UniTask.ToCoroutine(async () =>
{
var cts = new CancellationTokenSource();
var task = Resources.LoadAsync<Texture>("sample_texture").ToUniTask(cancellationToken: cts.Token, cancelImmediately: false);
cts.Cancel();
task.Status.Should().Be(UniTaskStatus.Pending);
await UniTask.NextFrame();
task.Status.Should().Be(UniTaskStatus.Canceled);
});
[Test]
public void ResourcesLoad_CancelImmediately()
{
{
var cts = new CancellationTokenSource();
var task = Resources.LoadAsync<Texture>("sample_texture").ToUniTask(cancellationToken: cts.Token, cancelImmediately: true);
cts.Cancel();
task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
[UnityTest]
public IEnumerator UnityWebRequest_Completed() => UniTask.ToCoroutine(async () =>
{
var filePath = System.IO.Path.Combine(Application.dataPath, "Tests", "Resources", "sample_texture.png");
var asyncOperation = UnityWebRequest.Get($"file://{filePath}").SendWebRequest();
await asyncOperation.ToUniTask();
asyncOperation.isDone.Should().BeTrue();
asyncOperation.webRequest.result.Should().Be(UnityWebRequest.Result.Success);
});
[UnityTest]
public IEnumerator UnityWebRequest_CancelOnPlayerLoop() => UniTask.ToCoroutine(async () =>
{
var cts = new CancellationTokenSource();
var filePath = System.IO.Path.Combine(Application.dataPath, "Tests", "Resources", "sample_texture.png");
var task = UnityWebRequest.Get($"file://{filePath}").SendWebRequest().ToUniTask(cancellationToken: cts.Token);
cts.Cancel();
task.Status.Should().Be(UniTaskStatus.Pending);
await UniTask.NextFrame();
task.Status.Should().Be(UniTaskStatus.Canceled);
});
[Test]
public void UnityWebRequest_CancelImmediately()
{
var cts = new CancellationTokenSource();
cts.Cancel();
var filePath = System.IO.Path.Combine(Application.dataPath, "Tests", "Resources", "sample_texture.png");
var task = UnityWebRequest.Get($"file://{filePath}").SendWebRequest().ToUniTask(cancellationToken: cts.Token, cancelImmediately: true);
task.Status.Should().Be(UniTaskStatus.Canceled);
}
#endif
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 295d574a16494d6aa4d02fcb32179e39
timeCreated: 1698887128

View File

@@ -145,6 +145,11 @@ namespace Cysharp.Threading.TasksTests
public int MyProperty { get; set; }
}
class MyBoolenClass
{
public bool MyProperty { get; set; }
}
[UnityTest]
public IEnumerator WaitUntil() => UniTask.ToCoroutine(async () =>
{
@@ -159,6 +164,20 @@ namespace Cysharp.Threading.TasksTests
diff.Should().Be(11);
});
[UnityTest]
public IEnumerator WaitUntilWithState() => UniTask.ToCoroutine(async () =>
{
var v = new MyBoolenClass { MyProperty = false };
UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => v.MyProperty = true).Forget();
var startFrame = Time.frameCount;
await UniTask.WaitUntil(v, static v => v.MyProperty, PlayerLoopTiming.EarlyUpdate);
var diff = Time.frameCount - startFrame;
diff.Should().Be(11);
});
[UnityTest]
public IEnumerator WaitWhile() => UniTask.ToCoroutine(async () =>
{
@@ -173,6 +192,20 @@ namespace Cysharp.Threading.TasksTests
diff.Should().Be(11);
});
[UnityTest]
public IEnumerator WaitWhileWithState() => UniTask.ToCoroutine(async () =>
{
var v = new MyBoolenClass { MyProperty = true };
UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => v.MyProperty = false).Forget();
var startFrame = Time.frameCount;
await UniTask.WaitWhile(v, static v => v.MyProperty, PlayerLoopTiming.EarlyUpdate);
var diff = Time.frameCount - startFrame;
diff.Should().Be(11);
});
[UnityTest]
public IEnumerator WaitUntilValueChanged() => UniTask.ToCoroutine(async () =>
{

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 894f21dfce4e82343a91661e1ec1a455
guid: 8d82913edf6ac48aca30f66ae9ba42d6
folderAsset: yes
DefaultImporter:
externalObjects: {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,215 @@
fileFormatVersion: 2
guid: 535006a83baed4ebda99d24a909a2efe
TextureImporter:
internalIDToNameTable:
- first:
213: -2664112245596591751
second: sample_texture_0
- first:
213: -4606777057269188692
second: sample_texture_1
- first:
213: 1950921086533113773
second: sample_texture_2
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: sample_texture_0
rect:
serializedVersion: 2
x: 0
y: 76
width: 243
height: 251
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 9796277170c270bd0800000000000000
internalID: -2664112245596591751
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: sample_texture_1
rect:
serializedVersion: 2
x: 227
y: 0
width: 190
height: 231
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: ca7fc069ca07110c0800000000000000
internalID: -4606777057269188692
vertices: []
indices:
edges: []
weights: []
- serializedVersion: 2
name: sample_texture_2
rect:
serializedVersion: 2
x: 398
y: 87
width: 202
height: 188
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: da710ab4460131b10800000000000000
internalID: 1950921086533113773
vertices: []
indices:
edges: []
weights: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable:
sample_texture_0: -2664112245596591751
sample_texture_1: -4606777057269188692
sample_texture_2: 1950921086533113773
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
{
"dependencies": {
"com.cysharp.runtimeunittesttoolkit": "https://github.com/Cysharp/RuntimeUnitTestToolkit.git?path=RuntimeUnitTestToolkit/Assets/RuntimeUnitTestToolkit#2.6.0",
"com.unity.collab-proxy": "2.4.3",
"com.unity.ide.rider": "3.0.31",
"com.unity.ide.visualstudio": "2.0.22",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.7.6",
"com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.9",
"com.unity.ugui": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}

View File

@@ -0,0 +1,360 @@
{
"dependencies": {
"com.cysharp.runtimeunittesttoolkit": {
"version": "https://github.com/Cysharp/RuntimeUnitTestToolkit.git?path=RuntimeUnitTestToolkit/Assets/RuntimeUnitTestToolkit#2.6.0",
"depth": 0,
"source": "git",
"dependencies": {},
"hash": "4e3dbfaa9c40b5cfdcb71a1d4e8bca0d45ca1055"
},
"com.unity.collab-proxy": {
"version": "2.4.3",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.31",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.22",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.sysroot": {
"version": "2.0.10",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.sysroot.linux-x86_64": {
"version": "2.0.9",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.10"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.33",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.textmeshpro": {
"version": "3.0.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.7.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.toolchain.win-x86_64-linux-x86_64": {
"version": "2.0.9",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.10",
"com.unity.sysroot.linux-x86_64": "2.0.9"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}

View File

@@ -0,0 +1,35 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!387306366 &1
MemorySettings:
m_ObjectHideFlags: 0
m_EditorMemorySettings:
m_MainAllocatorBlockSize: -1
m_ThreadAllocatorBlockSize: -1
m_MainGfxBlockSize: -1
m_ThreadGfxBlockSize: -1
m_CacheBlockSize: -1
m_TypetreeBlockSize: -1
m_ProfilerBlockSize: -1
m_ProfilerEditorBlockSize: -1
m_BucketAllocatorGranularity: -1
m_BucketAllocatorBucketsCount: -1
m_BucketAllocatorBlockSize: -1
m_BucketAllocatorBlockCount: -1
m_ProfilerBucketAllocatorGranularity: -1
m_ProfilerBucketAllocatorBucketsCount: -1
m_ProfilerBucketAllocatorBlockSize: -1
m_ProfilerBucketAllocatorBlockCount: -1
m_TempAllocatorSizeMain: -1
m_JobTempAllocatorBlockSize: -1
m_BackgroundJobTempAllocatorBlockSize: -1
m_JobTempAllocatorReducedBlockSize: -1
m_TempAllocatorSizeGIBakingWorker: -1
m_TempAllocatorSizeNavMeshWorker: -1
m_TempAllocatorSizeAudioWorker: -1
m_TempAllocatorSizeCloudWorker: -1
m_TempAllocatorSizeGfx: -1
m_TempAllocatorSizeJobWorker: -1
m_TempAllocatorSizeBackgroundWorker: -1
m_TempAllocatorSizePreloadManager: -1
m_PlatformMemorySettings: {}

View File

@@ -3,7 +3,7 @@
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 20
serializedVersion: 26
productGUID: 904cd7a3163037f42a9204c0e2f2b7bd
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
@@ -48,12 +48,16 @@ PlayerSettings:
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 0
unsupportedMSAAFallback: 0
m_SpriteBatchVertexThreshold: 300
m_MTRendering: 1
mipStripping: 0
numberOfMipsStripped: 0
numberOfMipsStrippedPerMipmapLimitGroup: {}
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
iosUseCustomAppBackgroundBehavior: 0
iosAllowHTTPDownload: 1
allowedAutorotateToPortrait: 1
allowedAutorotateToPortraitUpsideDown: 1
allowedAutorotateToLandscapeRight: 1
@@ -66,6 +70,13 @@ PlayerSettings:
androidRenderOutsideSafeArea: 1
androidUseSwappy: 0
androidBlitType: 0
androidResizableWindow: 0
androidDefaultWindowWidth: 1920
androidDefaultWindowHeight: 1080
androidMinimumWindowWidth: 400
androidMinimumWindowHeight: 300
androidFullscreenMode: 1
androidAutoRotationBehavior: 1
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 1
@@ -77,6 +88,7 @@ PlayerSettings:
hideHomeButton: 0
submitAnalytics: 1
usePlayerLog: 1
dedicatedServerOptimizations: 0
bakeCollisionMeshes: 0
forceSingleInstance: 0
useFlipModelSwapchain: 1
@@ -111,16 +123,22 @@ PlayerSettings:
switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchGpuScratchPoolGranularity: 2097152
switchAllowGpuScratchShrinking: 0
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
switchNVNGraphicsFirmwareMemory: 32
switchMaxWorkerMultiple: 8
stadiaPresentMode: 0
stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0
m_SupportedAspectRatios:
4:3: 1
5:4: 1
16:10: 1
16:9: 1
Others: 1
vulkanEnablePreTransform: 0
vulkanEnableLateAcquireNextImage: 0
vulkanEnableCommandBufferRecycling: 1
loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0
bundleVersion: 0.1
preloadedAssets: []
metroInputSource: 0
@@ -129,46 +147,29 @@ PlayerSettings:
xboxOneDisableKinectGpuReservation: 1
xboxOneEnable7thCore: 1
vrSettings:
cardboard:
depthFormat: 0
enableTransitionView: 0
daydream:
depthFormat: 0
useSustainedPerformanceMode: 0
enableVideoLayer: 0
useProtectedVideoMemory: 0
minimumSupportedHeadTracking: 0
maximumSupportedHeadTracking: 1
hololens:
depthFormat: 1
depthBufferSharingEnabled: 1
lumin:
depthFormat: 0
frameTiming: 2
enableGLCache: 0
glCacheMaxBlobSize: 524288
glCacheMaxFileSize: 8388608
oculus:
sharedDepthBuffer: 1
dashSupport: 1
lowOverheadMode: 0
protectedContext: 0
v2Signing: 1
enable360StereoCapture: 0
isWsaHolographicRemotingEnabled: 0
enableFrameTimingStats: 0
enableOpenGLProfilerGPURecorders: 1
allowHDRDisplaySupport: 0
useHDRDisplay: 0
D3DHDRBitDepth: 0
hdrBitDepth: 0
m_ColorGamuts: 00000000
targetPixelDensity: 30
resolutionScalingMode: 0
resetResolutionOnWindowResize: 0
androidSupportedAspectRatio: 1
androidMaxAspectRatio: 2.1
applicationIdentifier:
Standalone: com.Company.ProductName
buildNumber: {}
Standalone: com.DefaultCompany.UniTask
buildNumber:
Standalone: 0
VisionOS: 0
iPhone: 0
tvOS: 0
overrideDefaultApplicationIdentifier: 0
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 19
AndroidMinSdkVersion: 22
AndroidTargetSdkVersion: 0
AndroidPreferredInstallLocation: 1
aotOptions:
@@ -181,12 +182,15 @@ PlayerSettings:
APKExpansionFiles: 0
keepLoadedShadersAlive: 0
StripUnusedMeshComponents: 1
strictShaderVariantMatching: 0
VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988
iOSTargetOSVersionString: 10.0
iOSTargetOSVersionString: 12.0
tvOSSdkVersion: 0
tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString: 10.0
tvOSTargetOSVersionString: 12.0
VisionOSSdkVersion: 0
VisionOSTargetOSVersionString: 1.0
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1
@@ -220,32 +224,48 @@ PlayerSettings:
iOSLaunchScreeniPadFillPct: 100
iOSLaunchScreeniPadSize: 100
iOSLaunchScreeniPadCustomXibPath:
iOSUseLaunchScreenStoryboard: 0
iOSLaunchScreenCustomStoryboardPath:
iOSLaunchScreeniPadCustomStoryboardPath:
iOSDeviceRequirements: []
iOSURLSchemes: []
macOSURLSchemes: []
iOSBackgroundModes: 0
iOSMetalForceHardShadows: 0
metalEditorSupport: 1
metalAPIValidation: 1
metalCompileShaderBinary: 0
iOSRenderExtraFrameOnPause: 0
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:
VisionOSManualSigningProvisioningProfileID:
iOSManualSigningProvisioningProfileType: 0
tvOSManualSigningProvisioningProfileType: 0
VisionOSManualSigningProvisioningProfileType: 0
appleEnableAutomaticSigning: 0
iOSRequireARKit: 0
iOSAutomaticallyDetectAndAddCapabilities: 1
appleEnableProMotion: 0
shaderPrecisionModel: 0
clonedFromGUID: 5f34be1353de5cf4398729fda238591b
templatePackageId: com.unity.template.2d@3.1.0
templateDefaultScene: Assets/Scenes/SampleScene.unity
useCustomMainManifest: 0
useCustomLauncherManifest: 0
useCustomMainGradleTemplate: 0
useCustomLauncherGradleManifest: 0
useCustomBaseGradleTemplate: 0
useCustomGradlePropertiesTemplate: 0
useCustomGradleSettingsTemplate: 0
useCustomProguardFile: 0
AndroidTargetArchitectures: 1
AndroidTargetDevices: 0
AndroidSplashScreenScale: 0
androidSplashScreen: {fileID: 0}
AndroidKeystoreName: '{inproject}: '
AndroidKeyaliasName:
AndroidEnableArmv9SecurityFeatures: 0
AndroidBuildApkPerCpuArchitecture: 0
AndroidTVCompatibility: 0
AndroidIsGame: 1
@@ -258,11 +278,15 @@ PlayerSettings:
height: 180
banner: {fileID: 0}
androidGamepadSupportLevel: 0
chromeosInputEmulation: 1
AndroidMinifyRelease: 0
AndroidMinifyDebug: 0
AndroidValidateAppBundleSize: 1
AndroidAppBundleSizeToValidate: 100
m_BuildTargetIcons: []
m_BuildTargetPlatformIcons: []
m_BuildTargetBatching: []
m_BuildTargetShaderSettings: []
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0
@@ -298,8 +322,13 @@ PlayerSettings:
m_BuildTargetGraphicsAPIs:
- m_BuildTarget: AndroidPlayer
m_APIs: 150000000b000000
m_Automatic: 0
m_Automatic: 1
- m_BuildTarget: iOSSupport
m_APIs: 10000000
m_Automatic: 1
m_BuildTargetVRSettings: []
m_DefaultShaderChunkSizeInMB: 16
m_DefaultShaderChunkCount: 0
openGLRequireES31: 0
openGLRequireES31AEP: 0
openGLRequireES32: 0
@@ -309,7 +338,11 @@ PlayerSettings:
iPhone: 1
tvOS: 1
m_BuildTargetGroupLightmapEncodingQuality: []
m_BuildTargetGroupHDRCubemapEncodingQuality: []
m_BuildTargetGroupLightmapSettings: []
m_BuildTargetGroupLoadStoreDebugModeSettings: []
m_BuildTargetNormalMapEncoding: []
m_BuildTargetDefaultTextureCompressionFormat: []
playModeTestRunnerEnabled: 0
runPlayModeTestAsEditModeTest: 0
actionOnDotNetUnhandledException: 1
@@ -319,14 +352,20 @@ PlayerSettings:
cameraUsageDescription:
locationUsageDescription:
microphoneUsageDescription:
bluetoothUsageDescription:
macOSTargetOSVersion: 10.13.0
switchNMETAOverride:
switchNetLibKey:
switchSocketMemoryPoolSize: 6144
switchSocketAllocatorPoolSize: 128
switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0
switchEnableFileSystemTrace: 0
switchLTOSetting: 0
switchApplicationID: 0x01004b9000490000
switchNSODependencies:
switchCompilerFlags:
switchTitleNames_0:
switchTitleNames_1:
switchTitleNames_2:
@@ -342,6 +381,7 @@ PlayerSettings:
switchTitleNames_12:
switchTitleNames_13:
switchTitleNames_14:
switchTitleNames_15:
switchPublisherNames_0:
switchPublisherNames_1:
switchPublisherNames_2:
@@ -357,6 +397,7 @@ PlayerSettings:
switchPublisherNames_12:
switchPublisherNames_13:
switchPublisherNames_14:
switchPublisherNames_15:
switchIcons_0: {fileID: 0}
switchIcons_1: {fileID: 0}
switchIcons_2: {fileID: 0}
@@ -372,6 +413,7 @@ PlayerSettings:
switchIcons_12: {fileID: 0}
switchIcons_13: {fileID: 0}
switchIcons_14: {fileID: 0}
switchIcons_15: {fileID: 0}
switchSmallIcons_0: {fileID: 0}
switchSmallIcons_1: {fileID: 0}
switchSmallIcons_2: {fileID: 0}
@@ -387,6 +429,7 @@ PlayerSettings:
switchSmallIcons_12: {fileID: 0}
switchSmallIcons_13: {fileID: 0}
switchSmallIcons_14: {fileID: 0}
switchSmallIcons_15: {fileID: 0}
switchManualHTML:
switchAccessibleURLs:
switchLegalInformation:
@@ -396,7 +439,6 @@ PlayerSettings:
switchReleaseVersion: 0
switchDisplayVersion: 1.0.0
switchStartupUserAccount: 0
switchTouchScreenUsage: 0
switchSupportedLanguagesMask: 0
switchLogoType: 0
switchApplicationErrorCodeCategory:
@@ -438,6 +480,7 @@ PlayerSettings:
switchNativeFsCacheSize: 32
switchIsHoldTypeHorizontal: 0
switchSupportedNpadCount: 8
switchEnableTouchScreen: 1
switchSocketConfigEnabled: 0
switchTcpInitialSendBufferSize: 32
switchTcpInitialReceiveBufferSize: 64
@@ -448,7 +491,12 @@ PlayerSettings:
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
switchUseNewStyleFilepaths: 0
switchUseLegacyFmodPriorities: 0
switchUseMicroSleepForYield: 1
switchEnableRamDiskSupport: 0
switchMicroSleepForYieldTime: 25
switchRamDiskSpaceSize: 12
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
@@ -475,6 +523,7 @@ PlayerSettings:
ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:
@@ -517,6 +566,9 @@ PlayerSettings:
ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4AllowPS5Detection: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: []
ps4attribVROutputEnabled: 0
@@ -528,6 +580,7 @@ PlayerSettings:
webGLMemorySize: 16
webGLExceptionSupport: 1
webGLNameFilesAsHashes: 0
webGLShowDiagnostics: 0
webGLDataCaching: 1
webGLDebugSymbols: 0
webGLEmscriptenArgs:
@@ -536,18 +589,47 @@ PlayerSettings:
webGLAnalyzeBuildSize: 0
webGLUseEmbeddedResources: 0
webGLCompressionFormat: 1
webGLWasmArithmeticExceptions: 0
webGLLinkerTarget: 1
webGLThreadsSupport: 0
webGLWasmStreaming: 0
webGLDecompressionFallback: 0
webGLInitialMemorySize: 32
webGLMaximumMemorySize: 2048
webGLMemoryGrowthMode: 2
webGLMemoryLinearGrowthStep: 16
webGLMemoryGeometricGrowthStep: 0.2
webGLMemoryGeometricGrowthCap: 96
webGLPowerPreference: 2
scriptingDefineSymbols: {}
additionalCompilerArguments: {}
platformArchitecture: {}
scriptingBackend:
Android: 1
Server: 1
Standalone: 1
il2cppCompilerConfiguration: {}
managedStrippingLevel: {}
il2cppCodeGeneration: {}
managedStrippingLevel:
Android: 1
EmbeddedLinux: 1
GameCoreScarlett: 1
GameCoreXboxOne: 1
Nintendo Switch: 1
PS4: 1
PS5: 1
QNX: 1
Stadia: 1
Standalone: 1
VisionOS: 1
WebGL: 1
Windows Store Apps: 1
XboxOne: 1
iPhone: 1
tvOS: 1
incrementalIl2cppBuild: {}
suppressCommonWarnings: 1
allowUnsafeCode: 0
useDeterministicCompilation: 1
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 0
@@ -578,11 +660,13 @@ PlayerSettings:
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
a: 1}
metroSplashScreenUseBackgroundColor: 0
syncCapabilities: 0
platformCapabilities: {}
metroTargetDeviceFamilies: {}
metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
vcxProjDefaultLanguage:
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:
@@ -601,6 +685,7 @@ PlayerSettings:
XboxOneCapability: []
XboxOneGameRating: {}
XboxOneIsContentPackage: 0
XboxOneEnhancedXboxCompatibilityMode: 0
XboxOneEnableGPUVariability: 1
XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0}
@@ -609,10 +694,7 @@ PlayerSettings:
XboxOneXTitleMemory: 8
XboxOneOverrideIdentityName:
XboxOneOverrideIdentityPublisher:
vrEditorSettings:
daydream:
daydreamIconForeground: {fileID: 0}
daydreamIconBackground: {fileID: 0}
vrEditorSettings: {}
cloudServicesEnabled:
UNet: 1
luminIcon:
@@ -626,12 +708,22 @@ PlayerSettings:
luminVersion:
m_VersionCode: 1
m_VersionName:
hmiPlayerDataPath:
hmiForceSRGBBlit: 1
embeddedLinuxEnableGamepadInput: 1
hmiLogStartupTiming: 0
hmiCpuConfiguration:
apiCompatibilityLevel: 6
activeInputHandler: 0
windowsGamepadBackendHint: 0
cloudProjectId:
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []
projectName:
organizationId:
cloudEnabled: 0
enableNativePlatformBackendsForNewInputSystem: 0
disableOldInputManagerSupport: 0
legacyClampBlendShapeWeights: 1
hmiLoadingImage: {fileID: 0}
platformRequiresReadableAssets: 0
virtualTexturingSupportEnabled: 0
insecureHttpOption: 0

View File

@@ -1,2 +1,2 @@
m_EditorVersion: 2020.2.1f1
m_EditorVersionWithRevision: 2020.2.1f1 (270dd8c3da1c)
m_EditorVersion: 2022.3.39f1
m_EditorVersionWithRevision: 2022.3.39f1 (4e1b0f82c39a)

View File

@@ -0,0 +1,121 @@
{
"templatePinStates": [],
"dependencyTypeInfos": [
{
"userAdded": false,
"type": "UnityEngine.AnimationClip",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.Animations.AnimatorController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.AnimatorOverrideController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.Audio.AudioMixerController",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.ComputeShader",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Cubemap",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.GameObject",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.LightingDataAsset",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.LightingSettings",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Material",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.MonoScript",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.PhysicMaterial",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.PhysicsMaterial2D",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Rendering.VolumeProfile",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEditor.SceneAsset",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Shader",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.ShaderVariantCollection",
"defaultInstantiationMode": 1
},
{
"userAdded": false,
"type": "UnityEngine.Texture",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Texture2D",
"defaultInstantiationMode": 0
},
{
"userAdded": false,
"type": "UnityEngine.Timeline.TimelineAsset",
"defaultInstantiationMode": 0
}
],
"defaultDependencyTypeInfo": {
"userAdded": false,
"type": "<default_scene_template_dependencies>",
"defaultInstantiationMode": 1
},
"newSceneOverride": 0
}

View File

@@ -9,6 +9,7 @@ UnityConnectSettings:
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
m_ConfigUrl: https://config.uca.cloud.unity3d.com
m_DashboardUrl: https://dashboard.unity3d.com
m_TestInitMode: 0
CrashReportingSettings:
m_EventUrl: https://perf-events.cloud.unity3d.com
@@ -22,6 +23,7 @@ UnityConnectSettings:
m_Enabled: 0
m_TestMode: 0
m_InitializeOnStartup: 1
m_PackageRequiringCoreStatsPresent: 0
UnityAdsSettings:
m_Enabled: 0
m_InitializeOnStartup: 1

View File

@@ -1,24 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!162 &1
EditorUserSettings:
m_ObjectHideFlags: 0
serializedVersion: 4
m_ConfigSettings:
RecentlyUsedScenePath-0:
value: 22424703114646680e0b0227036c6c1118131a25340527392367083debf42d
flags: 0
vcSharedLogLevel:
value: 0d5e400f0650
flags: 0
m_VCAutomaticAdd: 1
m_VCDebugCom: 0
m_VCDebugCmd: 0
m_VCDebugOut: 0
m_SemanticMergeMode: 2
m_VCShowFailedCheckout: 1
m_VCOverwriteFailedCheckoutAssets: 1
m_VCProjectOverlayIcons: 1
m_VCHierarchyOverlayIcons: 1
m_VCOtherOverlayIcons: 1
m_VCAllowAsyncUpdate: 0