mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-16 12:00:10 +00:00
Compare commits
344 Commits
2.0.3-prev
...
moreasmdef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a35e5f929d | ||
|
|
9a3f10d4bf | ||
|
|
638522600a | ||
|
|
081113a62c | ||
|
|
6d382450cf | ||
|
|
19f2a6f282 | ||
|
|
7ed0b016ea | ||
|
|
f72a51e13d | ||
|
|
0e2dbbe754 | ||
|
|
cff51a0425 | ||
|
|
7cac4bbbab | ||
|
|
3f4a46bca6 | ||
|
|
7d21a75ea8 | ||
|
|
88817b7093 | ||
|
|
52cdadc035 | ||
|
|
5401b9b227 | ||
|
|
38de930f81 | ||
|
|
9be6ef7ba6 | ||
|
|
739bc6e26c | ||
|
|
71879266ac | ||
|
|
5ced0a1d4b | ||
|
|
908e361985 | ||
|
|
797affae4d | ||
|
|
ae3b825e29 | ||
|
|
143d97a73b | ||
|
|
90631c54b1 | ||
|
|
478e2998a8 | ||
|
|
9406305b2e | ||
|
|
1c26c81b20 | ||
|
|
a455de88b0 | ||
|
|
fba6942d5f | ||
|
|
3115efb672 | ||
|
|
fd70c031cb | ||
|
|
a2eb75df68 | ||
|
|
4a62d7eba6 | ||
|
|
40d2d2fe06 | ||
|
|
d5d2cb5937 | ||
|
|
854100c075 | ||
|
|
5837b26208 | ||
|
|
da0e654e7d | ||
|
|
a3e9932be7 | ||
|
|
e82353b4d9 | ||
|
|
944b61f28c | ||
|
|
457c574865 | ||
|
|
089a509663 | ||
|
|
3bebaef969 | ||
|
|
37e8b4500e | ||
|
|
8537ddf8a6 | ||
|
|
346b1e0a6b | ||
|
|
fc7b9660a5 | ||
|
|
21e5cc22c7 | ||
|
|
3f18b37e5f | ||
|
|
5d4a90e9bd | ||
|
|
2bf9f4f062 | ||
|
|
d69490cb49 | ||
|
|
4e460c11ca | ||
|
|
9313969314 | ||
|
|
a40f89a922 | ||
|
|
e0d8410b62 | ||
|
|
bef1bd8ad1 | ||
|
|
81b4fcfac1 | ||
|
|
f1e4a3c65d | ||
|
|
65622b01f6 | ||
|
|
87dd5f13fd | ||
|
|
79cd2c17ba | ||
|
|
85fb08552e | ||
|
|
7bd4b6faf7 | ||
|
|
0b1ae7e295 | ||
|
|
35a893ad9e | ||
|
|
4955ed18f1 | ||
|
|
fe462328ab | ||
|
|
5136d92efa | ||
|
|
227f7872cb | ||
|
|
725b2fdc35 | ||
|
|
75abc8059f | ||
|
|
f1193743c8 | ||
|
|
109730eacd | ||
|
|
1f736afe86 | ||
|
|
4d554a6718 | ||
|
|
69c0c362e9 | ||
|
|
3bb446556a | ||
|
|
ea950d8cec | ||
|
|
a65f4da7a2 | ||
|
|
0bdc933c20 | ||
|
|
0c0f79c6db | ||
|
|
32f9b9d4ac | ||
|
|
53907a3719 | ||
|
|
4937aeee3f | ||
|
|
5e5b8aff89 | ||
|
|
a2cbbd82d0 | ||
|
|
7eac5d8ba8 | ||
|
|
e2b1ed55ae | ||
|
|
727c7102d3 | ||
|
|
1494ea6717 | ||
|
|
f1ce64dbd3 | ||
|
|
3bad5cd2bf | ||
|
|
7432c0073a | ||
|
|
f1813a7c94 | ||
|
|
9e45c0a4d1 | ||
|
|
2c652cdde7 | ||
|
|
7718d345c8 | ||
|
|
9f39708325 | ||
|
|
bb6dbfa920 | ||
|
|
ba265005bb | ||
|
|
4d7cc7ed61 | ||
|
|
b64f31eb0b | ||
|
|
38d159b69e | ||
|
|
d5455f3716 | ||
|
|
a72ceeba11 | ||
|
|
c6b7d332b2 | ||
|
|
f37278f2a6 | ||
|
|
3f3e03b83d | ||
|
|
c99d3eb3c3 | ||
|
|
08d5183e7e | ||
|
|
51769b2224 | ||
|
|
6ec0ed8d61 | ||
|
|
2e35324403 | ||
|
|
e9474649c4 | ||
|
|
a8e0ce50c8 | ||
|
|
db7ddba735 | ||
|
|
1999d94b33 | ||
|
|
44af123b6c | ||
|
|
547b700ba7 | ||
|
|
6b87d5d2b0 | ||
|
|
023894d45e | ||
|
|
009715c0da | ||
|
|
c2824027d4 | ||
|
|
65b6553a1a | ||
|
|
9d3b7adc8e | ||
|
|
3724fc204c | ||
|
|
b97451a915 | ||
|
|
9ddcac4c6c | ||
|
|
b61e3c347f | ||
|
|
0bb44066c0 | ||
|
|
305c4aaa07 | ||
|
|
42d627f3ba | ||
|
|
6dd2b464a3 | ||
|
|
32f24cf8f8 | ||
|
|
4a89e3ea86 | ||
|
|
887db5b281 | ||
|
|
fee5518a82 | ||
|
|
551128e64c | ||
|
|
c65ae8d18e | ||
|
|
c1f75d9ebd | ||
|
|
73a5ff6648 | ||
|
|
1c264f380e | ||
|
|
f02bfa0a1e | ||
|
|
9d684006fc | ||
|
|
c49f1ed028 | ||
|
|
d935b226c0 | ||
|
|
d9e20de8a5 | ||
|
|
23997f0f93 | ||
|
|
529272d11b | ||
|
|
1194c38568 | ||
|
|
f0d2ee2beb | ||
|
|
68cdda086a | ||
|
|
54ceca6ceb | ||
|
|
50bdf7460c | ||
|
|
c06e45d0bb | ||
|
|
3ed6e28a00 | ||
|
|
ab76098895 | ||
|
|
0a447e43b0 | ||
|
|
8df44f2768 | ||
|
|
a7ec64d644 | ||
|
|
868e104d85 | ||
|
|
7ced7f5764 | ||
|
|
12b39c6ba1 | ||
|
|
93df9d7693 | ||
|
|
3980f314fa | ||
|
|
c2538da1cd | ||
|
|
5ed943bca2 | ||
|
|
d6a0563319 | ||
|
|
af82a94b87 | ||
|
|
82219e6111 | ||
|
|
81f9c55c7f | ||
|
|
0640f278cc | ||
|
|
769b5c6bab | ||
|
|
bdd569e213 | ||
|
|
5bfff5bc24 | ||
|
|
edf32496e4 | ||
|
|
785f5837d1 | ||
|
|
8c9272bc9f | ||
|
|
3e00735b3d | ||
|
|
00a1be8666 | ||
|
|
a2783d3c8a | ||
|
|
85d1a8a4a4 | ||
|
|
bbfb8354bb | ||
|
|
2f68e47443 | ||
|
|
89339ffb29 | ||
|
|
0535862fe6 | ||
|
|
a9e5fd4589 | ||
|
|
a3f3a28ea1 | ||
|
|
59020df965 | ||
|
|
ac01be79bf | ||
|
|
de5951f208 | ||
|
|
ded9a561db | ||
|
|
a2c18eb343 | ||
|
|
0b27c3a342 | ||
|
|
9c86cfb508 | ||
|
|
7e5e6ed6c2 | ||
|
|
d081e5f40b | ||
|
|
344ae0738c | ||
|
|
1b553f67b0 | ||
|
|
bf0adad427 | ||
|
|
11ca42a527 | ||
|
|
4898e4c7bf | ||
|
|
d494e0b9e3 | ||
|
|
be26ab249b | ||
|
|
611d8d5513 | ||
|
|
95c93b7c3d | ||
|
|
1dd0c49eec | ||
|
|
5d8e0e61ad | ||
|
|
478126e256 | ||
|
|
80704e489d | ||
|
|
3c0aa03643 | ||
|
|
37cd00d347 | ||
|
|
859c4d706f | ||
|
|
7289fe6e25 | ||
|
|
0c33977f5a | ||
|
|
4d4466e801 | ||
|
|
79330d7cdb | ||
|
|
680ce1098b | ||
|
|
2337d705ec | ||
|
|
d2880a818f | ||
|
|
86ea128bf4 | ||
|
|
a66f378622 | ||
|
|
265f88584b | ||
|
|
686394c861 | ||
|
|
8bad158ab4 | ||
|
|
5e59e7ec86 | ||
|
|
8bb0a48720 | ||
|
|
b4468b4eba | ||
|
|
0725bd1b30 | ||
|
|
ebd80243e0 | ||
|
|
f1ac469058 | ||
|
|
2e0b603d25 | ||
|
|
1d90a40f66 | ||
|
|
1bec3f507e | ||
|
|
1d5ecbb3ab | ||
|
|
e1a4aeb9da | ||
|
|
43f1bb4d85 | ||
|
|
8b7a0e9b15 | ||
|
|
da329e19d1 | ||
|
|
b8260d4e91 | ||
|
|
345e32aaf0 | ||
|
|
d7bef8c5b5 | ||
|
|
b2f82df4d3 | ||
|
|
83596b3d1f | ||
|
|
0022598a1c | ||
|
|
f4294d3752 | ||
|
|
a1444c0b39 | ||
|
|
e1d5359d73 | ||
|
|
239bf749b6 | ||
|
|
2bf3b1e172 | ||
|
|
d225de201f | ||
|
|
c3b8a3852d | ||
|
|
c31dab888e | ||
|
|
d4cf59bd2f | ||
|
|
d5edc3acd3 | ||
|
|
130286e8c2 | ||
|
|
a9baa52309 | ||
|
|
3001996298 | ||
|
|
bfcd18aabb | ||
|
|
96aa299e7e | ||
|
|
24faa34418 | ||
|
|
21bf08a6b3 | ||
|
|
d5db96b913 | ||
|
|
a8455af16d | ||
|
|
2290b14532 | ||
|
|
90c5a6311b | ||
|
|
6e0ad3623b | ||
|
|
005e02a1fa | ||
|
|
10fb8060fa | ||
|
|
35b933730b | ||
|
|
7ab9467069 | ||
|
|
598312ba61 | ||
|
|
985aa5c43a | ||
|
|
10eff95a42 | ||
|
|
d27d6d5d9d | ||
|
|
b8c109848e | ||
|
|
8b7f832c0f | ||
|
|
7cce0f48e5 | ||
|
|
8a56838111 | ||
|
|
ff15e00003 | ||
|
|
f60d2c51fb | ||
|
|
6dfb969015 | ||
|
|
da7e9fc4b3 | ||
|
|
70385c4115 | ||
|
|
51ba740413 | ||
|
|
f3e3ba8864 | ||
|
|
07cf65c1ec | ||
|
|
eca5b1c096 | ||
|
|
c74ce14ad1 | ||
|
|
f59c56506f | ||
|
|
896eef1ee4 | ||
|
|
ec0123eec7 | ||
|
|
78f56b9b33 | ||
|
|
1d88ed85bc | ||
|
|
2b7986da19 | ||
|
|
c3d22968e1 | ||
|
|
0e25122ee2 | ||
|
|
4504d84aa8 | ||
|
|
2b87cadba3 | ||
|
|
21dc83c641 | ||
|
|
3b593f349c | ||
|
|
962c215e3b | ||
|
|
42dcfdbcdc | ||
|
|
6d7e6ec871 | ||
|
|
36d53a3bcb | ||
|
|
ea9e61c2e1 | ||
|
|
a52c26102b | ||
|
|
e31c87b8a8 | ||
|
|
cc165a6897 | ||
|
|
f99910d802 | ||
|
|
997b0b3710 | ||
|
|
ec7064083a | ||
|
|
07cccfddd6 | ||
|
|
f07527cd06 | ||
|
|
7b273c4bd1 | ||
|
|
d36e7987b3 | ||
|
|
bbd5686816 | ||
|
|
fb1152d8f4 | ||
|
|
7a306118f5 | ||
|
|
efaf3ee8f5 | ||
|
|
2e4fe90956 | ||
|
|
e33d572104 | ||
|
|
2b2af9e455 | ||
|
|
d003597662 | ||
|
|
ec0a8f5a8b | ||
|
|
49ba57f20a | ||
|
|
6f4d1183cc | ||
|
|
dd18c9fff8 | ||
|
|
21f5f78ff1 | ||
|
|
1729f389db | ||
|
|
6d37bb7bac | ||
|
|
957adfad7a | ||
|
|
3ef889e17d | ||
|
|
c73af7390f | ||
|
|
c5b4376486 | ||
|
|
ba65049dd8 | ||
|
|
ee58aab0a9 | ||
|
|
859eaa2278 | ||
|
|
79f770e687 | ||
|
|
8ff4de67a1 |
@@ -1,114 +0,0 @@
|
||||
version: 2.1
|
||||
executors:
|
||||
unity:
|
||||
# https://hub.docker.com/r/gableroux/unity3d/tags
|
||||
parameters:
|
||||
version: {type: string}
|
||||
docker:
|
||||
- image: gableroux/unity3d:<< parameters.version >>
|
||||
go:
|
||||
docker:
|
||||
- image: circleci/golang
|
||||
commands:
|
||||
unity_activate:
|
||||
parameters:
|
||||
unity_version: {type: string}
|
||||
unity_license: {type: string}
|
||||
steps:
|
||||
# get activation file, if fail to activate unity, use this key and activate from https://license.unity3d.com/manual
|
||||
- run: apt update && apt install libunwind8 -y
|
||||
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0
|
||||
- run: cat Unity_v<< parameters.unity_version >>.alf
|
||||
# get from UNITY_LICENSE envvar(base64 encoded(cat foo.ulf | base64 )), this file is generated from above manual activation
|
||||
- run: echo << parameters.unity_license >> | base64 -di >> .circleci/Unity.ulf
|
||||
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .circleci/Unity.ulf || exit 0
|
||||
jobs:
|
||||
build-and-test:
|
||||
parameters:
|
||||
unity_version: {type: string}
|
||||
unity_license: {type: string}
|
||||
executor:
|
||||
name: unity
|
||||
version: << parameters.unity_version >>
|
||||
steps:
|
||||
- checkout
|
||||
- unity_activate:
|
||||
unity_version: << parameters.unity_version >>
|
||||
unity_license: << parameters.unity_license >>
|
||||
- run:
|
||||
name: Build Linux(Mono)
|
||||
command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend Mono2x /BuildTarget StandaloneLinux64
|
||||
working_directory: .
|
||||
# TODO:check unity version and packages...
|
||||
# - run: ./bin/UnitTest/StandaloneLinux64_Mono2x/test
|
||||
build-and-create-package:
|
||||
parameters:
|
||||
unity_version: {type: string}
|
||||
unity_license: {type: string}
|
||||
executor:
|
||||
name: unity
|
||||
version: << parameters.unity_version >>
|
||||
steps:
|
||||
- checkout
|
||||
- unity_activate:
|
||||
unity_version: << parameters.unity_version >>
|
||||
unity_license: << parameters.unity_license >>
|
||||
- run:
|
||||
name: Export unitypackage
|
||||
command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
||||
working_directory: .
|
||||
- store_artifacts:
|
||||
path: ./UniRx.Async.unitypackage
|
||||
destination: /UniRx.Async.unitypackage
|
||||
# upload to github by ghr
|
||||
upload-github:
|
||||
executor: go
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: go get github.com/tcnksm/ghr
|
||||
- run: ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} ${CIRCLE_TAG} .
|
||||
- store_artifacts:
|
||||
path: UniRx.Async.unitypackage
|
||||
destination: UniRx.Async.unitypackage
|
||||
workflows:
|
||||
version: 2
|
||||
build-unity:
|
||||
jobs:
|
||||
# does not exists yet.
|
||||
# - build-and-test:
|
||||
# unity_version: 2019.3.0a2
|
||||
# unity_license: ${UNITY_LICENSE_2019_3}
|
||||
# - build-and-test:
|
||||
# unity_version: 2019.2.0b2
|
||||
# unity_license: ${UNITY_LICENSE_2019_2}
|
||||
- build-and-test:
|
||||
unity_version: 2019.1.2f1
|
||||
unity_license: ${UNITY_LICENSE_2019_1}
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
# test asmdef will not found.
|
||||
# - build-and-test:
|
||||
# unity_version: 2018.4.0f1
|
||||
# unity_license: ${UNITY_LICENSE_2018_4}
|
||||
# # UniTask minimum support version is 2018.3(C# 7.x)
|
||||
# - build-and-test:
|
||||
# unity_version: 2018.3.12f1
|
||||
# unity_license: ${UNITY_LICENSE_2018_3}
|
||||
- build-and-create-package:
|
||||
unity_version: 2019.1.2f1
|
||||
unity_license: ${UNITY_LICENSE_2019_1}
|
||||
filters:
|
||||
tags:
|
||||
only: /^\d\.\d\.\d.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- upload-github:
|
||||
requires:
|
||||
- build-and-create-package
|
||||
filters:
|
||||
tags:
|
||||
only: /^\d\.\d\.\d.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
80
.github/workflows/build-debug.yml
vendored
Normal file
80
.github/workflows/build-debug.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
name: Build-Debug
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
tags:
|
||||
- "!*" # not a tag push
|
||||
pull_request:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
jobs:
|
||||
build-dotnet:
|
||||
if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]'))"
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
NUGET_XMLDOC_MODE: skip
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
- run: dotnet test -c Debug ./src/UniTask.NetCoreTests/UniTask.NetCoreTests.csproj
|
||||
|
||||
build-unity:
|
||||
if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]')) && ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))"
|
||||
strategy:
|
||||
matrix:
|
||||
unity: ["2019.3.9f1", "2020.1.0b5"]
|
||||
include:
|
||||
- unity: 2019.3.9f1
|
||||
license: UNITY_2019_3
|
||||
- unity: 2020.1.0b5
|
||||
license: UNITY_2020_1
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
# with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags
|
||||
image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp
|
||||
steps:
|
||||
# Ubuntu 18.04 git is too old, use ppa latest git.
|
||||
- run: |
|
||||
apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa
|
||||
apt-get update && apt-get install --no-install-recommends -y git
|
||||
- uses: actions/checkout@v2
|
||||
- run: echo -n "$UNITY_LICENSE" >> .Unity.ulf
|
||||
env:
|
||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
||||
- name: Activate Unity, always returns a success. But if a subsequent run fails, the activation may have failed(if succeeded, shows `Next license update check is after` and not shows other message(like GUID != GUID). If fails not). In that case, upload the artifact's .alf file to https://license.unity3d.com/manual to get the .ulf file and set it to secrets.
|
||||
run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0
|
||||
|
||||
# Execute scripts: RuntimeUnitTestToolkit
|
||||
- name: Build UnitTest(Linux64, mono)
|
||||
run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend mono /BuildTarget StandaloneLinux64
|
||||
working-directory: src/UniTask
|
||||
- name: Execute UnitTest
|
||||
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_Mono2x/test
|
||||
|
||||
# Execute scripts: Export Package
|
||||
- name: Export unitypackage
|
||||
run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
||||
working-directory: src/UniTask
|
||||
|
||||
- name: check all .meta is commited
|
||||
run: |
|
||||
if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then
|
||||
echo "Detected .meta file generated. Do you forgot commit a .meta file?"
|
||||
exit 1
|
||||
else
|
||||
echo "Great, all .meta files are commited."
|
||||
fi
|
||||
working-directory: src/UniTask
|
||||
|
||||
# Store artifacts.
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: UniTask.unitypackage.zip
|
||||
path: ./src/UniTask/*.unitypackage
|
||||
31
.github/workflows/build-docs.yml
vendored
Normal file
31
.github/workflows/build-docs.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: build-docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- feature/docs
|
||||
|
||||
jobs:
|
||||
run-docfx:
|
||||
if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]'))"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: Cysharp/DocfxTemplate
|
||||
path: docs/_DocfxTemplate
|
||||
- uses: Kirbyrawr/docfx-action@master
|
||||
name: Docfx metadata
|
||||
with:
|
||||
args: metadata docs/docfx.json
|
||||
- uses: Kirbyrawr/docfx-action@master
|
||||
name: Docfx build
|
||||
with:
|
||||
args: build docs/docfx.json
|
||||
- name: Publish to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: docs/_site
|
||||
185
.github/workflows/build-release.yml
vendored
Normal file
185
.github/workflows/build-release.yml
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
name: build-release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "tag: git tag you want create. (sample 1.0.0)"
|
||||
required: true
|
||||
dry_run:
|
||||
description: "dry_run: true will never create relase/nuget."
|
||||
required: true
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
GIT_TAG: ${{ github.event.inputs.tag }}
|
||||
DRY_RUN: ${{ github.event.inputs.dry_run }}
|
||||
DRY_RUN_BRANCH_PREFIX: "test_release"
|
||||
DOTNET_SDK_VERISON_3: 3.1.x
|
||||
|
||||
jobs:
|
||||
update-packagejson:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TARGET_FILE: ./src/UniTask/Assets/Plugins/UniTask/package.json
|
||||
outputs:
|
||||
sha: ${{ steps.commit.outputs.sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: before
|
||||
run: cat ${{ env.TARGET_FILE}}
|
||||
- name: update package.json to version ${{ env.GIT_TAG }}
|
||||
run: sed -i -e "s/\(\"version\":\) \"\(.*\)\",/\1 \"${{ env.GIT_TAG }}\",/" ${{ env.TARGET_FILE }}
|
||||
- name: after
|
||||
run: cat ${{ env.TARGET_FILE}}
|
||||
- name: Commit files
|
||||
id: commit
|
||||
run: |
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git commit -m "feat: Update package.json to ${{ env.GIT_TAG }}" -a
|
||||
echo "::set-output name=sha::$(git rev-parse HEAD)"
|
||||
- name: check sha
|
||||
run: echo "SHA ${SHA}"
|
||||
env:
|
||||
SHA: ${{ steps.commit.outputs.sha }}
|
||||
- name: tag
|
||||
run: git tag ${{ env.GIT_TAG }}
|
||||
if: env.DRY_RUN == 'false'
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
tags: true
|
||||
if: env.DRY_RUN == 'false'
|
||||
- name: Push changes (dry_run)
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }}
|
||||
tags: false
|
||||
if: env.DRY_RUN == 'true'
|
||||
|
||||
build-dotnet:
|
||||
needs: [update-packagejson]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
NUGET_XMLDOC_MODE: skip
|
||||
steps:
|
||||
- run: echo ${{ needs.update-packagejson.outputs.sha }}
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ needs.update-packagejson.outputs.sha }}
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}"
|
||||
# build and pack
|
||||
- run: dotnet build -c Release -p:Version=${{ env.GIT_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
|
||||
# Store artifacts.
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: nuget
|
||||
path: ./publish/
|
||||
|
||||
build-unity:
|
||||
needs: [update-packagejson]
|
||||
strategy:
|
||||
matrix:
|
||||
unity: ["2019.3.9f1"]
|
||||
include:
|
||||
- unity: 2019.3.9f1
|
||||
license: UNITY_2019_3
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
container:
|
||||
# with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags
|
||||
image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp
|
||||
steps:
|
||||
# Ubuntu 18.04 git is too old, use ppa latest git.
|
||||
- run: |
|
||||
apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa
|
||||
apt-get update && apt-get install --no-install-recommends -y git
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ needs.update-packagejson.outputs.sha }}
|
||||
# activate Unity from manual license file(ulf)
|
||||
- run: echo -n "$UNITY_LICENSE" >> .Unity.ulf
|
||||
env:
|
||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
||||
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0
|
||||
|
||||
# Execute scripts: Export Package
|
||||
- name: Export unitypackage
|
||||
run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
||||
working-directory: src/UniTask
|
||||
|
||||
- name: check all .meta is commited
|
||||
run: |
|
||||
if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then
|
||||
echo "Detected .meta file generated. Do you forgot commit a .meta file?"
|
||||
exit 1
|
||||
else
|
||||
echo "Great, all .meta files are commited."
|
||||
fi
|
||||
working-directory: src/UniTask
|
||||
|
||||
# Store artifacts.
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: UniTask.${{ env.GIT_TAG }}.unitypackage
|
||||
path: ./src/UniTask/UniTask.${{ env.GIT_TAG }}.unitypackage
|
||||
|
||||
create-release:
|
||||
if: github.event.inputs.dry_run == 'false'
|
||||
needs: [update-packagejson, build-dotnet, build-unity]
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
NUGET_XMLDOC_MODE: skip
|
||||
steps:
|
||||
# setup dotnet for nuget push
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}"
|
||||
# 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
|
||||
|
||||
cleanup:
|
||||
if: github.event.inputs.dry_run == 'true'
|
||||
needs: [build-dotnet, build-unity]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Delete branch
|
||||
uses: dawidd6/action-delete-branch@v3
|
||||
with:
|
||||
github_token: ${{ github.token }}
|
||||
branches: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }}
|
||||
24
.github/workflows/stale.yml
vendored
Normal file
24
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: "Close stale issues"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# enable issue
|
||||
stale-issue-message: "This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days."
|
||||
stale-issue-label: "stale"
|
||||
# enable pr
|
||||
stale-pr-message: "This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days."
|
||||
stale-pr-label: "stale"
|
||||
days-before-stale: 90
|
||||
days-before-close: 7
|
||||
exempt-issue-labels: "wip"
|
||||
exempt-pr-labels: "wip"
|
||||
remove-stale-when-updated: true
|
||||
15
.github/workflows/toc.yml
vendored
Normal file
15
.github/workflows/toc.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: TOC Generator
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'README.md'
|
||||
|
||||
jobs:
|
||||
generateTOC:
|
||||
name: TOC Generator
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: technote-space/toc-generator@v2.4.0
|
||||
with:
|
||||
TOC_TITLE: "## Table of Contents"
|
||||
102
.gitignore
vendored
102
.gitignore
vendored
@@ -157,3 +157,105 @@ 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
|
||||
|
||||
10
docs/.gitignore
vendored
Normal file
10
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
###############
|
||||
# folder #
|
||||
###############
|
||||
/**/DROP/
|
||||
/**/TEMP/
|
||||
/**/packages/
|
||||
/**/bin/
|
||||
/**/obj/
|
||||
_site
|
||||
_DocfxTemplate
|
||||
5
docs/api/.gitignore
vendored
Normal file
5
docs/api/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
###############
|
||||
# temp file #
|
||||
###############
|
||||
*.yml
|
||||
.manifest
|
||||
70
docs/docfx.json
Normal file
70
docs/docfx.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"metadata": [
|
||||
{
|
||||
"src": [
|
||||
{
|
||||
"files": [
|
||||
"UniTask/Assets/Plugins/UniTask/Runtime/**/*.cs"
|
||||
],
|
||||
"src": "../src"
|
||||
}
|
||||
],
|
||||
"dest": "api",
|
||||
"disableGitFeatures": false,
|
||||
"disableDefaultFilter": false
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"globalMetadata": {
|
||||
"_disableContribution": true,
|
||||
"_appTitle": "UniTask"
|
||||
},
|
||||
"content": [
|
||||
{
|
||||
"files": [
|
||||
"api/**.yml",
|
||||
"api/index.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"articles/**.md",
|
||||
"articles/**/toc.yml",
|
||||
"toc.yml",
|
||||
"*.md"
|
||||
]
|
||||
}
|
||||
],
|
||||
"resource": [
|
||||
{
|
||||
"files": [
|
||||
"images/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"overwrite": [
|
||||
{
|
||||
"files": [
|
||||
"apidoc/**.md"
|
||||
],
|
||||
"exclude": [
|
||||
"obj/**",
|
||||
"_site/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"dest": "_site",
|
||||
|
||||
"globalMetadataFiles": [],
|
||||
"fileMetadataFiles": [],
|
||||
"template": [
|
||||
"_DocfxTemplate/templates/default-v2.5.2",
|
||||
"_DocfxTemplate/templates/cysharp"
|
||||
],
|
||||
"postProcessors": [],
|
||||
"markdownEngineName": "markdig",
|
||||
"noLangKeyword": false,
|
||||
"keepFileLink": false,
|
||||
"cleanupCacheHistory": false
|
||||
}
|
||||
}
|
||||
8
docs/index.md
Normal file
8
docs/index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Home
|
||||
---
|
||||
# UniTask
|
||||
|
||||
Provides an efficient async/await integration to Unity.
|
||||
|
||||
https://github.com/Cysharp/UniTask
|
||||
11
docs/toc.yml
Normal file
11
docs/toc.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
- name: API Documentation
|
||||
href: api/
|
||||
homepage: api/Cysharp.Threading.Tasks.html
|
||||
|
||||
- name: Repository
|
||||
href: https://github.com/Cysharp/UniTask
|
||||
homepage: https://github.com/Cysharp/UniTask
|
||||
|
||||
- name: Releases
|
||||
href: https://github.com/Cysharp/UniTask/releases
|
||||
homepage: https://github.com/Cysharp/UniTask/releases
|
||||
BIN
src/UniTask.NetCore/Icon.png
Normal file
BIN
src/UniTask.NetCore/Icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
101
src/UniTask.NetCore/NetCore/AsyncEnumerableExtensions.cs
Normal file
101
src/UniTask.NetCore/NetCore/AsyncEnumerableExtensions.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
#if !NETSTANDARD2_0
|
||||
|
||||
#pragma warning disable 0649
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Sources;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class AsyncEnumerableExtensions
|
||||
{
|
||||
public static IUniTaskAsyncEnumerable<T> AsUniTaskAsyncEnumerable<T>(this IAsyncEnumerable<T> source)
|
||||
{
|
||||
return new AsyncEnumerableToUniTaskAsyncEnumerable<T>(source);
|
||||
}
|
||||
|
||||
public static IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IUniTaskAsyncEnumerable<T> source)
|
||||
{
|
||||
return new UniTaskAsyncEnumerableToAsyncEnumerable<T>(source);
|
||||
}
|
||||
|
||||
sealed class AsyncEnumerableToUniTaskAsyncEnumerable<T> : IUniTaskAsyncEnumerable<T>
|
||||
{
|
||||
readonly IAsyncEnumerable<T> source;
|
||||
|
||||
public AsyncEnumerableToUniTaskAsyncEnumerable(IAsyncEnumerable<T> source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source.GetAsyncEnumerator(cancellationToken));
|
||||
}
|
||||
|
||||
sealed class Enumerator : IUniTaskAsyncEnumerator<T>
|
||||
{
|
||||
readonly IAsyncEnumerator<T> enumerator;
|
||||
|
||||
public Enumerator(IAsyncEnumerator<T> enumerator)
|
||||
{
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
public T Current => enumerator.Current;
|
||||
|
||||
public async UniTask DisposeAsync()
|
||||
{
|
||||
await enumerator.DisposeAsync();
|
||||
}
|
||||
|
||||
public async UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
return await enumerator.MoveNextAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class UniTaskAsyncEnumerableToAsyncEnumerable<T> : IAsyncEnumerable<T>
|
||||
{
|
||||
readonly IUniTaskAsyncEnumerable<T> source;
|
||||
|
||||
public UniTaskAsyncEnumerableToAsyncEnumerable(IUniTaskAsyncEnumerable<T> source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source.GetAsyncEnumerator(cancellationToken));
|
||||
}
|
||||
|
||||
sealed class Enumerator : IAsyncEnumerator<T>
|
||||
{
|
||||
readonly IUniTaskAsyncEnumerator<T> enumerator;
|
||||
|
||||
public Enumerator(IUniTaskAsyncEnumerator<T> enumerator)
|
||||
{
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
public T Current => enumerator.Current;
|
||||
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
}
|
||||
|
||||
public ValueTask<bool> MoveNextAsync()
|
||||
{
|
||||
return enumerator.MoveNextAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma warning disable 0649
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Sources;
|
||||
|
||||
@@ -9,115 +8,90 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class UniTaskValueTaskExtensions
|
||||
{
|
||||
public static ValueTask AsValueTask(this UniTask task)
|
||||
public static ValueTask AsValueTask(this in UniTask task)
|
||||
{
|
||||
ref var core = ref Unsafe.As<UniTask, UniTaskToValueTask>(ref task);
|
||||
if (core.source == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return new ValueTask(new UniTaskValueTaskSource(core.source), core.token);
|
||||
#if NETSTANDARD2_0
|
||||
return new ValueTask(new UniTaskValueTaskSource(task), 0);
|
||||
#else
|
||||
return task;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static ValueTask<T> AsValueTask<T>(this UniTask<T> task)
|
||||
public static ValueTask<T> AsValueTask<T>(this in UniTask<T> task)
|
||||
{
|
||||
ref var core = ref Unsafe.As<UniTask<T>, UniTaskToValueTask<T>>(ref task);
|
||||
if (core.source == null)
|
||||
{
|
||||
return new ValueTask<T>(core.result);
|
||||
}
|
||||
|
||||
return new ValueTask<T>(new UniTaskValueTaskSource<T>(core.source), core.token);
|
||||
#if NETSTANDARD2_0
|
||||
return new ValueTask<T>(new UniTaskValueTaskSource<T>(task), 0);
|
||||
#else
|
||||
return task;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct UniTaskToValueTask
|
||||
public static async UniTask<T> AsUniTask<T>(this ValueTask<T> task)
|
||||
{
|
||||
public IUniTaskSource source;
|
||||
public short token;
|
||||
return await task;
|
||||
}
|
||||
|
||||
public static async UniTask AsUniTask(this ValueTask task)
|
||||
{
|
||||
await task;
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
|
||||
class UniTaskValueTaskSource : IValueTaskSource
|
||||
{
|
||||
readonly IUniTaskSource source;
|
||||
readonly UniTask task;
|
||||
readonly UniTask.Awaiter awaiter;
|
||||
|
||||
public UniTaskValueTaskSource(IUniTaskSource source)
|
||||
public UniTaskValueTaskSource(UniTask task)
|
||||
{
|
||||
this.source = source;
|
||||
this.task = task;
|
||||
this.awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
source.GetResult(token);
|
||||
awaiter.GetResult();
|
||||
}
|
||||
|
||||
public ValueTaskSourceStatus GetStatus(short token)
|
||||
{
|
||||
var status = source.GetStatus(token);
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Pending:
|
||||
return ValueTaskSourceStatus.Pending;
|
||||
case UniTaskStatus.Succeeded:
|
||||
return ValueTaskSourceStatus.Succeeded;
|
||||
case UniTaskStatus.Faulted:
|
||||
return ValueTaskSourceStatus.Faulted;
|
||||
case UniTaskStatus.Canceled:
|
||||
return ValueTaskSourceStatus.Canceled;
|
||||
default:
|
||||
return (ValueTaskSourceStatus)status;
|
||||
}
|
||||
return (ValueTaskSourceStatus)task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
source.OnCompleted(continuation, state, token);
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
}
|
||||
|
||||
struct UniTaskToValueTask<T>
|
||||
{
|
||||
public IUniTaskSource<T> source;
|
||||
public T result;
|
||||
public short token;
|
||||
}
|
||||
|
||||
class UniTaskValueTaskSource<T> : IValueTaskSource<T>
|
||||
{
|
||||
readonly IUniTaskSource<T> source;
|
||||
readonly UniTask<T> task;
|
||||
readonly UniTask<T>.Awaiter awaiter;
|
||||
|
||||
public UniTaskValueTaskSource(IUniTaskSource<T> source)
|
||||
public UniTaskValueTaskSource(UniTask<T> task)
|
||||
{
|
||||
this.source = source;
|
||||
this.task = task;
|
||||
this.awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
return source.GetResult(token);
|
||||
return awaiter.GetResult();
|
||||
}
|
||||
|
||||
public ValueTaskSourceStatus GetStatus(short token)
|
||||
{
|
||||
var status = source.GetStatus(token);
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Pending:
|
||||
return ValueTaskSourceStatus.Pending;
|
||||
case UniTaskStatus.Succeeded:
|
||||
return ValueTaskSourceStatus.Succeeded;
|
||||
case UniTaskStatus.Faulted:
|
||||
return ValueTaskSourceStatus.Faulted;
|
||||
case UniTaskStatus.Canceled:
|
||||
return ValueTaskSourceStatus.Canceled;
|
||||
default:
|
||||
return (ValueTaskSourceStatus)status;
|
||||
}
|
||||
return (ValueTaskSourceStatus)task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
source.OnCompleted(continuation, state, token);
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
39
src/UniTask.NetCore/NetCore/UniTask.Delay.cs
Normal file
39
src/UniTask.NetCore/NetCore/UniTask.Delay.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
//using Cysharp.Threading.Tasks.Internal;
|
||||
//using System;
|
||||
//using System.Collections.Concurrent;
|
||||
//using System.Runtime.CompilerServices;
|
||||
//using System.Threading;
|
||||
|
||||
//namespace Cysharp.Threading.Tasks
|
||||
//{
|
||||
// public partial struct UniTask
|
||||
// {
|
||||
// public static UniTask Delay()
|
||||
// {
|
||||
// return default;
|
||||
// }
|
||||
|
||||
// sealed class DelayPromise : IUniTaskSource
|
||||
// {
|
||||
// public void GetResult(short token)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public UniTaskStatus GetStatus(short token)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public UniTaskStatus UnsafeGetStatus()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
@@ -41,7 +43,11 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
||||
#else
|
||||
ThreadPool.UnsafeQueueUserWorkItem(WaitCallbackDelegate, continuation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +56,48 @@ namespace Cysharp.Threading.Tasks
|
||||
((Action)state).Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1
|
||||
|
||||
sealed class ThreadPoolWorkItem : IThreadPoolWorkItem, ITaskPoolNode<ThreadPoolWorkItem>
|
||||
{
|
||||
static TaskPool<ThreadPoolWorkItem> pool;
|
||||
ThreadPoolWorkItem nextNode;
|
||||
public ref ThreadPoolWorkItem NextNode => ref nextNode;
|
||||
|
||||
static ThreadPoolWorkItem()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(ThreadPoolWorkItem), () => pool.Size);
|
||||
}
|
||||
|
||||
Action continuation;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ThreadPoolWorkItem Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryPop(out var item))
|
||||
{
|
||||
item = new ThreadPoolWorkItem();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Execute()
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
if (call != null)
|
||||
{
|
||||
pool.TryPush(this);
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1;netstandard2.1;netstandard2.0</TargetFrameworks>
|
||||
<AssemblyName>UniTask</AssemblyName>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
|
||||
|
||||
<!-- 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>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Icon.png" Pack="true" PackagePath="/" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\UniTask\Assets\Plugins\UniTask\Runtime\**\*.cs"
|
||||
Exclude="
|
||||
@@ -16,7 +35,10 @@
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityEqualityComparer.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\DiagnosticsExtensions.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\PlayerLoopRunner.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\ContinuationQueue.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityWebRequestExtensions.cs;
|
||||
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UniTaskSynchronizationContext.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\CancellationTokenSourceExtensions.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\EnumeratorAsyncExtensions.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopHelper.cs;
|
||||
@@ -24,9 +46,8 @@
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Run.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Bridge.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.WaitUntil.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.uGUI.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.MonoBehaviour.cs;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.*;
|
||||
..\UniTask\Assets\Plugins\UniTask\Runtime\UnityBindingExtensions.cs;
|
||||
" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
258
src/UniTask.NetCoreSandbox/AllocationCheck.cs
Normal file
258
src/UniTask.NetCoreSandbox/AllocationCheck.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Exporters;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PooledAwait;
|
||||
using System;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Cysharp.Threading.Tasks.CompilerServices;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
[Config(typeof(BenchmarkConfig))]
|
||||
public class AllocationCheck
|
||||
{
|
||||
// note: all the benchmarks use Task/Task<T> for the public API, because BenchmarkDotNet
|
||||
// doesn't work reliably with more exotic task-types (even just ValueTask fails); instead,
|
||||
// we'll obscure the cost of the outer awaitable by doing a relatively large number of
|
||||
// iterations, so that we're only really measuring the inner loop
|
||||
private const int InnerOps = 1000;
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps)]
|
||||
public async Task ViaUniTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
{
|
||||
var a = Core();
|
||||
var b = Core();
|
||||
var c = Core();
|
||||
await a;
|
||||
await b;
|
||||
await c;
|
||||
}
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps)]
|
||||
public async Task<int> ViaUniTaskT()
|
||||
{
|
||||
var sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
{
|
||||
var a = Core();
|
||||
var b = Core();
|
||||
var c = Core();
|
||||
sum += await a;
|
||||
sum += await b;
|
||||
sum += await c;
|
||||
}
|
||||
return sum;
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
var a = await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
|
||||
var b = await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
|
||||
var c = await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
//[Benchmark(OperationsPerInvoke = InnerOps)]
|
||||
//[Benchmark]
|
||||
public void ViaUniTaskVoid()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
{
|
||||
Core().Forget();
|
||||
Core().Forget();
|
||||
Core().Forget();
|
||||
}
|
||||
|
||||
static async UniTaskVoid Core()
|
||||
{
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo : IAsyncStateMachine
|
||||
{
|
||||
public AsyncUniTaskVoidMethodBuilder builder;
|
||||
public TestAwaiter awaiter;
|
||||
public TestAwaiter awaiterawaiter;
|
||||
|
||||
public int state;
|
||||
|
||||
public void MoveNext()
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case -1:
|
||||
awaiterawaiter = awaiter.GetAwaiter();
|
||||
if (awaiterawaiter.IsCompleted)
|
||||
{
|
||||
goto case 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 0;
|
||||
builder.AwaitUnsafeOnCompleted(ref awaiterawaiter, ref this);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0:
|
||||
default:
|
||||
goto END;
|
||||
}
|
||||
|
||||
END:
|
||||
builder.SetResult();
|
||||
}
|
||||
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskTestException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public struct TestAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public TestAwaiter GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public struct TestAwaiter<T> : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
readonly T value;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status, T value)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TestAwaiter<T> GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ThreadPoolWorkItem : IThreadPoolWorkItem
|
||||
{
|
||||
public static readonly ConcurrentQueue<ThreadPoolWorkItem> pool = new ConcurrentQueue<ThreadPoolWorkItem>();
|
||||
|
||||
public static void CreatePoolItems(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
pool.Enqueue(new ThreadPoolWorkItem());
|
||||
}
|
||||
}
|
||||
|
||||
Action continuation;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ThreadPoolWorkItem Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryDequeue(out var item))
|
||||
{
|
||||
item = new ThreadPoolWorkItem();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Execute()
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
pool.Enqueue(this);
|
||||
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
283
src/UniTask.NetCoreSandbox/Benchmark.cs
Normal file
283
src/UniTask.NetCoreSandbox/Benchmark.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Exporters;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PooledAwait;
|
||||
using System;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Cysharp.Threading.Tasks.CompilerServices;
|
||||
|
||||
//class Program
|
||||
//{
|
||||
// static void Main(string[] args)
|
||||
// {
|
||||
// var switcher = new BenchmarkSwitcher(new[]
|
||||
// {
|
||||
// typeof(StandardBenchmark)
|
||||
// });
|
||||
|
||||
//#if DEBUG
|
||||
// var b = new StandardBenchmark();
|
||||
|
||||
//#else
|
||||
// switcher.Run(args);
|
||||
//#endif
|
||||
// }
|
||||
//}
|
||||
|
||||
public class BenchmarkConfig : ManualConfig
|
||||
{
|
||||
public BenchmarkConfig()
|
||||
{
|
||||
AddDiagnoser(MemoryDiagnoser.Default);
|
||||
AddJob(Job.ShortRun.WithLaunchCount(1).WithIterationCount(1).WithWarmupCount(1)/*.RunOncePerIteration()*/);
|
||||
}
|
||||
}
|
||||
|
||||
// borrowed from PooledAwait
|
||||
|
||||
[Config(typeof(BenchmarkConfig))]
|
||||
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
|
||||
[CategoriesColumn]
|
||||
public class ComparisonBenchmarks
|
||||
{
|
||||
// note: all the benchmarks use Task/Task<T> for the public API, because BenchmarkDotNet
|
||||
// doesn't work reliably with more exotic task-types (even just ValueTask fails); instead,
|
||||
// we'll obscure the cost of the outer awaitable by doing a relatively large number of
|
||||
// iterations, so that we're only really measuring the inner loop
|
||||
private const int InnerOps = 1000;
|
||||
|
||||
public bool ConfigureAwait { get; set; } = false;
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = ".NET")]
|
||||
[BenchmarkCategory("Task<T>")]
|
||||
public async Task<int> ViaTaskT()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
sum += await Inner(1, 2).ConfigureAwait(ConfigureAwait);
|
||||
return sum;
|
||||
|
||||
static async Task<int> Inner(int x, int y)
|
||||
{
|
||||
int i = x;
|
||||
await Task.Yield();
|
||||
i *= y;
|
||||
await Task.Yield();
|
||||
return 5 * i;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = ".NET")]
|
||||
[BenchmarkCategory("Task")]
|
||||
public async Task ViaTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
await Inner().ConfigureAwait(ConfigureAwait);
|
||||
|
||||
static async Task Inner()
|
||||
{
|
||||
await Task.Yield();
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = ".NET")]
|
||||
[BenchmarkCategory("ValueTask<T>")]
|
||||
public async Task<int> ViaValueTaskT()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
sum += await Inner(1, 2).ConfigureAwait(ConfigureAwait);
|
||||
return sum;
|
||||
|
||||
static async ValueTask<int> Inner(int x, int y)
|
||||
{
|
||||
int i = x;
|
||||
await Task.Yield();
|
||||
i *= y;
|
||||
await Task.Yield();
|
||||
return 5 * i;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = ".NET")]
|
||||
[BenchmarkCategory("ValueTask")]
|
||||
public async Task ViaValueTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
await Inner().ConfigureAwait(ConfigureAwait);
|
||||
|
||||
static async ValueTask Inner()
|
||||
{
|
||||
await Task.Yield();
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "Pooled")]
|
||||
[BenchmarkCategory("ValueTask<T>")]
|
||||
public async Task<int> ViaPooledValueTaskT()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
sum += await Inner(1, 2).ConfigureAwait(ConfigureAwait);
|
||||
return sum;
|
||||
|
||||
static async PooledValueTask<int> Inner(int x, int y)
|
||||
{
|
||||
int i = x;
|
||||
await Task.Yield();
|
||||
i *= y;
|
||||
await Task.Yield();
|
||||
return 5 * i;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "Pooled")]
|
||||
[BenchmarkCategory("ValueTask")]
|
||||
public async Task ViaPooledValueTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
await Inner().ConfigureAwait(ConfigureAwait);
|
||||
|
||||
static async PooledValueTask Inner()
|
||||
{
|
||||
await Task.Yield();
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "Pooled")]
|
||||
[BenchmarkCategory("Task<T>")]
|
||||
public async Task<int> ViaPooledTaskT()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
sum += await Inner(1, 2).ConfigureAwait(ConfigureAwait);
|
||||
return sum;
|
||||
|
||||
static async PooledTask<int> Inner(int x, int y)
|
||||
{
|
||||
int i = x;
|
||||
await Task.Yield();
|
||||
i *= y;
|
||||
await Task.Yield();
|
||||
return 5 * i;
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "Pooled")]
|
||||
[BenchmarkCategory("Task")]
|
||||
public async Task ViaPooledTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
await Inner().ConfigureAwait(ConfigureAwait);
|
||||
|
||||
static async PooledTask Inner()
|
||||
{
|
||||
await Task.Yield();
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
//[Benchmark(OperationsPerInvoke = InnerOps, Description = "UniTaskVoid")]
|
||||
//[BenchmarkCategory("UniTask")]
|
||||
//public async Task ViaUniTaskVoid()
|
||||
//{
|
||||
// for (int i = 0; i < InnerOps; i++)
|
||||
// {
|
||||
// await Inner();
|
||||
// }
|
||||
|
||||
// static async UniTaskVoid Inner()
|
||||
// {
|
||||
// await UniTask.Yield();
|
||||
// await UniTask.Yield();
|
||||
// }
|
||||
//}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "UniTask")]
|
||||
[BenchmarkCategory("UniTask")]
|
||||
public async Task ViaUniTask()
|
||||
{
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
{
|
||||
await Inner();
|
||||
}
|
||||
|
||||
static async UniTask Inner()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
await UniTask.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark(OperationsPerInvoke = InnerOps, Description = "UniTaskT")]
|
||||
[BenchmarkCategory("UniTask")]
|
||||
public async Task<int> ViaUniTaskT()
|
||||
{
|
||||
var sum = 0;
|
||||
for (int i = 0; i < InnerOps; i++)
|
||||
{
|
||||
sum += await Inner(1, 2);
|
||||
}
|
||||
return sum;
|
||||
|
||||
static async UniTask<int> Inner(int x, int y)
|
||||
{
|
||||
int i = x;
|
||||
await UniTask.Yield();
|
||||
i *= y;
|
||||
await UniTask.Yield();
|
||||
return 5 * i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
public MyAwaiter GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => false;
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
continuation();
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
continuation();
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyTestStateMachine : IAsyncStateMachine
|
||||
{
|
||||
public void MoveNext()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
#pragma warning disable CS1998
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
using System.Linq;
|
||||
using System;
|
||||
@@ -15,6 +17,193 @@ using System.Reactive.Concurrency;
|
||||
|
||||
namespace NetCoreSandbox
|
||||
{
|
||||
public class MySyncContext : SynchronizationContext
|
||||
{
|
||||
public MySyncContext()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Post(SendOrPostCallback d, object state)
|
||||
{
|
||||
Console.WriteLine("Called SyncContext Post!");
|
||||
base.Post(d, state);
|
||||
}
|
||||
}
|
||||
|
||||
public class Text
|
||||
{
|
||||
|
||||
public string text { get; set; }
|
||||
}
|
||||
|
||||
public class ZeroAllocAsyncAwaitInDotNetCore
|
||||
{
|
||||
public ValueTask<int> NanikaAsync(int x, int y)
|
||||
{
|
||||
return Core(this, x, y);
|
||||
|
||||
static async UniTask<int> Core(ZeroAllocAsyncAwaitInDotNetCore self, int x, int y)
|
||||
{
|
||||
// nanika suru...
|
||||
await Task.Delay(TimeSpan.FromSeconds(x + y));
|
||||
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TaskTestException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Foo
|
||||
{
|
||||
public async UniTask MethodFooAsync()
|
||||
{
|
||||
await MethodBarAsync();
|
||||
}
|
||||
|
||||
private async UniTask MethodBarAsync()
|
||||
|
||||
{
|
||||
Throw();
|
||||
}
|
||||
|
||||
private void Throw()
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public struct TestAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public TestAwaiter GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
}
|
||||
public struct TestAwaiter<T> : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
readonly T value;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status, T value)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TestAwaiter<T> GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static partial class UnityUIComponentExtensions
|
||||
{
|
||||
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, Text text)
|
||||
{
|
||||
AAAACORECORE(source, text).Forget();
|
||||
|
||||
async UniTaskVoid AAAACORECORE(IUniTaskAsyncEnumerable<string> source2, Text text2)
|
||||
{
|
||||
var e = source2.GetAsyncEnumerator();
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
text2.text = e.Current;
|
||||
// action(e.Current);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//public static IDisposable SubscribeToText<T>(this IObservable<T> source, Text text)
|
||||
//{
|
||||
// return source.SubscribeWithState(text, (x, t) => t.text = x.ToString());
|
||||
//}
|
||||
|
||||
//public static IDisposable SubscribeToText<T>(this IObservable<T> source, Text text, Func<T, string> selector)
|
||||
//{
|
||||
// return source.SubscribeWithState2(text, selector, (x, t, s) => t.text = s(x));
|
||||
//}
|
||||
|
||||
//public static IDisposable SubscribeToInteractable(this IObservable<bool> source, Selectable selectable)
|
||||
//{
|
||||
// return source.SubscribeWithState(selectable, (x, s) => s.interactable = x);
|
||||
//}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static string FlattenGenArgs(Type type)
|
||||
@@ -37,33 +226,116 @@ namespace NetCoreSandbox
|
||||
await Task.Delay(10, cancellationToken);
|
||||
}
|
||||
|
||||
static async Task Main(string[] args)
|
||||
public class MyDisposable : IDisposable
|
||||
{
|
||||
await foreach (var item in UniTaskAsyncEnumerable.Range(1, 10)
|
||||
.SelectAwait(x => UniTask.Run(() => x))
|
||||
.TakeLast(6)
|
||||
|
||||
|
||||
|
||||
)
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void Test()
|
||||
{
|
||||
var disp = new MyDisposable();
|
||||
|
||||
using var _ = new MyDisposable();
|
||||
|
||||
Console.WriteLine("tako");
|
||||
}
|
||||
|
||||
|
||||
static async UniTask FooBarAsync()
|
||||
{
|
||||
await using (UniTask.ReturnToCurrentSynchronizationContext())
|
||||
{
|
||||
await UniTask.SwitchToThreadPool();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static async UniTask Aaa()
|
||||
{
|
||||
await FooBarAsync();
|
||||
|
||||
Console.WriteLine("FooBarAsync End");
|
||||
}
|
||||
|
||||
static async UniTask WhereSelect()
|
||||
{
|
||||
await foreach (var item in UniTaskAsyncEnumerable.Range(1, 10)
|
||||
.SelectAwait(async x =>
|
||||
{
|
||||
await UniTask.Yield();
|
||||
return x;
|
||||
})
|
||||
.Where(x => x % 2 == 0))
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
// AsyncEnumerable.Range(1,10).FirstAsync(
|
||||
// AsyncEnumerable.Range(1, 10).GroupBy(x=>x).Select(x=>x.first
|
||||
}
|
||||
|
||||
|
||||
// AsyncEnumerable.Range(1,10).WithCancellation(CancellationToken.None).WithCancellation
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
#if !DEBUG
|
||||
|
||||
|
||||
|
||||
|
||||
//Enumerable.Range(1,10).ToHashSet(
|
||||
//await new AllocationCheck().ViaUniTaskVoid();
|
||||
//Console.ReadLine();
|
||||
BenchmarkDotNet.Running.BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
|
||||
|
||||
//await new ComparisonBenchmarks().ViaUniTaskT();
|
||||
return;
|
||||
#endif
|
||||
|
||||
var e = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Console.WriteLine($"Start {i}");
|
||||
await writer.YieldAsync(i);
|
||||
Console.WriteLine($"End {i}");
|
||||
}
|
||||
});
|
||||
|
||||
var ee = e.GetAsyncEnumerator();
|
||||
while (await ee.MoveNextAsync())
|
||||
{
|
||||
Console.WriteLine("ForEach " + ee.Current);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static async UniTask YieldCore()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998
|
||||
|
||||
|
||||
static async UniTask<int> AsyncTest()
|
||||
{
|
||||
// empty
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(true, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma warning restore CS1998
|
||||
|
||||
void Foo()
|
||||
{
|
||||
|
||||
473
src/UniTask.NetCoreSandbox/QueueCheck.cs
Normal file
473
src/UniTask.NetCoreSandbox/QueueCheck.cs
Normal file
@@ -0,0 +1,473 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
[Config(typeof(BenchmarkConfig))]
|
||||
public class QueueCheck
|
||||
{
|
||||
Node node1 = new Node();
|
||||
Node node2 = new Node();
|
||||
RefNode refNode1 = new RefNode();
|
||||
RefNode refNode2 = new RefNode();
|
||||
Queue<Node> q1 = new Queue<Node>();
|
||||
Stack<Node> s1 = new Stack<Node>();
|
||||
ConcurrentQueue<Node> cq = new ConcurrentQueue<Node>();
|
||||
ConcurrentStack<Node> cs = new ConcurrentStack<Node>();
|
||||
static TaskPool<Node> pool;
|
||||
static TaskPoolRefNode<RefNode> poolRefNode;
|
||||
static TaskPoolEqualNull<Node> poolEqualNull;
|
||||
static TaskPoolClass<Node> poolClass = new TaskPoolClass<Node>();
|
||||
static TaskPoolWithoutSize<Node> poolWithoutSize;
|
||||
static TaskPoolWithoutLock<Node> poolWithoutLock;
|
||||
|
||||
[Benchmark]
|
||||
public void Queue()
|
||||
{
|
||||
q1.Enqueue(node1);
|
||||
q1.Enqueue(node1);
|
||||
q1.TryDequeue(out _);
|
||||
q1.TryDequeue(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void QueueLock()
|
||||
{
|
||||
lock (q1) { q1.Enqueue(node1); }
|
||||
lock (q1) { q1.Enqueue(node1); }
|
||||
lock (q1) { q1.TryDequeue(out _); }
|
||||
lock (q1) { q1.TryDequeue(out _); }
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Stack()
|
||||
{
|
||||
s1.Push(node1);
|
||||
s1.Push(node2);
|
||||
s1.TryPop(out _);
|
||||
s1.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void StackLock()
|
||||
{
|
||||
lock (s1) { s1.Push(node1); }
|
||||
lock (s1) { s1.Push(node2); }
|
||||
lock (s1) { s1.TryPop(out _); }
|
||||
lock (s1) { s1.TryPop(out _); }
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void ConcurrentQueue()
|
||||
{
|
||||
cq.Enqueue(node1);
|
||||
cq.Enqueue(node1);
|
||||
cq.TryDequeue(out _);
|
||||
cq.TryDequeue(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void ConcurrentStack()
|
||||
{
|
||||
cs.Push(node1);
|
||||
cs.Push(node2);
|
||||
cs.TryPop(out _);
|
||||
cs.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TaskPool()
|
||||
{
|
||||
pool.TryPush(node1);
|
||||
pool.TryPush(node2);
|
||||
pool.TryPop(out _);
|
||||
pool.TryPop(out _);
|
||||
}
|
||||
[Benchmark]
|
||||
public void TaskPoolRefNode()
|
||||
{
|
||||
poolRefNode.TryPush(refNode1);
|
||||
poolRefNode.TryPush(refNode2);
|
||||
poolRefNode.TryPop(out _);
|
||||
poolRefNode.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TaskPoolEqualNull()
|
||||
{
|
||||
poolEqualNull.TryPush(node1);
|
||||
poolEqualNull.TryPush(node2);
|
||||
poolEqualNull.TryPop(out _);
|
||||
poolEqualNull.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TaskPoolClass()
|
||||
{
|
||||
poolClass.TryPush(node1);
|
||||
poolClass.TryPush(node2);
|
||||
poolClass.TryPop(out _);
|
||||
poolClass.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TaskPoolWithoutSize()
|
||||
{
|
||||
poolWithoutSize.TryPush(node1);
|
||||
poolWithoutSize.TryPush(node2);
|
||||
poolWithoutSize.TryPop(out _);
|
||||
poolWithoutSize.TryPop(out _);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void TaskPoolWithoutLock()
|
||||
{
|
||||
poolWithoutLock.TryPush(node1);
|
||||
poolWithoutLock.TryPush(node2);
|
||||
poolWithoutLock.TryPop(out _);
|
||||
poolWithoutLock.TryPop(out _);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Node : ITaskPoolNode<Node>
|
||||
{
|
||||
public Node NextNode { get; set; }
|
||||
}
|
||||
|
||||
public interface ITaskPoolNode<T>
|
||||
{
|
||||
T NextNode { get; set; }
|
||||
}
|
||||
|
||||
public sealed class RefNode :ITaskPoolRefNode<RefNode>
|
||||
{
|
||||
RefNode nextNode;
|
||||
public ref RefNode NextNode => ref nextNode;
|
||||
}
|
||||
|
||||
public interface ITaskPoolRefNode<T>
|
||||
{
|
||||
ref T NextNode { get; }
|
||||
}
|
||||
|
||||
|
||||
// mutable struct, don't mark readonly.
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct TaskPoolWithoutLock<T>
|
||||
where T : class, ITaskPoolNode<T>
|
||||
{
|
||||
int size;
|
||||
T root;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
//if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (!(v is null))
|
||||
{
|
||||
root = v.NextNode;
|
||||
v.NextNode = null;
|
||||
size--;
|
||||
result = v;
|
||||
// Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
//Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
//if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
size++;
|
||||
// Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct TaskPool<T>
|
||||
where T : class, ITaskPoolNode<T>
|
||||
{
|
||||
int gate;
|
||||
int size;
|
||||
T root;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (!(v is null))
|
||||
{
|
||||
root = v.NextNode;
|
||||
v.NextNode = null;
|
||||
size--;
|
||||
result = v;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
size++;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct TaskPoolRefNode<T>
|
||||
where T : class, ITaskPoolRefNode<T>
|
||||
{
|
||||
int gate;
|
||||
int size;
|
||||
T root;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (!(v is null))
|
||||
{
|
||||
ref var nextNode = ref v.NextNode;
|
||||
root = nextNode;
|
||||
nextNode = null;
|
||||
size--;
|
||||
result = v;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
size++;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct TaskPoolEqualNull<T>
|
||||
where T : class, ITaskPoolNode<T>
|
||||
{
|
||||
int gate;
|
||||
int size;
|
||||
T root;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (v != null)
|
||||
{
|
||||
root = v.NextNode;
|
||||
v.NextNode = null;
|
||||
size--;
|
||||
result = v;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
size++;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskPoolClass<T>
|
||||
where T : class, ITaskPoolNode<T>
|
||||
{
|
||||
int gate;
|
||||
int size;
|
||||
T root;
|
||||
|
||||
public int Size => size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (!(v is null))
|
||||
{
|
||||
root = v.NextNode;
|
||||
v.NextNode = null;
|
||||
size--;
|
||||
result = v;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
size++;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct TaskPoolWithoutSize<T>
|
||||
where T : class, ITaskPoolNode<T>
|
||||
{
|
||||
int gate;
|
||||
T root;
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPop(out T result)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
var v = root;
|
||||
if (!(v is null))
|
||||
{
|
||||
root = v.NextNode;
|
||||
v.NextNode = null;
|
||||
result = v;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
Volatile.Write(ref gate, 0);
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryPush(T item)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref gate, 1, 0) == 0)
|
||||
{
|
||||
//if (size < TaskPool.MaxPoolSize)
|
||||
{
|
||||
item.NextNode = root;
|
||||
root = item;
|
||||
Volatile.Write(ref gate, 0);
|
||||
return true;
|
||||
}
|
||||
//else
|
||||
{
|
||||
// Volatile.Write(ref gate, 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
|
||||
<PackageReference Include="PooledAwait" Version="1.0.49" />
|
||||
<PackageReference Include="System.Interactive.Async" Version="4.1.1" />
|
||||
<PackageReference Include="System.Reactive" Version="4.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
167
src/UniTask.NetCoreTests/AsyncLazyTest.cs
Normal file
167
src/UniTask.NetCoreTests/AsyncLazyTest.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class AsyncLazyTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task LazyLazy()
|
||||
{
|
||||
{
|
||||
var l = UniTask.Lazy(() => After());
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await a;
|
||||
await b;
|
||||
await c;
|
||||
}
|
||||
{
|
||||
var l = UniTask.Lazy(() => AfterException());
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LazyImmediate()
|
||||
{
|
||||
{
|
||||
var l = UniTask.Lazy(() => UniTask.FromResult(1).AsUniTask());
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await a;
|
||||
await b;
|
||||
await c;
|
||||
}
|
||||
{
|
||||
var l = UniTask.Lazy(() => UniTask.FromException(new TaskTestException()));
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
|
||||
}
|
||||
}
|
||||
|
||||
static async UniTask AwaitAwait(UniTask t)
|
||||
{
|
||||
await t;
|
||||
}
|
||||
|
||||
|
||||
async UniTask After()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||
await UniTask.Yield();
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
async UniTask AfterException()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||
await UniTask.Yield();
|
||||
throw new TaskTestException();
|
||||
}
|
||||
}
|
||||
|
||||
public class AsyncLazyTest2
|
||||
{
|
||||
[Fact]
|
||||
public async Task LazyLazy()
|
||||
{
|
||||
{
|
||||
var l = UniTask.Lazy(() => After());
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
var a2 = await a;
|
||||
var b2 = await b;
|
||||
var c2 = await c;
|
||||
(a2, b2, c2).Should().Be((10, 10, 10));
|
||||
}
|
||||
{
|
||||
var l = UniTask.Lazy(() => AfterException());
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LazyImmediate()
|
||||
{
|
||||
{
|
||||
var l = UniTask.Lazy(() => UniTask.FromResult(1));
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
var a2 = await a;
|
||||
var b2 = await b;
|
||||
var c2 = await c;
|
||||
(a2, b2, c2).Should().Be((1, 1, 1));
|
||||
}
|
||||
{
|
||||
var l = UniTask.Lazy(() => UniTask.FromException<int>(new TaskTestException()));
|
||||
var a = AwaitAwait(l.Task);
|
||||
var b = AwaitAwait(l.Task);
|
||||
var c = AwaitAwait(l.Task);
|
||||
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
|
||||
}
|
||||
}
|
||||
|
||||
static async UniTask<int> AwaitAwait(UniTask<int> t)
|
||||
{
|
||||
return await t;
|
||||
}
|
||||
|
||||
|
||||
async UniTask<int> After()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||
await UniTask.Yield();
|
||||
await UniTask.Yield();
|
||||
return 10;
|
||||
}
|
||||
|
||||
async UniTask<int> AfterException()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
Thread.Sleep(TimeSpan.FromSeconds(1));
|
||||
await UniTask.Yield();
|
||||
throw new TaskTestException();
|
||||
}
|
||||
}
|
||||
}
|
||||
197
src/UniTask.NetCoreTests/AsyncReactivePropertyTest.cs
Normal file
197
src/UniTask.NetCoreTests/AsyncReactivePropertyTest.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class AsyncReactivePropertyTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Iteration()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(99);
|
||||
|
||||
var f = await rp.FirstAsync();
|
||||
f.Should().Be(99);
|
||||
|
||||
var array = rp.Take(5).ToArrayAsync();
|
||||
|
||||
rp.Value = 100;
|
||||
rp.Value = 100;
|
||||
rp.Value = 100;
|
||||
rp.Value = 131;
|
||||
|
||||
var ar = await array;
|
||||
|
||||
ar.Should().BeEquivalentTo(new[] { 99, 100, 100, 100, 131 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithoutCurrent()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(99);
|
||||
|
||||
var array = rp.WithoutCurrent().Take(5).ToArrayAsync();
|
||||
|
||||
rp.Value = 100;
|
||||
rp.Value = 100;
|
||||
rp.Value = 100;
|
||||
rp.Value = 131;
|
||||
rp.Value = 191;
|
||||
|
||||
var ar = await array;
|
||||
|
||||
ar.Should().BeEquivalentTo(new[] { 100, 100, 100, 131, 191 });
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task StateIteration()
|
||||
//{
|
||||
// var rp = new ReadOnlyAsyncReactiveProperty<int>(99);
|
||||
// var setter = rp.GetSetter();
|
||||
|
||||
// var f = await rp.FirstAsync();
|
||||
// f.Should().Be(99);
|
||||
|
||||
// var array = rp.Take(5).ToArrayAsync();
|
||||
|
||||
// setter(100);
|
||||
// setter(100);
|
||||
// setter(100);
|
||||
// setter(131);
|
||||
|
||||
// var ar = await array;
|
||||
|
||||
// ar.Should().BeEquivalentTo(new[] { 99, 100, 100, 100, 131 });
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public async Task StateWithoutCurrent()
|
||||
//{
|
||||
// var rp = new ReadOnlyAsyncReactiveProperty<int>(99);
|
||||
// var setter = rp.GetSetter();
|
||||
|
||||
// var array = rp.WithoutCurrent().Take(5).ToArrayAsync();
|
||||
// setter(100);
|
||||
// setter(100);
|
||||
// setter(100);
|
||||
// setter(131);
|
||||
// setter(191);
|
||||
|
||||
// var ar = await array;
|
||||
|
||||
// ar.Should().BeEquivalentTo(new[] { 100, 100, 100, 131, 191 });
|
||||
//}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public void StateFromEnumeration()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(10);
|
||||
|
||||
var state = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
|
||||
|
||||
rp.Value = 10;
|
||||
state.Value.Should().Be(10);
|
||||
|
||||
rp.Value = 20;
|
||||
state.Value.Should().Be(20);
|
||||
|
||||
state.Dispose();
|
||||
|
||||
rp.Value = 30;
|
||||
state.Value.Should().Be(20);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WaitAsyncTest()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(128);
|
||||
|
||||
var f = await rp.FirstAsync();
|
||||
f.Should().Be(128);
|
||||
|
||||
{
|
||||
var t = rp.WaitAsync();
|
||||
rp.Value = 99;
|
||||
rp.Value = 100;
|
||||
var v = await t;
|
||||
|
||||
v.Should().Be(99);
|
||||
}
|
||||
|
||||
{
|
||||
var t = rp.WaitAsync();
|
||||
rp.Value = 99;
|
||||
rp.Value = 100;
|
||||
var v = await t;
|
||||
|
||||
v.Should().Be(99);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task WaitAsyncCancellationTest()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(128);
|
||||
|
||||
var t = rp.WaitAsync(cts.Token);
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
rp.Value = 99;
|
||||
rp.Value = 100;
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => { await t; });
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ReadOnlyWaitAsyncTest()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(128);
|
||||
var rrp = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
|
||||
|
||||
var t = rrp.WaitAsync();
|
||||
rp.Value = 99;
|
||||
rp.Value = 100;
|
||||
var v = await t;
|
||||
|
||||
v.Should().Be(99);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ReadOnlyWaitAsyncCancellationTest()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(128);
|
||||
var rrp = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
|
||||
|
||||
var t = rrp.WaitAsync(cts.Token);
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
rp.Value = 99;
|
||||
rp.Value = 100;
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => { await t; });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
51
src/UniTask.NetCoreTests/CancellationTokenTest.cs
Normal file
51
src/UniTask.NetCoreTests/CancellationTokenTest.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class CancellationTokenTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task WaitUntilCanceled()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
cts.CancelAfter(TimeSpan.FromSeconds(1.5));
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
await cts.Token.WaitUntilCanceled();
|
||||
|
||||
var elapsed = DateTime.UtcNow - now;
|
||||
|
||||
elapsed.Should().BeGreaterThan(TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AlreadyCanceled()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
cts.Token.WaitUntilCanceled().GetAwaiter().IsCompleted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void None()
|
||||
{
|
||||
CancellationToken.None.WaitUntilCanceled().GetAwaiter().IsCompleted.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
370
src/UniTask.NetCoreTests/ChannelTest.cs
Normal file
370
src/UniTask.NetCoreTests/ChannelTest.cs
Normal file
@@ -0,0 +1,370 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class ChannelTest
|
||||
{
|
||||
(System.Threading.Channels.Channel<int>, Cysharp.Threading.Tasks.Channel<int>) CreateChannel()
|
||||
{
|
||||
var reference = System.Threading.Channels.Channel.CreateUnbounded<int>(new UnboundedChannelOptions
|
||||
{
|
||||
AllowSynchronousContinuations = true,
|
||||
SingleReader = true,
|
||||
SingleWriter = false
|
||||
});
|
||||
|
||||
var channel = Cysharp.Threading.Tasks.Channel.CreateSingleConsumerUnbounded<int>();
|
||||
|
||||
return (reference, channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SingleWriteSingleRead()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
var t1 = reference.Reader.WaitToReadAsync();
|
||||
var t2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
t1.IsCompleted.Should().BeFalse();
|
||||
t2.Status.IsCompleted().Should().BeFalse();
|
||||
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
|
||||
(await t1).Should().BeTrue();
|
||||
(await t2).Should().BeTrue();
|
||||
|
||||
reference.Reader.TryRead(out var refitem).Should().BeTrue();
|
||||
channel.Reader.TryRead(out var chanitem).Should().BeTrue();
|
||||
refitem.Should().Be(item);
|
||||
chanitem.Should().Be(item);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultiWrite()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
var t1 = reference.Reader.WaitToReadAsync();
|
||||
var t2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
t1.IsCompleted.Should().BeFalse();
|
||||
t2.Status.IsCompleted().Should().BeFalse();
|
||||
|
||||
foreach (var i in Enumerable.Range(1, 3))
|
||||
{
|
||||
reference.Writer.TryWrite(item * i);
|
||||
channel.Writer.TryWrite(item * i);
|
||||
}
|
||||
|
||||
(await t1).Should().BeTrue();
|
||||
(await t2).Should().BeTrue();
|
||||
|
||||
foreach (var i in Enumerable.Range(1, 3))
|
||||
{
|
||||
(await reference.Reader.WaitToReadAsync()).Should().BeTrue();
|
||||
(await channel.Reader.WaitToReadAsync()).Should().BeTrue();
|
||||
|
||||
reference.Reader.TryRead(out var refitem).Should().BeTrue();
|
||||
channel.Reader.TryRead(out var chanitem).Should().BeTrue();
|
||||
refitem.Should().Be(item * i);
|
||||
chanitem.Should().Be(item * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CompleteOnEmpty()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
reference.Reader.TryRead(out var refitem);
|
||||
channel.Reader.TryRead(out var chanitem);
|
||||
}
|
||||
|
||||
// Empty.
|
||||
|
||||
var completion1 = reference.Reader.Completion;
|
||||
var wait1 = reference.Reader.WaitToReadAsync();
|
||||
|
||||
var completion2 = channel.Reader.Completion;
|
||||
var wait2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
reference.Writer.TryComplete();
|
||||
channel.Writer.TryComplete();
|
||||
|
||||
completion1.Status.Should().Be(TaskStatus.RanToCompletion);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
|
||||
(await wait1).Should().BeFalse();
|
||||
(await wait2).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CompleteErrorOnEmpty()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
reference.Reader.TryRead(out var refitem);
|
||||
channel.Reader.TryRead(out var chanitem);
|
||||
}
|
||||
|
||||
// Empty.
|
||||
|
||||
var completion1 = reference.Reader.Completion;
|
||||
var wait1 = reference.Reader.WaitToReadAsync();
|
||||
|
||||
var completion2 = channel.Reader.Completion;
|
||||
var wait2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
var ex = new Exception();
|
||||
reference.Writer.TryComplete(ex);
|
||||
channel.Writer.TryComplete(ex);
|
||||
|
||||
completion1.Status.Should().Be(TaskStatus.Faulted);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
|
||||
(await Assert.ThrowsAsync<Exception>(async () => await wait1)).Should().Be(ex);
|
||||
(await Assert.ThrowsAsync<Exception>(async () => await wait2)).Should().Be(ex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CompleteWithRest()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
// Three Item2.
|
||||
|
||||
var completion1 = reference.Reader.Completion;
|
||||
var wait1 = reference.Reader.WaitToReadAsync();
|
||||
|
||||
var completion2 = channel.Reader.Completion;
|
||||
var wait2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
reference.Writer.TryComplete();
|
||||
channel.Writer.TryComplete();
|
||||
|
||||
// completion1.Status.Should().Be(TaskStatus.WaitingForActivation);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Pending);
|
||||
|
||||
(await wait1).Should().BeTrue();
|
||||
(await wait2).Should().BeTrue();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Reader.TryRead(out var i1).Should().BeTrue();
|
||||
channel.Reader.TryRead(out var i2).Should().BeTrue();
|
||||
i1.Should().Be(item);
|
||||
i2.Should().Be(item);
|
||||
}
|
||||
|
||||
(await reference.Reader.WaitToReadAsync()).Should().BeFalse();
|
||||
(await channel.Reader.WaitToReadAsync()).Should().BeFalse();
|
||||
|
||||
completion1.Status.Should().Be(TaskStatus.RanToCompletion);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task CompleteErrorWithRest()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
// Three Item2.
|
||||
|
||||
var completion1 = reference.Reader.Completion;
|
||||
var wait1 = reference.Reader.WaitToReadAsync();
|
||||
|
||||
var completion2 = channel.Reader.Completion;
|
||||
var wait2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
var ex = new Exception();
|
||||
reference.Writer.TryComplete(ex);
|
||||
channel.Writer.TryComplete(ex);
|
||||
|
||||
// completion1.Status.Should().Be(TaskStatus.WaitingForActivation);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Pending);
|
||||
|
||||
(await wait1).Should().BeTrue();
|
||||
(await wait2).Should().BeTrue();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Reader.TryRead(out var i1).Should().BeTrue();
|
||||
channel.Reader.TryRead(out var i2).Should().BeTrue();
|
||||
i1.Should().Be(item);
|
||||
i2.Should().Be(item);
|
||||
}
|
||||
|
||||
wait1 = reference.Reader.WaitToReadAsync();
|
||||
wait2 = channel.Reader.WaitToReadAsync();
|
||||
|
||||
(await Assert.ThrowsAsync<Exception>(async () => await wait1)).Should().Be(ex);
|
||||
(await Assert.ThrowsAsync<Exception>(async () => await wait2)).Should().Be(ex);
|
||||
|
||||
completion1.Status.Should().Be(TaskStatus.Faulted);
|
||||
completion2.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Cancellation()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
var wait1 = reference.Reader.WaitToReadAsync(cts.Token);
|
||||
var wait2 = channel.Reader.WaitToReadAsync(cts.Token);
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await wait1)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await wait2)).CancellationToken.Should().Be(cts.Token);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AsyncEnumerator()
|
||||
{
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var ta1 = reference.Reader.ReadAllAsync().ToArrayAsync();
|
||||
var ta2 = channel.Reader.ReadAllAsync().ToArrayAsync();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
reference.Writer.TryComplete();
|
||||
channel.Writer.TryComplete();
|
||||
|
||||
(await ta1).Should().BeEquivalentTo(new[] { 10, 20, 30 });
|
||||
(await ta2).Should().BeEquivalentTo(new[] { 10, 20, 30 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AsyncEnumeratorCancellation()
|
||||
{
|
||||
// Token1, Token2 and Cancel1
|
||||
{
|
||||
var cts1 = new CancellationTokenSource();
|
||||
var cts2 = new CancellationTokenSource();
|
||||
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
|
||||
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
cts1.Cancel();
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts1.Token);
|
||||
}
|
||||
// Token1, Token2 and Cancel2
|
||||
{
|
||||
var cts1 = new CancellationTokenSource();
|
||||
var cts2 = new CancellationTokenSource();
|
||||
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
|
||||
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
cts2.Cancel();
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts2.Token);
|
||||
}
|
||||
// Token1 and Cancel1
|
||||
{
|
||||
var cts1 = new CancellationTokenSource();
|
||||
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync();
|
||||
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync();
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
cts1.Cancel();
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts1.Token);
|
||||
}
|
||||
// Token2 and Cancel2
|
||||
{
|
||||
var cts2 = new CancellationTokenSource();
|
||||
|
||||
var (reference, channel) = CreateChannel();
|
||||
|
||||
var ta1 = reference.Reader.ReadAllAsync().ToArrayAsync(cts2.Token);
|
||||
var ta2 = channel.Reader.ReadAllAsync().ToArrayAsync(cts2.Token);
|
||||
|
||||
foreach (var item in new[] { 10, 20, 30 })
|
||||
{
|
||||
reference.Writer.TryWrite(item);
|
||||
channel.Writer.TryWrite(item);
|
||||
}
|
||||
|
||||
cts2.Cancel();
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts2.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
590
src/UniTask.NetCoreTests/CompletionSourceTest.cs
Normal file
590
src/UniTask.NetCoreTests/CompletionSourceTest.cs
Normal file
@@ -0,0 +1,590 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class CompletionSourceTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task SetFirst()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
tcs.TrySetResult();
|
||||
await tcs.Task; // ok.
|
||||
await tcs.Task; // ok.
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SingleOnFirst()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetResult();
|
||||
await a;
|
||||
await tcs.Task; // ok.
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultiOne()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
tcs.TrySetResult();
|
||||
await a;
|
||||
await b;
|
||||
await tcs.Task; // ok.
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultiTwo()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
tcs.TrySetResult();
|
||||
await a;
|
||||
await b;
|
||||
await c;
|
||||
await tcs.Task; // ok.
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await c);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
|
||||
async UniTask Await()
|
||||
{
|
||||
await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
class TestException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class CompletionSourceTest2
|
||||
{
|
||||
[Fact]
|
||||
public async Task SetFirst()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
tcs.TrySetResult(10);
|
||||
var a = await tcs.Task; // ok.
|
||||
var b = await tcs.Task; // ok.
|
||||
a.Should().Be(10);
|
||||
b.Should().Be(10);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SingleOnFirst()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetResult(10);
|
||||
var r1 = await a;
|
||||
var r2 = await tcs.Task; // ok.
|
||||
r1.Should().Be(10);
|
||||
r2.Should().Be(10);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultiOne()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
tcs.TrySetResult(10);
|
||||
var r1 = await a;
|
||||
var r2 = await b;
|
||||
var r3 = await tcs.Task; // ok.
|
||||
(r1, r2, r3).Should().Be((10, 10, 10));
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultiTwo()
|
||||
{
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
tcs.TrySetResult(10);
|
||||
var r1 = await a;
|
||||
var r2 = await b;
|
||||
var r3 = await c;
|
||||
var r4 = await tcs.Task; // ok.
|
||||
(r1, r2, r3, r4).Should().Be((10, 10, 10, 10));
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
|
||||
}
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetException(new TestException());
|
||||
await Assert.ThrowsAsync<TestException>(async () => await a);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await b);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await c);
|
||||
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetException(new OperationCanceledException(cts.Token));
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource<int>();
|
||||
|
||||
async UniTask<int> Await()
|
||||
{
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
var a = Await();
|
||||
var b = Await();
|
||||
var c = Await();
|
||||
|
||||
tcs.TrySetCanceled(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
|
||||
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
class TestException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/UniTask.NetCoreTests/DeferTest.cs
Normal file
47
src/UniTask.NetCoreTests/DeferTest.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class DeferTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task D()
|
||||
{
|
||||
var created = false;
|
||||
var v = UniTask.Defer(() => { created = true; return UniTask.Run(() => 10); });
|
||||
|
||||
created.Should().BeFalse();
|
||||
|
||||
var t = await v;
|
||||
|
||||
created.Should().BeTrue();
|
||||
|
||||
t.Should().Be(10);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task D2()
|
||||
{
|
||||
var created = false;
|
||||
var v = UniTask.Defer(() => { created = true; return UniTask.Run(() => 10).AsUniTask(); });
|
||||
|
||||
created.Should().BeFalse();
|
||||
|
||||
await v;
|
||||
|
||||
created.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ namespace NetCoreTests.Linq
|
||||
xs.Should().Be(ys);
|
||||
}
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAwaitCancellationAsync((x, _) => UniTask.Run(() => x));
|
||||
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAwaitWithCancellationAsync((x, _) => UniTask.Run(() => x));
|
||||
var ys = Enumerable.Range(start, count).Sum(x => x);
|
||||
xs.Should().Be(ys);
|
||||
}
|
||||
|
||||
170
src/UniTask.NetCoreTests/Linq/CreateTest.cs
Normal file
170
src/UniTask.NetCoreTests/Linq/CreateTest.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
#pragma warning disable CS1998
|
||||
#pragma warning disable CS0162
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests.Linq
|
||||
{
|
||||
public class CreateTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task SyncCreation()
|
||||
{
|
||||
var from = 10;
|
||||
var count = 100;
|
||||
|
||||
var xs = await UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
await writer.YieldAsync(from + i);
|
||||
}
|
||||
}).ToArrayAsync();
|
||||
|
||||
var ys = await Range(from, count).AsUniTaskAsyncEnumerable().ToArrayAsync();
|
||||
|
||||
xs.Should().BeEquivalentTo(ys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SyncManually()
|
||||
{
|
||||
var list = new List<int>();
|
||||
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
list.Add(100);
|
||||
await writer.YieldAsync(10);
|
||||
|
||||
list.Add(200);
|
||||
await writer.YieldAsync(20);
|
||||
|
||||
list.Add(300);
|
||||
await writer.YieldAsync(30);
|
||||
|
||||
list.Add(400);
|
||||
});
|
||||
|
||||
list.Should().BeEmpty();
|
||||
var e = xs.GetAsyncEnumerator();
|
||||
|
||||
list.Should().BeEmpty();
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100);
|
||||
e.Current.Should().Be(10);
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100, 200);
|
||||
e.Current.Should().Be(20);
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100, 200, 300);
|
||||
e.Current.Should().Be(30);
|
||||
|
||||
(await e.MoveNextAsync()).Should().BeFalse();
|
||||
list.Should().BeEquivalentTo(100, 200, 300, 400);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SyncExceptionFirst()
|
||||
{
|
||||
var from = 10;
|
||||
var count = 100;
|
||||
|
||||
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
throw new UniTaskTestException();
|
||||
await writer.YieldAsync(from + i);
|
||||
}
|
||||
});
|
||||
|
||||
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SyncException()
|
||||
{
|
||||
var from = 10;
|
||||
var count = 100;
|
||||
|
||||
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
await writer.YieldAsync(from + i);
|
||||
|
||||
if (i == 15)
|
||||
{
|
||||
throw new UniTaskTestException();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ASyncManually()
|
||||
{
|
||||
var list = new List<int>();
|
||||
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||
{
|
||||
await UniTask.Yield();
|
||||
|
||||
list.Add(100);
|
||||
await writer.YieldAsync(10);
|
||||
|
||||
await UniTask.Yield();
|
||||
|
||||
list.Add(200);
|
||||
await writer.YieldAsync(20);
|
||||
|
||||
await UniTask.Yield();
|
||||
list.Add(300);
|
||||
await UniTask.Yield();
|
||||
await writer.YieldAsync(30);
|
||||
|
||||
await UniTask.Yield();
|
||||
|
||||
list.Add(400);
|
||||
});
|
||||
|
||||
list.Should().BeEmpty();
|
||||
var e = xs.GetAsyncEnumerator();
|
||||
|
||||
list.Should().BeEmpty();
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100);
|
||||
e.Current.Should().Be(10);
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100, 200);
|
||||
e.Current.Should().Be(20);
|
||||
|
||||
await e.MoveNextAsync();
|
||||
list.Should().BeEquivalentTo(100, 200, 300);
|
||||
e.Current.Should().Be(30);
|
||||
|
||||
(await e.MoveNextAsync()).Should().BeFalse();
|
||||
list.Should().BeEquivalentTo(100, 200, 300, 400);
|
||||
}
|
||||
|
||||
async IAsyncEnumerable<int> Range(int from, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
yield return from + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,5 +319,119 @@ namespace NetCoreTests.Linq
|
||||
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CombineLatestOK()
|
||||
{
|
||||
var a = new AsyncReactiveProperty<int>(0);
|
||||
var b = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var list = new List<(int, int)>();
|
||||
var complete = a.WithoutCurrent().CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
|
||||
|
||||
list.Count.Should().Be(0);
|
||||
|
||||
a.Value = 10;
|
||||
list.Count.Should().Be(0);
|
||||
|
||||
a.Value = 20;
|
||||
list.Count.Should().Be(0);
|
||||
|
||||
b.Value = 1;
|
||||
list.Count.Should().Be(1);
|
||||
|
||||
list[0].Should().Be((20, 1));
|
||||
|
||||
a.Value = 30;
|
||||
list.Last().Should().Be((30, 1));
|
||||
|
||||
b.Value = 2;
|
||||
list.Last().Should().Be((30, 2));
|
||||
|
||||
a.Dispose();
|
||||
b.Value = 3;
|
||||
list.Last().Should().Be((30, 3));
|
||||
|
||||
b.Dispose();
|
||||
|
||||
await complete;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CombineLatestLong()
|
||||
{
|
||||
var a = UniTaskAsyncEnumerable.Range(1, 100000);
|
||||
var b = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var list = new List<(int, int)>();
|
||||
var complete = a.CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
|
||||
|
||||
b.Value = 1;
|
||||
|
||||
list[0].Should().Be((100000, 1));
|
||||
|
||||
b.Dispose();
|
||||
|
||||
await complete;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CombineLatestError()
|
||||
{
|
||||
var a = new AsyncReactiveProperty<int>(0);
|
||||
var b = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var list = new List<(int, int)>();
|
||||
var complete = a.WithoutCurrent()
|
||||
.Select(x => { if (x == 0) { throw new MyException(); } return x; })
|
||||
.CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
|
||||
|
||||
|
||||
a.Value = 10;
|
||||
b.Value = 1;
|
||||
list.Last().Should().Be((10, 1));
|
||||
|
||||
a.Value = 0;
|
||||
|
||||
await Assert.ThrowsAsync<MyException>(async () => await complete);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task PariwiseImmediate()
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.Range(1, 5).Pairwise().ToArrayAsync();
|
||||
xs.Should().BeEquivalentTo((1, 2), (2, 3), (3, 4), (4, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Pariwise()
|
||||
{
|
||||
var a = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var list = new List<(int, int)>();
|
||||
var complete = a.WithoutCurrent().Pairwise().ForEachAsync(x => list.Add(x));
|
||||
|
||||
list.Count.Should().Be(0);
|
||||
a.Value = 10;
|
||||
list.Count.Should().Be(0);
|
||||
a.Value = 20;
|
||||
list.Count.Should().Be(1);
|
||||
a.Value = 30;
|
||||
a.Value = 40;
|
||||
a.Value = 50;
|
||||
|
||||
a.Dispose();
|
||||
|
||||
await complete;
|
||||
|
||||
list.Should().BeEquivalentTo((10, 20), (20, 30), (30, 40), (40, 50));
|
||||
}
|
||||
|
||||
class MyException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
src/UniTask.NetCoreTests/Linq/PulbishTest.cs
Normal file
78
src/UniTask.NetCoreTests/Linq/PulbishTest.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests.Linq
|
||||
{
|
||||
public class PublishTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Normal()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var multicast = rp.Publish();
|
||||
|
||||
var a = multicast.ToArrayAsync();
|
||||
var b = multicast.Take(2).ToArrayAsync();
|
||||
|
||||
var disp = multicast.Connect();
|
||||
|
||||
rp.Value = 2;
|
||||
|
||||
(await b).Should().BeEquivalentTo(1, 2);
|
||||
|
||||
var c = multicast.ToArrayAsync();
|
||||
|
||||
rp.Value = 3;
|
||||
rp.Value = 4;
|
||||
rp.Value = 5;
|
||||
|
||||
rp.Dispose();
|
||||
|
||||
(await a).Should().BeEquivalentTo(1, 2, 3, 4, 5);
|
||||
(await c).Should().BeEquivalentTo(3, 4, 5);
|
||||
|
||||
disp.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Cancel()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var multicast = rp.Publish();
|
||||
|
||||
var a = multicast.ToArrayAsync();
|
||||
var b = multicast.Take(2).ToArrayAsync();
|
||||
|
||||
var disp = multicast.Connect();
|
||||
|
||||
rp.Value = 2;
|
||||
|
||||
(await b).Should().BeEquivalentTo(1, 2);
|
||||
|
||||
var c = multicast.ToArrayAsync();
|
||||
|
||||
rp.Value = 3;
|
||||
|
||||
disp.Dispose();
|
||||
|
||||
rp.Value = 4;
|
||||
rp.Value = 5;
|
||||
|
||||
rp.Dispose();
|
||||
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await a);
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await c);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
29
src/UniTask.NetCoreTests/Linq/QueueTest.cs
Normal file
29
src/UniTask.NetCoreTests/Linq/QueueTest.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests.Linq
|
||||
{
|
||||
public class QueueTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Q()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(100);
|
||||
|
||||
var l = new List<int>();
|
||||
await rp.Take(10).Queue().ForEachAsync(x =>
|
||||
{
|
||||
rp.Value += 10;
|
||||
l.Add(x);
|
||||
});
|
||||
|
||||
l.Should().BeEquivalentTo(100, 110, 120, 130, 140, 150, 160, 170, 180, 190);
|
||||
}
|
||||
}
|
||||
}
|
||||
165
src/UniTask.NetCoreTests/Linq/TakeInfinityTest.cs
Normal file
165
src/UniTask.NetCoreTests/Linq/TakeInfinityTest.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests.Linq
|
||||
{
|
||||
public class TakeInfinityTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Take()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.Take(5).ToArrayAsync();
|
||||
|
||||
rp.Value = 2;
|
||||
rp.Value = 3;
|
||||
rp.Value = 4;
|
||||
rp.Value = 5;
|
||||
|
||||
(await xs).Should().BeEquivalentTo(1, 2, 3, 4, 5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TakeWhile()
|
||||
{
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.TakeWhile(x => x != 5).ToArrayAsync();
|
||||
|
||||
rp.Value = 2;
|
||||
rp.Value = 3;
|
||||
rp.Value = 4;
|
||||
rp.Value = 5;
|
||||
|
||||
(await xs).Should().BeEquivalentTo(1, 2, 3, 4);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TakeUntilCanceled()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.TakeUntilCanceled(cts.Token).ToArrayAsync();
|
||||
|
||||
var c = CancelAsync();
|
||||
|
||||
await c;
|
||||
var foo = await xs;
|
||||
|
||||
foo.Should().BeEquivalentTo(new[] { 1, 10, 20 });
|
||||
|
||||
async Task CancelAsync()
|
||||
{
|
||||
rp.Value = 10;
|
||||
await Task.Yield();
|
||||
rp.Value = 20;
|
||||
await Task.Yield();
|
||||
cts.Cancel();
|
||||
rp.Value = 30;
|
||||
await Task.Yield();
|
||||
rp.Value = 40;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SkipUntilCanceled()
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.SkipUntilCanceled(cts.Token).ToArrayAsync();
|
||||
|
||||
var c = CancelAsync();
|
||||
|
||||
await c;
|
||||
var foo = await xs;
|
||||
|
||||
foo.Should().BeEquivalentTo(new[] { 20, 30, 40 });
|
||||
|
||||
async Task CancelAsync()
|
||||
{
|
||||
rp.Value = 10;
|
||||
await Task.Yield();
|
||||
rp.Value = 20;
|
||||
await Task.Yield();
|
||||
cts.Cancel();
|
||||
rp.Value = 30;
|
||||
await Task.Yield();
|
||||
rp.Value = 40;
|
||||
|
||||
rp.Dispose(); // complete.
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TakeUntil()
|
||||
{
|
||||
var cts = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.TakeUntil(cts.WaitAsync()).ToArrayAsync();
|
||||
|
||||
var c = CancelAsync();
|
||||
|
||||
await c;
|
||||
var foo = await xs;
|
||||
|
||||
foo.Should().BeEquivalentTo(new[] { 1, 10, 20 });
|
||||
|
||||
async Task CancelAsync()
|
||||
{
|
||||
rp.Value = 10;
|
||||
await Task.Yield();
|
||||
rp.Value = 20;
|
||||
await Task.Yield();
|
||||
cts.Value = 9999;
|
||||
rp.Value = 30;
|
||||
await Task.Yield();
|
||||
rp.Value = 40;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SkipUntil()
|
||||
{
|
||||
var cts = new AsyncReactiveProperty<int>(0);
|
||||
|
||||
var rp = new AsyncReactiveProperty<int>(1);
|
||||
|
||||
var xs = rp.SkipUntil(cts.WaitAsync()).ToArrayAsync();
|
||||
|
||||
var c = CancelAsync();
|
||||
|
||||
await c;
|
||||
var foo = await xs;
|
||||
|
||||
foo.Should().BeEquivalentTo(new[] { 20, 30, 40 });
|
||||
|
||||
async Task CancelAsync()
|
||||
{
|
||||
rp.Value = 10;
|
||||
await Task.Yield();
|
||||
rp.Value = 20;
|
||||
await Task.Yield();
|
||||
cts.Value = 9999;
|
||||
rp.Value = 30;
|
||||
await Task.Yield();
|
||||
rp.Value = 40;
|
||||
|
||||
rp.Dispose(); // complete.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
301
src/UniTask.NetCoreTests/TaskBuilderCases.cs
Normal file
301
src/UniTask.NetCoreTests/TaskBuilderCases.cs
Normal file
@@ -0,0 +1,301 @@
|
||||
#pragma warning disable CS1998
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class UniTaskBuilderTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Empty()
|
||||
{
|
||||
await Core();
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EmptyThrow()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
throw new TaskTestException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Done()
|
||||
{
|
||||
await Core();
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(true, UniTaskStatus.Succeeded);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Fail()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(true, UniTaskStatus.Faulted);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Cancel()
|
||||
{
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(true, UniTaskStatus.Canceled);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetResult()
|
||||
{
|
||||
await Core();
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetException()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Faulted);
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetCancelException()
|
||||
{
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
|
||||
|
||||
static async UniTask Core()
|
||||
{
|
||||
await new TestAwaiter(false, UniTaskStatus.Succeeded);
|
||||
await new TestAwaiter(false, UniTaskStatus.Canceled);
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UniTask_T_BuilderTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Empty()
|
||||
{
|
||||
(await Core()).Should().Be(10);
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EmptyThrow()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
throw new TaskTestException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Done()
|
||||
{
|
||||
(await Core()).Should().Be(10);
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
return await new TestAwaiter<int>(true, UniTaskStatus.Succeeded, 10);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Fail()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
return await new TestAwaiter<int>(true, UniTaskStatus.Faulted, 10);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Task_Cancel()
|
||||
{
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
return await new TestAwaiter<int>(true, UniTaskStatus.Canceled, 10);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetResult()
|
||||
{
|
||||
(await Core()).Should().Be(6);
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
var sum = 0;
|
||||
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 1);
|
||||
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 2);
|
||||
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 3);
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetException()
|
||||
{
|
||||
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
|
||||
await new TestAwaiter<int>(false, UniTaskStatus.Faulted, 10);
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AwaitUnsafeOnCompletedCall_Task_SetCancelException()
|
||||
{
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
|
||||
|
||||
static async UniTask<int> Core()
|
||||
{
|
||||
await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
|
||||
await new TestAwaiter<int>(false, UniTaskStatus.Canceled, 10);
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskTestException : Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public struct TestAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public TestAwaiter GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
}
|
||||
|
||||
public struct TestAwaiter<T> : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly UniTaskStatus status;
|
||||
readonly bool isCompleted;
|
||||
readonly T value;
|
||||
|
||||
public TestAwaiter(bool isCompleted, UniTaskStatus status, T value)
|
||||
{
|
||||
this.isCompleted = isCompleted;
|
||||
this.status = status;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TestAwaiter<T> GetAwaiter() => this;
|
||||
|
||||
public bool IsCompleted => isCompleted;
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case UniTaskStatus.Faulted:
|
||||
throw new TaskTestException();
|
||||
case UniTaskStatus.Canceled:
|
||||
throw new OperationCanceledException();
|
||||
case UniTaskStatus.Pending:
|
||||
case UniTaskStatus.Succeeded:
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
637
src/UniTask.NetCoreTests/TriggerEventTest.cs
Normal file
637
src/UniTask.NetCoreTests/TriggerEventTest.cs
Normal file
@@ -0,0 +1,637 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class TriggerEventTest
|
||||
{
|
||||
[Fact]
|
||||
public void SimpleAdd()
|
||||
{
|
||||
var ev = new TriggerEvent<int>();
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
|
||||
ev.Add(one);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.SetCompleted();
|
||||
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
}
|
||||
// after removed, onemore
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
|
||||
ev.Add(one);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.SetCompleted();
|
||||
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddFour()
|
||||
{
|
||||
var ev = new TriggerEvent<int>();
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
var four = new TestEvent(4);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(four);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
four.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.SetCompleted();
|
||||
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
two.CompletedCalled.Count.Should().Be(1);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
}
|
||||
|
||||
// after removed, onemore.
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
var four = new TestEvent(4);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(four);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
ev.Add(four);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
four.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.SetCompleted();
|
||||
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
two.CompletedCalled.Count.Should().Be(1);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
|
||||
|
||||
// do nothing
|
||||
ev.SetResult(0);
|
||||
ev.SetError(null);
|
||||
ev.SetCompleted();
|
||||
ev.SetCanceled(default);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
one.CompletedCalled.Count.Should().Be(1);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.CompletedCalled.Count.Should().Be(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void OneRemove()
|
||||
{
|
||||
var ev = new TriggerEvent<int>();
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.Remove(one);
|
||||
|
||||
ev.SetResult(40);
|
||||
ev.SetResult(50);
|
||||
ev.SetResult(60);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public void TwoRemove()
|
||||
{
|
||||
var ev = new TriggerEvent<int>();
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.Remove(two);
|
||||
|
||||
ev.SetResult(40);
|
||||
ev.SetResult(50);
|
||||
ev.SetResult(60);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public void ThreeRemove()
|
||||
{
|
||||
var ev = new TriggerEvent<int>();
|
||||
{
|
||||
var one = new TestEvent(1);
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
|
||||
ev.Remove(three);
|
||||
|
||||
ev.SetResult(40);
|
||||
ev.SetResult(50);
|
||||
ev.SetResult(60);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40, 50, 60);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveSelf()
|
||||
{
|
||||
new RemoveMe().Run1();
|
||||
new RemoveMe().Run2();
|
||||
new RemoveMe().Run3();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveNextInIterating()
|
||||
{
|
||||
new RemoveNext().Run1();
|
||||
new RemoveNext().Run2();
|
||||
new RemoveNext().Run3();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveNextNextTest()
|
||||
{
|
||||
new RemoveNextNext().Run1();
|
||||
new RemoveNextNext().Run2();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void AddTest()
|
||||
{
|
||||
new AddMe().Run1();
|
||||
new AddMe().Run2();
|
||||
}
|
||||
|
||||
public class RemoveMe
|
||||
{
|
||||
TriggerEvent<int> ev;
|
||||
|
||||
public void Run1()
|
||||
{
|
||||
TestEvent one = default;
|
||||
one = new TestEvent(1, () => ev.Remove(one));
|
||||
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
public void Run2()
|
||||
{
|
||||
TestEvent one = default;
|
||||
one = new TestEvent(1, () => ev.Remove(one));
|
||||
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(two);
|
||||
ev.Add(one); // add second.
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
public void Run3()
|
||||
{
|
||||
TestEvent one = default;
|
||||
one = new TestEvent(1, () => ev.Remove(one));
|
||||
|
||||
var two = new TestEvent(2);
|
||||
var three = new TestEvent(3);
|
||||
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(one); // add thired.
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10);
|
||||
two.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
}
|
||||
|
||||
public class RemoveNext
|
||||
{
|
||||
TriggerEvent<int> ev;
|
||||
|
||||
public void Run1()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
one = new TestEvent(1, () => ev.Remove(two));
|
||||
two = new TestEvent(2);
|
||||
three = new TestEvent(3);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Count.Should().Be(0);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
public void Run2()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
one = new TestEvent(1, () => ev.Remove(two));
|
||||
two = new TestEvent(2);
|
||||
three = new TestEvent(3);
|
||||
|
||||
ev.Add(two);
|
||||
ev.Add(one); // add second
|
||||
ev.Add(three);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
public void Run3()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
one = new TestEvent(1, () => ev.Remove(two));
|
||||
two = new TestEvent(2);
|
||||
three = new TestEvent(3);
|
||||
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(one); // add thired.
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Should().BeEquivalentTo(10);
|
||||
three.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
}
|
||||
|
||||
public class RemoveNextNext
|
||||
{
|
||||
TriggerEvent<int> ev;
|
||||
|
||||
public void Run1()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
TestEvent four = default;
|
||||
one = new TestEvent(1, () => { ev.Remove(two); ev.Remove(three); });
|
||||
two = new TestEvent(2);
|
||||
three = new TestEvent(3);
|
||||
four = new TestEvent(4);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(four);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
two.NextCalled.Count.Should().Be(0);
|
||||
three.NextCalled.Count.Should().Be(0);
|
||||
four.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
public void Run2()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
TestEvent four = default;
|
||||
one = new TestEvent(1, () => { ev.Remove(one); ev.Remove(two); ev.Remove(three); });
|
||||
two = new TestEvent(2);
|
||||
three = new TestEvent(3);
|
||||
four = new TestEvent(4);
|
||||
|
||||
ev.Add(one);
|
||||
ev.Add(two);
|
||||
ev.Add(three);
|
||||
ev.Add(four);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10);
|
||||
two.NextCalled.Count.Should().Be(0);
|
||||
three.NextCalled.Count.Should().Be(0);
|
||||
four.NextCalled.Should().BeEquivalentTo(10, 20, 30);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AddMe
|
||||
{
|
||||
TriggerEvent<int> ev;
|
||||
|
||||
public void Run1()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
TestEvent four = default;
|
||||
|
||||
one = new TestEvent(1, () =>
|
||||
{
|
||||
if (two == null)
|
||||
{
|
||||
ev.Add(two = new TestEvent(2));
|
||||
}
|
||||
else if (three == null)
|
||||
{
|
||||
ev.Add(three = new TestEvent(3));
|
||||
}
|
||||
else if (four == null)
|
||||
{
|
||||
ev.Add(four = new TestEvent(4));
|
||||
}
|
||||
});
|
||||
|
||||
ev.Add(one);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
ev.SetResult(40);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40);
|
||||
two.NextCalled.Should().BeEquivalentTo(20, 30, 40);
|
||||
three.NextCalled.Should().BeEquivalentTo(30, 40);
|
||||
four.NextCalled.Should().BeEquivalentTo(40);
|
||||
}
|
||||
|
||||
public void Run2()
|
||||
{
|
||||
TestEvent one = default;
|
||||
TestEvent two = default;
|
||||
TestEvent three = default;
|
||||
TestEvent four = default;
|
||||
|
||||
one = new TestEvent(1, () =>
|
||||
{
|
||||
if (two == null)
|
||||
{
|
||||
ev.Add(two = new TestEvent(2, () =>
|
||||
{
|
||||
if (three == null)
|
||||
{
|
||||
ev.Add(three = new TestEvent(3, () =>
|
||||
{
|
||||
if (four == null)
|
||||
{
|
||||
ev.Add(four = new TestEvent(4));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
ev.Add(one);
|
||||
|
||||
ev.SetResult(10);
|
||||
ev.SetResult(20);
|
||||
ev.SetResult(30);
|
||||
ev.SetResult(40);
|
||||
|
||||
one.NextCalled.Should().BeEquivalentTo(10, 20, 30, 40);
|
||||
two.NextCalled.Should().BeEquivalentTo(20, 30, 40);
|
||||
three.NextCalled.Should().BeEquivalentTo(30, 40);
|
||||
four.NextCalled.Should().BeEquivalentTo(40);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TestEvent : ITriggerHandler<int>
|
||||
{
|
||||
public readonly int Id;
|
||||
readonly Action iteratingEvent;
|
||||
|
||||
public TestEvent(int id)
|
||||
{
|
||||
this.Id = id;
|
||||
}
|
||||
|
||||
public TestEvent(int id, Action iteratingEvent)
|
||||
{
|
||||
this.Id = id;
|
||||
this.iteratingEvent = iteratingEvent;
|
||||
}
|
||||
|
||||
public List<int> NextCalled = new List<int>();
|
||||
public List<Exception> ErrorCalled = new List<Exception>();
|
||||
public List<object> CompletedCalled = new List<object>();
|
||||
public List<CancellationToken> CancelCalled = new List<CancellationToken>();
|
||||
|
||||
public ITriggerHandler<int> Prev { get; set; }
|
||||
public ITriggerHandler<int> Next { get; set; }
|
||||
|
||||
public void OnCanceled(CancellationToken cancellationToken)
|
||||
{
|
||||
CancelCalled.Add(cancellationToken);
|
||||
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
CompletedCalled.Add(new object());
|
||||
}
|
||||
|
||||
public void OnError(Exception ex)
|
||||
{
|
||||
ErrorCalled.Add(ex);
|
||||
}
|
||||
|
||||
public void OnNext(int value)
|
||||
{
|
||||
NextCalled.Add(value);
|
||||
iteratingEvent?.Invoke();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Id.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
40
src/UniTask.NetCoreTests/WithCancellationTest.cs
Normal file
40
src/UniTask.NetCoreTests/WithCancellationTest.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace NetCoreTests
|
||||
{
|
||||
public class WithCancellationTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task Standard()
|
||||
{
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
|
||||
var v = await UniTask.Run(() => 10).WithCancellation(cts.Token);
|
||||
|
||||
v.Should().Be(10);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Cancel()
|
||||
{
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
|
||||
var t = UniTask.Create(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||
return 10;
|
||||
}).WithCancellation(cts.Token);
|
||||
|
||||
cts.Cancel();
|
||||
|
||||
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await t)).CancellationToken.Should().Be(cts.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
734
src/UniTask/Assembly-CSharp-firstpass.csproj
Normal file
734
src/UniTask/Assembly-CSharp-firstpass.csproj
Normal file
@@ -0,0 +1,734 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>10.0.20506</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<RootNamespace></RootNamespace>
|
||||
<ProjectGuid>{CECB0124-DA37-D676-2B9E-00C5241684F4}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<AssemblyName>Assembly-CSharp-firstpass</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<BaseDirectory>.</BaseDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Temp\Bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;UNITY_2020_2_1;UNITY_2020_2;UNITY_2020;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;USE_SEARCH_ENGINE_API;SCENE_TEMPLATE_MODULE;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;INCLUDE_DYNAMIC_GI;ENABLE_MONO_BDWGC;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;PLATFORM_STANDALONE;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;UNITY_PRO_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_LEGACY_INPUT_MANAGER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169</NoWarn>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>Temp\bin\Release\</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>0169</NoWarn>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoConfig>true</NoConfig>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
|
||||
<ImplicitlyExpandNETStandardFacades>false</ImplicitlyExpandNETStandardFacades>
|
||||
<ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<UnityProjectGenerator>Package</UnityProjectGenerator>
|
||||
<UnityProjectGeneratorVersion>2.0.5</UnityProjectGeneratorVersion>
|
||||
<UnityProjectType>GamePlugins:3</UnityProjectType>
|
||||
<UnityBuildTarget>StandaloneWindows64:19</UnityBuildTarget>
|
||||
<UnityVersion>2020.2.1f1</UnityVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="C:\Program Files (x86)\Microsoft Visual Studio Tools for Unity\16.0\Analyzers\Microsoft.Unity.Analyzers.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CompilerServices\AsyncUniTaskMethodBuilder.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.Bridge.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\EnumerableAsyncExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\Error.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Channel.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\IUniTaskSource.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Progress.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\PooledDelegate.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.WhenAny.Generated.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.uGUI.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.MonoBehaviour.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskCompletionSource.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\DiagnosticsExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CompilerServices\AsyncMethodBuilderAttribute.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\AsyncAwakeTrigger.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CompilerServices\AsyncUniTaskVoidMethodBuilder.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\IUniTaskAsyncEnumerable.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CancellationTokenSourceExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\_InternalVisibleTo.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\AsyncUnit.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\RuntimeHelpersAbstraction.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\TriggerEvent.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.Threading.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskVoid.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\TaskPool.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityBindingExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\AsyncTriggerBase.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityWebRequestException.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\WeakDictionary.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskSynchronizationContext.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\ArrayPool.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\AsyncStartTrigger.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskExtensions.Shorthand.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.Delay.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskScheduler.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.WhenAll.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.Factory.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\ValueStopwatch.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\ContinuationQueue.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\EnumeratorAsyncExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.AssetBundleRequestAllAssets.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\PlayerLoopRunner.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.WaitUntil.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.Run.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\ArrayUtil.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\MoveNextSource.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\MonoBehaviourMessagesTriggers.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\ExceptionExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\AsyncReactiveProperty.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\AsyncLazy.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.WhenAny.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\PlayerLoopHelper.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\MinimumQueue.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTask.WhenAll.Generated.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CompilerServices\StateMachineRunner.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\StatePool.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.AsyncGPUReadback.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.Jobs.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskObservableExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\UniTaskExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\AsyncTriggerExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CancellationTokenExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\ArrayPoolUtil.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\TaskTracker.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Triggers\AsyncDestroyTrigger.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\UnityEqualityComparer.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\Internal\UnityWebRequestExtensions.cs" />
|
||||
<Compile Include="Assets\Plugins\UniTask\Runtime\CancellationTokenEqualityComparer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Assets\Plugins\UniTask\Runtime\UniTask.asmdef" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ARModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ARModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AccessibilityModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AccessibilityModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AndroidJNIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AndroidJNIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterInputModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterInputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClusterRendererModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ClusterRendererModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CrashReportingModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.CrashReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DSPGraphModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.DSPGraphModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.DirectorModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.DirectorModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.GIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GameCenterModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.GameCenterModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.GridModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.GridModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.HotReloadModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.HotReloadModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ImageConversionModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ImageConversionModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.JSONSerializeModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.JSONSerializeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.LocalizationModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.LocalizationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PerformanceReportingModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.PerformanceReportingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ProfilerModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ProfilerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ScreenCaptureModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.ScreenCaptureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SharedInternalsModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.SharedInternalsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteMaskModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteMaskModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SpriteShapeModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.SpriteShapeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.StreamingModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.StreamingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.SubstanceModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.SubstanceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TLSModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.TLSModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TerrainModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.TerrainModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIElementsNativeModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UIElementsNativeModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UNETModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UNETModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UmbraModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UmbraModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityAnalyticsModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityAnalyticsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityConnectModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityCurlModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityCurlModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityTestProtocolModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityTestProtocolModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAssetBundleModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestAudioModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestAudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestTextureModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestTextureModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UnityWebRequestWWWModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.UnityWebRequestWWWModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VFXModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.VFXModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VideoModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.VideoModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.VirtualTexturingModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.VirtualTexturingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.WindModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEngine.WindModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CoreModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.GraphViewModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.GraphViewModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.PackageManagerUIModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.PackageManagerUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.SceneTemplateModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.SceneTemplateModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIElementsSamplesModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIElementsSamplesModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UIServiceModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.UIServiceModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.UnityConnectModule">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\Managed\UnityEngine\UnityEditor.UnityConnectModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>Library\PackageCache\com.unity.ext.nunit@1.0.5\net35\unity-custom\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\ref\2.0.0\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.AppContext">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Concurrent">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Collections.Concurrent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.NonGeneric">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Collections.NonGeneric.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Specialized">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Collections.Specialized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ComponentModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.EventBasedAsync">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ComponentModel.EventBasedAsync.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ComponentModel.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.TypeConverter">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ComponentModel.TypeConverter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Console">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.Common">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Data.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Contracts">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Debug">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.Debug.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.FileVersionInfo">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.FileVersionInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Process">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.Process.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.StackTrace">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.StackTrace.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TextWriterTraceListener">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.TextWriterTraceListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tools">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.Tools.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.TraceSource">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.TraceSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Drawing.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Dynamic.Runtime">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Dynamic.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Globalization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Extensions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Globalization.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.ZipFile">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.DriveInfo">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.FileSystem.DriveInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Watcher">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.FileSystem.Watcher.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.IsolatedStorage">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.IsolatedStorage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.MemoryMappedFiles">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.MemoryMappedFiles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Pipes">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.Pipes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.UnmanagedMemoryStream">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.IO.UnmanagedMemoryStream.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Parallel">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Linq.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Queryable">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Linq.Queryable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NameResolution">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.NameResolution.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.NetworkInformation">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.NetworkInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Ping">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Ping.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Requests">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Requests.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Security">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebHeaderCollection">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.WebHeaderCollection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets.Client">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.WebSockets.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.WebSockets">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Net.WebSockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ObjectModel">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ObjectModel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Extensions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Reflection.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Reflection.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Reader">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Resources.Reader.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.ResourceManager">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Resources.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Resources.Writer">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Resources.Writer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.VisualC">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.CompilerServices.VisualC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Handles">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Handles.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Numerics">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Serialization.Formatters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Json">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Serialization.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Serialization.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Xml">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Runtime.Serialization.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Claims">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Csp">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Cryptography.Csp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.Principal.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.SecureString">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Security.SecureString.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Text.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encoding.Extensions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Text.Encoding.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Overlapped">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.Overlapped.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Parallel">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.Tasks.Parallel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Thread">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.Thread.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.ThreadPool">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.ThreadPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Timer">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Threading.Timer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.ReaderWriter">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XDocument">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlDocument">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.XmlDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XmlSerializer">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.XmlSerializer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.XPath.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.XPath.XDocument">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netstandard\System.Xml.XPath.XDocument.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics.Vectors">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\Extensions\2.0.0\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.WindowsRuntime">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\Extensions\2.0.0\System.Runtime.InteropServices.WindowsRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\mscorlib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.ComponentModel.Composition.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Drawing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.IO.Compression.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Runtime.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.ServiceModel.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Transactions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Xml.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Xml.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization">
|
||||
<HintPath>C:\Program Files\Unity\Hub\Editor\2020.2.1f1\Editor\Data\NetStandard\compat\2.0.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VSCode.Editor">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.VSCode.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEditor.CacheServer">
|
||||
<HintPath>Library\ScriptAssemblies\UnityEditor.CacheServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.VisualStudio.Editor">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.VisualStudio.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Addressables">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.Addressables.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ScriptableBuildPipeline">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.ScriptableBuildPipeline.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Addressables.Editor">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.Addressables.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ScriptableBuildPipeline.Editor">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.ScriptableBuildPipeline.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.ResourceManager">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.ResourceManager.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Rider.Editor">
|
||||
<HintPath>Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="UniTask.TextMeshPro.csproj">
|
||||
<Project>{B5929667-6CB2-8779-D894-4F69110C1A43}</Project>
|
||||
<Name>UniTask.TextMeshPro</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="TempAsm.csproj">
|
||||
<Project>{9E0EF10C-B6E1-E08E-3160-7162D66F7EE0}</Project>
|
||||
<Name>TempAsm</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.DOTween.csproj">
|
||||
<Project>{7121D833-D063-D143-CFFC-CD50DDF1B3D1}</Project>
|
||||
<Name>UniTask.DOTween</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.Addressables.csproj">
|
||||
<Project>{78124C71-0355-1FB9-3AEB-7D573CD8E7CA}</Project>
|
||||
<Name>UniTask.Addressables</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="UniTask.Linq.csproj">
|
||||
<Project>{7F0F67EA-D985-C15F-AAE8-F643789B52A7}</Project>
|
||||
<Name>UniTask.Linq</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="GenerateTargetFrameworkMonikerAttribute" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
31
src/UniTask/Assets/Editor/EditorRunnerChecker.cs
Normal file
31
src/UniTask/Assets/Editor/EditorRunnerChecker.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
public static class EditorRunnerChecker
|
||||
{
|
||||
[MenuItem("Tools/UniTaskEditorRunnerChecker")]
|
||||
public static void RunUniTaskAsync()
|
||||
{
|
||||
RunCore().Forget();
|
||||
}
|
||||
|
||||
static async UniTaskVoid RunCore()
|
||||
{
|
||||
Debug.Log("Start");
|
||||
|
||||
//var r = await UnityWebRequest.Get("https://bing.com/").SendWebRequest().ToUniTask();
|
||||
//Debug.Log(r.downloadHandler.text.Substring(0, 100));
|
||||
await UniTask.Yield();
|
||||
|
||||
Debug.Log("End");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d5a9a3e1f0f069478969f752fde29a9
|
||||
guid: e51b78c06cb410f42b36e0af9de3b065
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -10,7 +10,7 @@
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
|
||||
@@ -7,113 +7,239 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public class AsyncLazy
|
||||
{
|
||||
Func<UniTask> valueFactory;
|
||||
UniTask target;
|
||||
static Action<object> continuation = SetCompletionSource;
|
||||
|
||||
Func<UniTask> taskFactory;
|
||||
UniTaskCompletionSource completionSource;
|
||||
UniTask.Awaiter awaiter;
|
||||
|
||||
object syncLock;
|
||||
bool initialized;
|
||||
|
||||
public AsyncLazy(Func<UniTask> valueFactory)
|
||||
public AsyncLazy(Func<UniTask> taskFactory)
|
||||
{
|
||||
this.valueFactory = valueFactory;
|
||||
this.target = default;
|
||||
this.taskFactory = taskFactory;
|
||||
this.completionSource = new UniTaskCompletionSource();
|
||||
this.syncLock = new object();
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
internal AsyncLazy(UniTask value)
|
||||
internal AsyncLazy(UniTask task)
|
||||
{
|
||||
this.valueFactory = null;
|
||||
this.target = value;
|
||||
this.taskFactory = null;
|
||||
this.completionSource = new UniTaskCompletionSource();
|
||||
this.syncLock = null;
|
||||
this.initialized = true;
|
||||
|
||||
var awaiter = task.GetAwaiter();
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
SetCompletionSource(awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.awaiter = awaiter;
|
||||
awaiter.SourceOnCompleted(continuation, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask Task => EnsureInitialized();
|
||||
public UniTask Task
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return completionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask.Awaiter GetAwaiter() => EnsureInitialized().GetAwaiter();
|
||||
|
||||
UniTask EnsureInitialized()
|
||||
public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
void EnsureInitialized()
|
||||
{
|
||||
if (Volatile.Read(ref initialized))
|
||||
{
|
||||
return target;
|
||||
return;
|
||||
}
|
||||
|
||||
return EnsureInitializedCore();
|
||||
EnsureInitializedCore();
|
||||
}
|
||||
|
||||
UniTask EnsureInitializedCore()
|
||||
void EnsureInitializedCore()
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
if (!Volatile.Read(ref initialized))
|
||||
{
|
||||
var f = Interlocked.Exchange(ref valueFactory, null);
|
||||
var f = Interlocked.Exchange(ref taskFactory, null);
|
||||
if (f != null)
|
||||
{
|
||||
target = f().Preserve(); // with preserve(allow multiple await).
|
||||
var task = f();
|
||||
var awaiter = task.GetAwaiter();
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
SetCompletionSource(awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.awaiter = awaiter;
|
||||
awaiter.SourceOnCompleted(continuation, this);
|
||||
}
|
||||
|
||||
Volatile.Write(ref initialized, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
void SetCompletionSource(in UniTask.Awaiter awaiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
awaiter.GetResult();
|
||||
completionSource.TrySetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetCompletionSource(object state)
|
||||
{
|
||||
var self = (AsyncLazy)state;
|
||||
try
|
||||
{
|
||||
self.awaiter.GetResult();
|
||||
self.completionSource.TrySetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
self.awaiter = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AsyncLazy<T>
|
||||
{
|
||||
Func<UniTask<T>> valueFactory;
|
||||
UniTask<T> target;
|
||||
static Action<object> continuation = SetCompletionSource;
|
||||
|
||||
Func<UniTask<T>> taskFactory;
|
||||
UniTaskCompletionSource<T> completionSource;
|
||||
UniTask<T>.Awaiter awaiter;
|
||||
|
||||
object syncLock;
|
||||
bool initialized;
|
||||
|
||||
public AsyncLazy(Func<UniTask<T>> valueFactory)
|
||||
public AsyncLazy(Func<UniTask<T>> taskFactory)
|
||||
{
|
||||
this.valueFactory = valueFactory;
|
||||
this.target = default;
|
||||
this.taskFactory = taskFactory;
|
||||
this.completionSource = new UniTaskCompletionSource<T>();
|
||||
this.syncLock = new object();
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
internal AsyncLazy(UniTask<T> value)
|
||||
internal AsyncLazy(UniTask<T> task)
|
||||
{
|
||||
this.valueFactory = null;
|
||||
this.target = value;
|
||||
this.taskFactory = null;
|
||||
this.completionSource = new UniTaskCompletionSource<T>();
|
||||
this.syncLock = null;
|
||||
this.initialized = true;
|
||||
|
||||
var awaiter = task.GetAwaiter();
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
SetCompletionSource(awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.awaiter = awaiter;
|
||||
awaiter.SourceOnCompleted(continuation, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask<T> Task => EnsureInitialized();
|
||||
public UniTask<T> Task
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureInitialized();
|
||||
return completionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask<T>.Awaiter GetAwaiter() => EnsureInitialized().GetAwaiter();
|
||||
|
||||
UniTask<T> EnsureInitialized()
|
||||
public UniTask<T>.Awaiter GetAwaiter() => Task.GetAwaiter();
|
||||
|
||||
void EnsureInitialized()
|
||||
{
|
||||
if (Volatile.Read(ref initialized))
|
||||
{
|
||||
return target;
|
||||
return;
|
||||
}
|
||||
|
||||
return EnsureInitializedCore();
|
||||
EnsureInitializedCore();
|
||||
}
|
||||
|
||||
UniTask<T> EnsureInitializedCore()
|
||||
void EnsureInitializedCore()
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
if (!Volatile.Read(ref initialized))
|
||||
{
|
||||
var f = Interlocked.Exchange(ref valueFactory, null);
|
||||
var f = Interlocked.Exchange(ref taskFactory, null);
|
||||
if (f != null)
|
||||
{
|
||||
target = f().Preserve(); // with preserve(allow multiple await).
|
||||
var task = f();
|
||||
var awaiter = task.GetAwaiter();
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
SetCompletionSource(awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.awaiter = awaiter;
|
||||
awaiter.SourceOnCompleted(continuation, this);
|
||||
}
|
||||
|
||||
Volatile.Write(ref initialized, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
void SetCompletionSource(in UniTask<T>.Awaiter awaiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = awaiter.GetResult();
|
||||
completionSource.TrySetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetCompletionSource(object state)
|
||||
{
|
||||
var self = (AsyncLazy<T>)state;
|
||||
try
|
||||
{
|
||||
var result = self.awaiter.GetResult();
|
||||
self.completionSource.TrySetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completionSource.TrySetException(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
self.awaiter = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,644 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public interface IReadOnlyAsyncReactiveProperty<T> : IUniTaskAsyncEnumerable<T>
|
||||
{
|
||||
T Value { get; }
|
||||
IUniTaskAsyncEnumerable<T> WithoutCurrent();
|
||||
UniTask<T> WaitAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public interface IAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>
|
||||
{
|
||||
new T Value { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AsyncReactiveProperty<T> : IAsyncReactiveProperty<T>, IDisposable
|
||||
{
|
||||
TriggerEvent<T> triggerEvent;
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
[UnityEngine.SerializeField]
|
||||
#endif
|
||||
T latestValue;
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return latestValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.latestValue = value;
|
||||
triggerEvent.SetResult(value);
|
||||
}
|
||||
}
|
||||
|
||||
public AsyncReactiveProperty(T value)
|
||||
{
|
||||
this.latestValue = value;
|
||||
this.triggerEvent = default;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
|
||||
{
|
||||
return new WithoutCurrentEnumerable(this);
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
|
||||
{
|
||||
return new Enumerator(this, cancellationToken, true);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
triggerEvent.SetCompleted();
|
||||
}
|
||||
|
||||
public static implicit operator T(AsyncReactiveProperty<T> value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (isValueType) return latestValue.ToString();
|
||||
return latestValue?.ToString();
|
||||
}
|
||||
|
||||
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
static bool isValueType;
|
||||
|
||||
static AsyncReactiveProperty()
|
||||
{
|
||||
isValueType = typeof(T).IsValueType;
|
||||
}
|
||||
|
||||
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
|
||||
{
|
||||
static Action<object> cancellationCallback = CancellationCallback;
|
||||
|
||||
static TaskPool<WaitAsyncSource> pool;
|
||||
WaitAsyncSource nextNode;
|
||||
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
|
||||
|
||||
static WaitAsyncSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
|
||||
}
|
||||
|
||||
AsyncReactiveProperty<T> parent;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
WaitAsyncSource()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new WaitAsyncSource();
|
||||
}
|
||||
|
||||
result.parent = parent;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
|
||||
}
|
||||
|
||||
result.parent.triggerEvent.Add(result);
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancellationTokenRegistration = default;
|
||||
parent.triggerEvent.Remove(this);
|
||||
parent = null;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
static void CancellationCallback(object state)
|
||||
{
|
||||
var self = (WaitAsyncSource)state;
|
||||
self.OnCanceled(self.cancellationToken);
|
||||
}
|
||||
|
||||
// IUniTaskSource
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
// ITriggerHandler
|
||||
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
|
||||
|
||||
public void OnCanceled(CancellationToken cancellationToken)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
// Complete as Cancel.
|
||||
core.TrySetCanceled(CancellationToken.None);
|
||||
}
|
||||
|
||||
public void OnError(Exception ex)
|
||||
{
|
||||
core.TrySetException(ex);
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
core.TrySetResult(value);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
|
||||
{
|
||||
readonly AsyncReactiveProperty<T> parent;
|
||||
|
||||
public WithoutCurrentEnumerable(AsyncReactiveProperty<T> parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(parent, cancellationToken, false);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
|
||||
{
|
||||
static Action<object> cancellationCallback = CancellationCallback;
|
||||
|
||||
readonly AsyncReactiveProperty<T> parent;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
T value;
|
||||
bool isDisposed;
|
||||
bool firstCall;
|
||||
|
||||
public Enumerator(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancellationToken = cancellationToken;
|
||||
this.firstCall = publishCurrentValue;
|
||||
|
||||
parent.triggerEvent.Add(this);
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
|
||||
}
|
||||
}
|
||||
|
||||
public T Current => value;
|
||||
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// raise latest value on first call.
|
||||
if (firstCall)
|
||||
{
|
||||
firstCall = false;
|
||||
value = parent.Value;
|
||||
return CompletedTasks.True;
|
||||
}
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
parent.triggerEvent.Remove(this);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
this.value = value;
|
||||
completionSource.TrySetResult(true);
|
||||
}
|
||||
|
||||
public void OnCanceled(CancellationToken cancellationToken)
|
||||
{
|
||||
DisposeAsync().Forget();
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
}
|
||||
|
||||
public void OnError(Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
|
||||
static void CancellationCallback(object state)
|
||||
{
|
||||
var self = (Enumerator)state;
|
||||
self.DisposeAsync().Forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ReadOnlyAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>, IDisposable
|
||||
{
|
||||
TriggerEvent<T> triggerEvent;
|
||||
|
||||
T latestValue;
|
||||
IUniTaskAsyncEnumerator<T> enumerator;
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return latestValue;
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyAsyncReactiveProperty(T initialValue, IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
|
||||
{
|
||||
latestValue = initialValue;
|
||||
ConsumeEnumerator(source, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
public ReadOnlyAsyncReactiveProperty(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
|
||||
{
|
||||
ConsumeEnumerator(source, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
async UniTaskVoid ConsumeEnumerator(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
|
||||
{
|
||||
enumerator = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await enumerator.MoveNextAsync())
|
||||
{
|
||||
var value = enumerator.Current;
|
||||
this.latestValue = value;
|
||||
triggerEvent.SetResult(value);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await enumerator.DisposeAsync();
|
||||
enumerator = null;
|
||||
}
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
|
||||
{
|
||||
return new WithoutCurrentEnumerable(this);
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
|
||||
{
|
||||
return new Enumerator(this, cancellationToken, true);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (enumerator != null)
|
||||
{
|
||||
enumerator.DisposeAsync().Forget();
|
||||
}
|
||||
|
||||
triggerEvent.SetCompleted();
|
||||
}
|
||||
|
||||
public static implicit operator T(ReadOnlyAsyncReactiveProperty<T> value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (isValueType) return latestValue.ToString();
|
||||
return latestValue?.ToString();
|
||||
}
|
||||
|
||||
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
static bool isValueType;
|
||||
|
||||
static ReadOnlyAsyncReactiveProperty()
|
||||
{
|
||||
isValueType = typeof(T).IsValueType;
|
||||
}
|
||||
|
||||
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
|
||||
{
|
||||
static Action<object> cancellationCallback = CancellationCallback;
|
||||
|
||||
static TaskPool<WaitAsyncSource> pool;
|
||||
WaitAsyncSource nextNode;
|
||||
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
|
||||
|
||||
static WaitAsyncSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
|
||||
}
|
||||
|
||||
ReadOnlyAsyncReactiveProperty<T> parent;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
WaitAsyncSource()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new WaitAsyncSource();
|
||||
}
|
||||
|
||||
result.parent = parent;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
|
||||
}
|
||||
|
||||
result.parent.triggerEvent.Add(result);
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancellationTokenRegistration = default;
|
||||
parent.triggerEvent.Remove(this);
|
||||
parent = null;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
static void CancellationCallback(object state)
|
||||
{
|
||||
var self = (WaitAsyncSource)state;
|
||||
self.OnCanceled(self.cancellationToken);
|
||||
}
|
||||
|
||||
// IUniTaskSource
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
// ITriggerHandler
|
||||
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
|
||||
|
||||
public void OnCanceled(CancellationToken cancellationToken)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
// Complete as Cancel.
|
||||
core.TrySetCanceled(CancellationToken.None);
|
||||
}
|
||||
|
||||
public void OnError(Exception ex)
|
||||
{
|
||||
core.TrySetException(ex);
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
core.TrySetResult(value);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
|
||||
{
|
||||
readonly ReadOnlyAsyncReactiveProperty<T> parent;
|
||||
|
||||
public WithoutCurrentEnumerable(ReadOnlyAsyncReactiveProperty<T> parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(parent, cancellationToken, false);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
|
||||
{
|
||||
static Action<object> cancellationCallback = CancellationCallback;
|
||||
|
||||
readonly ReadOnlyAsyncReactiveProperty<T> parent;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
T value;
|
||||
bool isDisposed;
|
||||
bool firstCall;
|
||||
|
||||
public Enumerator(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancellationToken = cancellationToken;
|
||||
this.firstCall = publishCurrentValue;
|
||||
|
||||
parent.triggerEvent.Add(this);
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
|
||||
}
|
||||
}
|
||||
|
||||
public T Current => value;
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
|
||||
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// raise latest value on first call.
|
||||
if (firstCall)
|
||||
{
|
||||
firstCall = false;
|
||||
value = parent.Value;
|
||||
return CompletedTasks.True;
|
||||
}
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
isDisposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
parent.triggerEvent.Remove(this);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public void OnNext(T value)
|
||||
{
|
||||
this.value = value;
|
||||
completionSource.TrySetResult(true);
|
||||
}
|
||||
|
||||
public void OnCanceled(CancellationToken cancellationToken)
|
||||
{
|
||||
DisposeAsync().Forget();
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
}
|
||||
|
||||
public void OnError(Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
}
|
||||
|
||||
static void CancellationCallback(object state)
|
||||
{
|
||||
var self = (Enumerator)state;
|
||||
self.DisposeAsync().Forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class StateExtensions
|
||||
{
|
||||
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
|
||||
{
|
||||
return new ReadOnlyAsyncReactiveProperty<T>(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, T initialValue, CancellationToken cancellationToken)
|
||||
{
|
||||
return new ReadOnlyAsyncReactiveProperty<T>(initialValue, source, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcb1f7467a3e2b64c8a016c8aee2f9b4
|
||||
guid: 8ef320b87f537ee4fb2282e765dc6166
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public struct AsyncUnit : IEquatable<AsyncUnit>
|
||||
public readonly struct AsyncUnit : IEquatable<AsyncUnit>
|
||||
{
|
||||
public static readonly AsyncUnit Default = new AsyncUnit();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
@@ -8,16 +9,66 @@ namespace Cysharp.Threading.Tasks
|
||||
public static class CancellationTokenExtensions
|
||||
{
|
||||
static readonly Action<object> cancellationTokenCallback = Callback;
|
||||
static readonly Action<object> disposeCallback = DisposeCallback;
|
||||
|
||||
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cts)
|
||||
public static CancellationToken ToCancellationToken(this UniTask task)
|
||||
{
|
||||
if (cts.IsCancellationRequested)
|
||||
var cts = new CancellationTokenSource();
|
||||
ToCancellationTokenCore(task, cts).Forget();
|
||||
return cts.Token;
|
||||
}
|
||||
|
||||
public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken)
|
||||
{
|
||||
if (linkToken.IsCancellationRequested)
|
||||
{
|
||||
return (UniTask.FromCanceled(cts), default(CancellationTokenRegistration));
|
||||
return linkToken;
|
||||
}
|
||||
|
||||
if (!linkToken.CanBeCanceled)
|
||||
{
|
||||
return ToCancellationToken(task);
|
||||
}
|
||||
|
||||
var cts = CancellationTokenSource.CreateLinkedTokenSource(linkToken);
|
||||
ToCancellationTokenCore(task, cts).Forget();
|
||||
|
||||
return cts.Token;
|
||||
}
|
||||
|
||||
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task)
|
||||
{
|
||||
return ToCancellationToken(task.AsUniTask());
|
||||
}
|
||||
|
||||
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task, CancellationToken linkToken)
|
||||
{
|
||||
return ToCancellationToken(task.AsUniTask(), linkToken);
|
||||
}
|
||||
|
||||
static async UniTaskVoid ToCancellationTokenCore(UniTask task, CancellationTokenSource cts)
|
||||
{
|
||||
try
|
||||
{
|
||||
await task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UniTaskScheduler.PublishUnobservedTaskException(ex);
|
||||
}
|
||||
cts.Cancel();
|
||||
cts.Dispose();
|
||||
}
|
||||
|
||||
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return (UniTask.FromCanceled(cancellationToken), default(CancellationTokenRegistration));
|
||||
}
|
||||
|
||||
var promise = new UniTaskCompletionSource();
|
||||
return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
|
||||
return (promise.Task, cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
|
||||
}
|
||||
|
||||
static void Callback(object state)
|
||||
@@ -26,6 +77,11 @@ namespace Cysharp.Threading.Tasks
|
||||
promise.TrySetResult();
|
||||
}
|
||||
|
||||
public static CancellationTokenAwaitable WaitUntilCanceled(this CancellationToken cancellationToken)
|
||||
{
|
||||
return new CancellationTokenAwaitable(cancellationToken);
|
||||
}
|
||||
|
||||
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
|
||||
{
|
||||
var restoreFlow = false;
|
||||
@@ -69,6 +125,58 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CancellationTokenRegistration AddTo(this IDisposable disposable, CancellationToken cancellationToken)
|
||||
{
|
||||
return cancellationToken.RegisterWithoutCaptureExecutionContext(disposeCallback, disposable);
|
||||
}
|
||||
|
||||
static void DisposeCallback(object state)
|
||||
{
|
||||
var d = (IDisposable)state;
|
||||
d.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public struct CancellationTokenAwaitable
|
||||
{
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
public CancellationTokenAwaitable(CancellationToken cancellationToken)
|
||||
{
|
||||
this.cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
public Awaiter GetAwaiter()
|
||||
{
|
||||
return new Awaiter(cancellationToken);
|
||||
}
|
||||
|
||||
public struct Awaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
public Awaiter(CancellationToken cancellationToken)
|
||||
{
|
||||
this.cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
public bool IsCompleted => !cancellationToken.CanBeCanceled || cancellationToken.IsCancellationRequested;
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
UnsafeOnCompleted(continuation);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
cancellationToken.RegisterWithoutCaptureExecutionContext(continuation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class CancellationTokenSourceExtensions
|
||||
{
|
||||
public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
|
||||
public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
|
||||
{
|
||||
var delay = UniTask.Delay(millisecondsDelay, ignoreTimeScale, delayTiming, cts.Token);
|
||||
var delay = UniTask.Delay(millisecondsDelay, delayType, delayTiming, cts.Token);
|
||||
CancelAfterCore(cts, delay).Forget();
|
||||
}
|
||||
|
||||
public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
|
||||
public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
|
||||
{
|
||||
var delay = UniTask.Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cts.Token);
|
||||
var delay = UniTask.Delay(delayTimeSpan, delayType, delayTiming, cts.Token);
|
||||
CancelAfterCore(cts, delay).Forget();
|
||||
}
|
||||
|
||||
|
||||
450
src/UniTask/Assets/Plugins/UniTask/Runtime/Channel.cs
Normal file
450
src/UniTask/Assets/Plugins/UniTask/Runtime/Channel.cs
Normal file
@@ -0,0 +1,450 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class Channel
|
||||
{
|
||||
public static Channel<T> CreateSingleConsumerUnbounded<T>()
|
||||
{
|
||||
return new SingleConsumerUnboundedChannel<T>();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Channel<TWrite, TRead>
|
||||
{
|
||||
public ChannelReader<TRead> Reader { get; protected set; }
|
||||
public ChannelWriter<TWrite> Writer { get; protected set; }
|
||||
|
||||
public static implicit operator ChannelReader<TRead>(Channel<TWrite, TRead> channel) => channel.Reader;
|
||||
public static implicit operator ChannelWriter<TWrite>(Channel<TWrite, TRead> channel) => channel.Writer;
|
||||
}
|
||||
|
||||
public abstract class Channel<T> : Channel<T, T>
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class ChannelReader<T>
|
||||
{
|
||||
public abstract bool TryRead(out T item);
|
||||
public abstract UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
public abstract UniTask Completion { get; }
|
||||
|
||||
public virtual UniTask<T> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (this.TryRead(out var item))
|
||||
{
|
||||
return UniTask.FromResult(item);
|
||||
}
|
||||
|
||||
return ReadAsyncCore(cancellationToken);
|
||||
}
|
||||
|
||||
async UniTask<T> ReadAsyncCore(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (await WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
if (TryRead(out var item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ChannelClosedException();
|
||||
}
|
||||
|
||||
public abstract IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default(CancellationToken));
|
||||
}
|
||||
|
||||
public abstract class ChannelWriter<T>
|
||||
{
|
||||
public abstract bool TryWrite(T item);
|
||||
public abstract bool TryComplete(Exception error = null);
|
||||
|
||||
public void Complete(Exception error = null)
|
||||
{
|
||||
if (!TryComplete(error))
|
||||
{
|
||||
throw new ChannelClosedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ChannelClosedException : InvalidOperationException
|
||||
{
|
||||
public ChannelClosedException() :
|
||||
base("Channel is already closed.")
|
||||
{ }
|
||||
|
||||
public ChannelClosedException(string message) : base(message) { }
|
||||
|
||||
public ChannelClosedException(Exception innerException) :
|
||||
base("Channel is already closed", innerException)
|
||||
{ }
|
||||
|
||||
public ChannelClosedException(string message, Exception innerException) : base(message, innerException) { }
|
||||
}
|
||||
|
||||
internal class SingleConsumerUnboundedChannel<T> : Channel<T>
|
||||
{
|
||||
readonly Queue<T> items;
|
||||
readonly SingleConsumerUnboundedChannelReader readerSource;
|
||||
UniTaskCompletionSource completedTaskSource;
|
||||
UniTask completedTask;
|
||||
|
||||
Exception completionError;
|
||||
bool closed;
|
||||
|
||||
public SingleConsumerUnboundedChannel()
|
||||
{
|
||||
items = new Queue<T>();
|
||||
Writer = new SingleConsumerUnboundedChannelWriter(this);
|
||||
readerSource = new SingleConsumerUnboundedChannelReader(this);
|
||||
Reader = readerSource;
|
||||
}
|
||||
|
||||
sealed class SingleConsumerUnboundedChannelWriter : ChannelWriter<T>
|
||||
{
|
||||
readonly SingleConsumerUnboundedChannel<T> parent;
|
||||
|
||||
public SingleConsumerUnboundedChannelWriter(SingleConsumerUnboundedChannel<T> parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override bool TryWrite(T item)
|
||||
{
|
||||
bool waiting;
|
||||
lock (parent.items)
|
||||
{
|
||||
if (parent.closed) return false;
|
||||
|
||||
parent.items.Enqueue(item);
|
||||
waiting = parent.readerSource.isWaiting;
|
||||
}
|
||||
|
||||
if (waiting)
|
||||
{
|
||||
parent.readerSource.SingalContinuation();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryComplete(Exception error = null)
|
||||
{
|
||||
bool waiting;
|
||||
lock (parent.items)
|
||||
{
|
||||
if (parent.closed) return false;
|
||||
parent.closed = true;
|
||||
waiting = parent.readerSource.isWaiting;
|
||||
|
||||
if (parent.items.Count == 0)
|
||||
{
|
||||
if (error == null)
|
||||
{
|
||||
if (parent.completedTaskSource != null)
|
||||
{
|
||||
parent.completedTaskSource.TrySetResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.completedTask = UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent.completedTaskSource != null)
|
||||
{
|
||||
parent.completedTaskSource.TrySetException(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.completedTask = UniTask.FromException(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (waiting)
|
||||
{
|
||||
parent.readerSource.SingalCompleted(error);
|
||||
}
|
||||
}
|
||||
|
||||
parent.completionError = error;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SingleConsumerUnboundedChannelReader : ChannelReader<T>, IUniTaskSource<bool>
|
||||
{
|
||||
readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
|
||||
readonly SingleConsumerUnboundedChannel<T> parent;
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
UniTaskCompletionSourceCore<bool> core;
|
||||
internal bool isWaiting;
|
||||
|
||||
public SingleConsumerUnboundedChannelReader(SingleConsumerUnboundedChannel<T> parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 4);
|
||||
}
|
||||
|
||||
public override UniTask Completion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (parent.completedTaskSource != null) return parent.completedTaskSource.Task;
|
||||
|
||||
if (parent.closed)
|
||||
{
|
||||
return parent.completedTask;
|
||||
}
|
||||
|
||||
parent.completedTaskSource = new UniTaskCompletionSource();
|
||||
return parent.completedTaskSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryRead(out T item)
|
||||
{
|
||||
lock (parent.items)
|
||||
{
|
||||
if (parent.items.Count != 0)
|
||||
{
|
||||
item = parent.items.Dequeue();
|
||||
|
||||
// complete when all value was consumed.
|
||||
if (parent.closed && parent.items.Count == 0)
|
||||
{
|
||||
if (parent.completionError != null)
|
||||
{
|
||||
if (parent.completedTaskSource != null)
|
||||
{
|
||||
parent.completedTaskSource.TrySetException(parent.completionError);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.completedTask = UniTask.FromException(parent.completionError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent.completedTaskSource != null)
|
||||
{
|
||||
parent.completedTaskSource.TrySetResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.completedTask = UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return UniTask.FromCanceled<bool>(cancellationToken);
|
||||
}
|
||||
|
||||
lock (parent.items)
|
||||
{
|
||||
if (parent.items.Count != 0)
|
||||
{
|
||||
return CompletedTasks.True;
|
||||
}
|
||||
|
||||
if (parent.closed)
|
||||
{
|
||||
if (parent.completionError == null)
|
||||
{
|
||||
return CompletedTasks.False;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UniTask.FromException<bool>(parent.completionError);
|
||||
}
|
||||
}
|
||||
|
||||
cancellationTokenRegistration.Dispose();
|
||||
|
||||
core.Reset();
|
||||
isWaiting = true;
|
||||
|
||||
this.cancellationToken = cancellationToken;
|
||||
if (this.cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
|
||||
}
|
||||
|
||||
return new UniTask<bool>(this, core.Version);
|
||||
}
|
||||
}
|
||||
|
||||
public void SingalContinuation()
|
||||
{
|
||||
core.TrySetResult(true);
|
||||
}
|
||||
|
||||
public void SingalCancellation(CancellationToken cancellationToken)
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
public void SingalCompleted(Exception error)
|
||||
{
|
||||
if (error != null)
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.TrySetException(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.TrySetResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new ReadAllAsyncEnumerable(this, cancellationToken);
|
||||
}
|
||||
|
||||
bool IUniTaskSource<bool>.GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
|
||||
UniTaskStatus IUniTaskSource.GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
static void CancellationCallback(object state)
|
||||
{
|
||||
var self = (SingleConsumerUnboundedChannelReader)state;
|
||||
self.SingalCancellation(self.cancellationToken);
|
||||
}
|
||||
|
||||
sealed class ReadAllAsyncEnumerable : IUniTaskAsyncEnumerable<T>, IUniTaskAsyncEnumerator<T>
|
||||
{
|
||||
readonly Action<object> CancellationCallback1Delegate = CancellationCallback1;
|
||||
readonly Action<object> CancellationCallback2Delegate = CancellationCallback2;
|
||||
|
||||
readonly SingleConsumerUnboundedChannelReader parent;
|
||||
CancellationToken cancellationToken1;
|
||||
CancellationToken cancellationToken2;
|
||||
CancellationTokenRegistration cancellationTokenRegistration1;
|
||||
CancellationTokenRegistration cancellationTokenRegistration2;
|
||||
|
||||
T current;
|
||||
bool cacheValue;
|
||||
bool running;
|
||||
|
||||
public ReadAllAsyncEnumerable(SingleConsumerUnboundedChannelReader parent, CancellationToken cancellationToken)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.cancellationToken1 = cancellationToken;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (running)
|
||||
{
|
||||
throw new InvalidOperationException("Enumerator is already running, does not allow call GetAsyncEnumerator twice.");
|
||||
}
|
||||
|
||||
if (this.cancellationToken1 != cancellationToken)
|
||||
{
|
||||
this.cancellationToken2 = cancellationToken;
|
||||
}
|
||||
|
||||
if (this.cancellationToken1.CanBeCanceled)
|
||||
{
|
||||
this.cancellationTokenRegistration1 = this.cancellationToken1.RegisterWithoutCaptureExecutionContext(CancellationCallback1Delegate, this);
|
||||
}
|
||||
|
||||
if (this.cancellationToken2.CanBeCanceled)
|
||||
{
|
||||
this.cancellationTokenRegistration2 = this.cancellationToken2.RegisterWithoutCaptureExecutionContext(CancellationCallback2Delegate, this);
|
||||
}
|
||||
|
||||
running = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public T Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cacheValue)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
parent.TryRead(out current);
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
cacheValue = false;
|
||||
return parent.WaitToReadAsync(CancellationToken.None); // ok to use None, registered in ctor.
|
||||
}
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
cancellationTokenRegistration1.Dispose();
|
||||
cancellationTokenRegistration2.Dispose();
|
||||
return default;
|
||||
}
|
||||
|
||||
static void CancellationCallback1(object state)
|
||||
{
|
||||
var self = (ReadAllAsyncEnumerable)state;
|
||||
self.parent.SingalCancellation(self.cancellationToken1);
|
||||
}
|
||||
|
||||
static void CancellationCallback2(object state)
|
||||
{
|
||||
var self = (ReadAllAsyncEnumerable)state;
|
||||
self.parent.SingalCancellation(self.cancellationToken2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/UniTask/Assets/Plugins/UniTask/Runtime/Channel.cs.meta
Normal file
11
src/UniTask/Assets/Plugins/UniTask/Runtime/Channel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ceb3107bbdd1f14eb39091273798360
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -12,9 +12,8 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskMethodBuilder
|
||||
{
|
||||
// cache items.
|
||||
AutoResetUniTaskCompletionSource promise;
|
||||
IMoveNextRunner runner;
|
||||
IStateMachineRunnerPromise runnerPromise;
|
||||
Exception ex;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
@@ -31,98 +30,81 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (promise != null)
|
||||
if (runnerPromise != null)
|
||||
{
|
||||
return promise.Task;
|
||||
return runnerPromise.Task;
|
||||
}
|
||||
|
||||
if (runner == null)
|
||||
else if (ex != null)
|
||||
{
|
||||
return UniTask.FromException(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
return promise.Task;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise != null)
|
||||
{
|
||||
promise.TrySetException(exception);
|
||||
ex = exception;
|
||||
}
|
||||
else
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.CreateFromException(exception, out _);
|
||||
runnerPromise.SetException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetResult()
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
if (runnerPromise != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise != null)
|
||||
{
|
||||
promise.TrySetResult();
|
||||
runnerPromise.SetResult();
|
||||
}
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.OnCompleted(runnerPromise.MoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
@@ -156,9 +138,8 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskMethodBuilder<T>
|
||||
{
|
||||
// cache items.
|
||||
AutoResetUniTaskCompletionSource<T> promise;
|
||||
IMoveNextRunner runner;
|
||||
IStateMachineRunnerPromise<T> runnerPromise;
|
||||
Exception ex;
|
||||
T result;
|
||||
|
||||
// 1. Static Create method.
|
||||
@@ -170,106 +151,91 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
}
|
||||
|
||||
// 2. TaskLike Task property.
|
||||
[DebuggerHidden]
|
||||
public UniTask<T> Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (promise != null)
|
||||
if (runnerPromise != null)
|
||||
{
|
||||
return promise.Task;
|
||||
return runnerPromise.Task;
|
||||
}
|
||||
|
||||
if (runner == null)
|
||||
else if (ex != null)
|
||||
{
|
||||
return UniTask.FromException<T>(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return UniTask.FromResult(result);
|
||||
}
|
||||
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
return promise.Task;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.CreateFromException(exception, out _);
|
||||
ex = exception;
|
||||
}
|
||||
else
|
||||
{
|
||||
promise.TrySetException(exception);
|
||||
runnerPromise.SetException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetResult(T result)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
this.result = result;
|
||||
return;
|
||||
}
|
||||
|
||||
promise.TrySetResult(result);
|
||||
else
|
||||
{
|
||||
runnerPromise.SetResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.OnCompleted(runnerPromise.MoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskVoidMethodBuilder
|
||||
{
|
||||
IMoveNextRunner runner;
|
||||
IStateMachineRunner runner;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
@@ -33,12 +35,18 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// workaround for IL2CPP bug.
|
||||
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
|
||||
#else
|
||||
runner.Return();
|
||||
#endif
|
||||
runner = null;
|
||||
}
|
||||
|
||||
@@ -47,43 +55,51 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetResult()
|
||||
{
|
||||
// runner is finished, return.
|
||||
if (runner != null)
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// workaround for IL2CPP bug.
|
||||
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
|
||||
#else
|
||||
runner.Return();
|
||||
#endif
|
||||
runner = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.OnCompleted(runner.MoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
awaiter.UnsafeOnCompleted(runner.MoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
internal interface IMoveNextRunner
|
||||
{
|
||||
Action CallMoveNext { get; }
|
||||
void Return();
|
||||
}
|
||||
|
||||
internal sealed class MoveNextRunner<TStateMachine> : IMoveNextRunner, IPromisePoolItem
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static PromisePool<MoveNextRunner<TStateMachine>> pool = new PromisePool<MoveNextRunner<TStateMachine>>();
|
||||
|
||||
TStateMachine stateMachine;
|
||||
internal readonly Action callMoveNext;
|
||||
|
||||
public Action CallMoveNext => callMoveNext;
|
||||
|
||||
MoveNextRunner()
|
||||
{
|
||||
callMoveNext = MoveNext;
|
||||
}
|
||||
|
||||
public static MoveNextRunner<TStateMachine> Create(ref TStateMachine stateMachine)
|
||||
{
|
||||
var result = pool.TryRent() ?? new MoveNextRunner<TStateMachine>();
|
||||
result.stateMachine = stateMachine;
|
||||
return result;
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void MoveNext()
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public void Return()
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
}
|
||||
|
||||
void IPromisePoolItem.Reset()
|
||||
{
|
||||
stateMachine = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
// #ENABLE_IL2CPP in this file is to avoid bug of IL2CPP VM.
|
||||
// Issue is tracked on https://issuetracker.unity3d.com/issues/il2cpp-incorrect-results-when-calling-a-method-from-outside-class-in-a-struct
|
||||
// but currently it is labeled `Won't Fix`.
|
||||
|
||||
internal interface IStateMachineRunner
|
||||
{
|
||||
Action MoveNext { get; }
|
||||
void Return();
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
Action ReturnAction { get; }
|
||||
#endif
|
||||
}
|
||||
|
||||
internal interface IStateMachineRunnerPromise : IUniTaskSource
|
||||
{
|
||||
Action MoveNext { get; }
|
||||
UniTask Task { get; }
|
||||
void SetResult();
|
||||
void SetException(Exception exception);
|
||||
}
|
||||
|
||||
internal interface IStateMachineRunnerPromise<T> : IUniTaskSource<T>
|
||||
{
|
||||
Action MoveNext { get; }
|
||||
UniTask<T> Task { get; }
|
||||
void SetResult(T result);
|
||||
void SetException(Exception exception);
|
||||
}
|
||||
|
||||
internal static class StateMachineUtility
|
||||
{
|
||||
// Get AsyncStateMachine internal state to check IL2CPP bug
|
||||
public static int GetState(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
var info = stateMachine.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||
.First(x => x.Name.EndsWith("__state"));
|
||||
return (int)info.GetValue(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AsyncUniTaskVoid<TStateMachine> : IStateMachineRunner, ITaskPoolNode<AsyncUniTaskVoid<TStateMachine>>, IUniTaskSource
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static TaskPool<AsyncUniTaskVoid<TStateMachine>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
public Action ReturnAction { get; }
|
||||
#endif
|
||||
|
||||
TStateMachine stateMachine;
|
||||
|
||||
public Action MoveNext { get; }
|
||||
|
||||
public AsyncUniTaskVoid()
|
||||
{
|
||||
MoveNext = Run;
|
||||
#if ENABLE_IL2CPP
|
||||
ReturnAction = Return;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunner runnerFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncUniTaskVoid<TStateMachine>();
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
runnerFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
}
|
||||
|
||||
static AsyncUniTaskVoid()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncUniTaskVoid<TStateMachine>), () => pool.Size);
|
||||
}
|
||||
|
||||
AsyncUniTaskVoid<TStateMachine> nextNode;
|
||||
public ref AsyncUniTaskVoid<TStateMachine> NextNode => ref nextNode;
|
||||
|
||||
public void Return()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
stateMachine = default;
|
||||
pool.TryPush(this);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run()
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
// dummy interface implementation for TaskTracker.
|
||||
|
||||
UniTaskStatus IUniTaskSource.GetStatus(short token)
|
||||
{
|
||||
return UniTaskStatus.Pending;
|
||||
}
|
||||
|
||||
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
|
||||
{
|
||||
return UniTaskStatus.Pending;
|
||||
}
|
||||
|
||||
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AsyncUniTask<TStateMachine> : IStateMachineRunnerPromise, IUniTaskSource, ITaskPoolNode<AsyncUniTask<TStateMachine>>
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static TaskPool<AsyncUniTask<TStateMachine>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
readonly Action returnDelegate;
|
||||
#endif
|
||||
public Action MoveNext { get; }
|
||||
|
||||
TStateMachine stateMachine;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
AsyncUniTask()
|
||||
{
|
||||
MoveNext = Run;
|
||||
#if ENABLE_IL2CPP
|
||||
returnDelegate = Return;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncUniTask<TStateMachine>();
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
runnerPromiseFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
}
|
||||
|
||||
AsyncUniTask<TStateMachine> nextNode;
|
||||
public ref AsyncUniTask<TStateMachine> NextNode => ref nextNode;
|
||||
|
||||
static AsyncUniTask()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine>), () => pool.Size);
|
||||
}
|
||||
|
||||
void Return()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
stateMachine = default;
|
||||
pool.TryPush(this);
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
stateMachine = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run()
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public UniTask Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
get
|
||||
{
|
||||
return new UniTask(this, core.Version);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void SetResult()
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
core.TrySetException(exception);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// workaround for IL2CPP bug.
|
||||
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
|
||||
#else
|
||||
TryReturn();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AsyncUniTask<TStateMachine, T> : IStateMachineRunnerPromise<T>, IUniTaskSource<T>, ITaskPoolNode<AsyncUniTask<TStateMachine, T>>
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static TaskPool<AsyncUniTask<TStateMachine, T>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
readonly Action returnDelegate;
|
||||
#endif
|
||||
|
||||
public Action MoveNext { get; }
|
||||
|
||||
TStateMachine stateMachine;
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
AsyncUniTask()
|
||||
{
|
||||
MoveNext = Run;
|
||||
#if ENABLE_IL2CPP
|
||||
returnDelegate = Return;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise<T> runnerPromiseFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncUniTask<TStateMachine, T>();
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
runnerPromiseFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
}
|
||||
|
||||
AsyncUniTask<TStateMachine, T> nextNode;
|
||||
public ref AsyncUniTask<TStateMachine, T> NextNode => ref nextNode;
|
||||
|
||||
static AsyncUniTask()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine, T>), () => pool.Size);
|
||||
}
|
||||
|
||||
void Return()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
stateMachine = default;
|
||||
pool.TryPush(this);
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
stateMachine = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run()
|
||||
{
|
||||
// UnityEngine.Debug.Log($"MoveNext State:" + StateMachineUtility.GetState(stateMachine));
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public UniTask<T> Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
get
|
||||
{
|
||||
return new UniTask<T>(this, core.Version);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void SetResult(T result)
|
||||
{
|
||||
core.TrySetResult(result);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
core.TrySetException(exception);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public T GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// workaround for IL2CPP bug.
|
||||
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
|
||||
#else
|
||||
TryReturn();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,27 +12,55 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class EnumeratorAsyncExtensions
|
||||
{
|
||||
public static UniTask.Awaiter GetAwaiter(this IEnumerator enumerator)
|
||||
public static UniTask.Awaiter GetAwaiter<T>(this T enumerator)
|
||||
where T : IEnumerator
|
||||
{
|
||||
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
|
||||
var e = (IEnumerator)enumerator;
|
||||
Error.ThrowArgumentNullException(e, nameof(enumerator));
|
||||
return new UniTask(EnumeratorPromise.Create(e, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this IEnumerator enumerator)
|
||||
public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token);
|
||||
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
|
||||
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask ConfigureAwait(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
|
||||
return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
|
||||
public static UniTask ToUniTask(this IEnumerator enumerator, MonoBehaviour coroutineRunner)
|
||||
{
|
||||
static readonly PromisePool<EnumeratorPromise> pool = new PromisePool<EnumeratorPromise>();
|
||||
var source = AutoResetUniTaskCompletionSource.Create();
|
||||
coroutineRunner.StartCoroutine(Core(enumerator, coroutineRunner, source));
|
||||
return source.Task;
|
||||
}
|
||||
|
||||
static IEnumerator Core(IEnumerator inner, MonoBehaviour coroutineRunner, AutoResetUniTaskCompletionSource source)
|
||||
{
|
||||
yield return coroutineRunner.StartCoroutine(inner);
|
||||
source.TrySetResult();
|
||||
}
|
||||
|
||||
sealed class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<EnumeratorPromise>
|
||||
{
|
||||
static TaskPool<EnumeratorPromise> pool;
|
||||
EnumeratorPromise nextNode;
|
||||
public ref EnumeratorPromise NextNode => ref nextNode;
|
||||
|
||||
static EnumeratorPromise()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(EnumeratorPromise), () => pool.Size);
|
||||
}
|
||||
|
||||
IEnumerator innerEnumerator;
|
||||
CancellationToken cancellationToken;
|
||||
int initialFrame;
|
||||
bool loopRunning;
|
||||
bool calledGetResult;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -47,16 +75,26 @@ namespace Cysharp.Threading.Tasks
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
var result = pool.TryRent() ?? new EnumeratorPromise();
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new EnumeratorPromise();
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
result.loopRunning = true;
|
||||
result.calledGetResult = false;
|
||||
result.initialFrame = -1;
|
||||
|
||||
token = result.core.Version;
|
||||
|
||||
// run immediately.
|
||||
if (result.MoveNext())
|
||||
{
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -64,12 +102,15 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
try
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
calledGetResult = true;
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
if (!loopRunning)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,12 +131,38 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (calledGetResult)
|
||||
{
|
||||
loopRunning = false;
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (innerEnumerator == null) // invalid status, returned but loop running?
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
loopRunning = false;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (initialFrame == -1)
|
||||
{
|
||||
// Time can not touch in threadpool.
|
||||
if (PlayerLoopHelper.IsMainThread)
|
||||
{
|
||||
initialFrame = Time.frameCount;
|
||||
}
|
||||
}
|
||||
else if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true; // already executed in first frame, skip.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (innerEnumerator.MoveNext())
|
||||
@@ -105,27 +172,24 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
loopRunning = false;
|
||||
core.TrySetException(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
loopRunning = false;
|
||||
core.TrySetResult(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
innerEnumerator = default;
|
||||
cancellationToken = default;
|
||||
}
|
||||
|
||||
~EnumeratorPromise()
|
||||
{
|
||||
if (pool.TryReturn(this))
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
// Unwrap YieldInstructions
|
||||
@@ -139,11 +203,10 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
else if (current is CustomYieldInstruction)
|
||||
else if (current is CustomYieldInstruction cyi)
|
||||
{
|
||||
// WWW, WaitForSecondsRealtime
|
||||
var e2 = UnwrapWaitCustomYieldInstruction((CustomYieldInstruction)current);
|
||||
while (e2.MoveNext())
|
||||
while (cyi.keepWaiting)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
@@ -169,7 +232,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return null;
|
||||
goto WARN;
|
||||
}
|
||||
}
|
||||
else if (current is IEnumerator e3)
|
||||
@@ -182,17 +245,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
else
|
||||
{
|
||||
// WaitForEndOfFrame, WaitForFixedUpdate, others.
|
||||
yield return null;
|
||||
goto WARN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WWW and others as CustomYieldInstruction.
|
||||
static IEnumerator UnwrapWaitCustomYieldInstruction(CustomYieldInstruction yieldInstruction)
|
||||
{
|
||||
while (yieldInstruction.keepWaiting)
|
||||
{
|
||||
continue;
|
||||
|
||||
WARN:
|
||||
// WaitForEndOfFrame, WaitForFixedUpdate, others.
|
||||
UnityEngine.Debug.LogWarning($"yield {current.GetType().Name} is not supported on await IEnumerator or IEnumerator.ToUniTask(), please use ToUniTask(MonoBehaviour coroutineRunner) instead.");
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
@@ -202,12 +262,12 @@ namespace Cysharp.Threading.Tasks
|
||||
static IEnumerator UnwrapWaitForSeconds(WaitForSeconds waitForSeconds)
|
||||
{
|
||||
var second = (float)waitForSeconds_Seconds.GetValue(waitForSeconds);
|
||||
var startTime = DateTimeOffset.UtcNow;
|
||||
var elapsed = 0.0f;
|
||||
while (true)
|
||||
{
|
||||
yield return null;
|
||||
|
||||
var elapsed = (DateTimeOffset.UtcNow - startTime).TotalSeconds;
|
||||
elapsed += Time.deltaTime;
|
||||
if (elapsed >= second)
|
||||
{
|
||||
break;
|
||||
@@ -224,5 +284,4 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables.meta
vendored
Normal file
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5b9231662e24c942b544bd85d4b39cb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -11,23 +11,40 @@ using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class AddressableAsyncExtensions
|
||||
public static class AddressablesAsyncExtensions
|
||||
{
|
||||
#region AsyncOperationHandle
|
||||
|
||||
public static AsyncOperationHandleAwaiter GetAwaiter(this AsyncOperationHandle handle)
|
||||
public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle)
|
||||
{
|
||||
return new AsyncOperationHandleAwaiter(handle);
|
||||
return ToUniTask(handle).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle)
|
||||
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token);
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask ConfigureAwait(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken))
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellation, out var token), token);
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
|
||||
|
||||
if (!handle.IsValid())
|
||||
{
|
||||
// autoReleaseHandle:true handle is invalid(immediately internal handle == null) so return completed.
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
if (handle.IsDone)
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
return UniTask.FromException(handle.OperationException);
|
||||
}
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
|
||||
@@ -70,24 +87,33 @@ namespace Cysharp.Threading.Tasks
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
|
||||
handle.Completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
|
||||
sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource>
|
||||
{
|
||||
static readonly PromisePool<AsyncOperationHandleConfiguredSource> pool = new PromisePool<AsyncOperationHandleConfiguredSource>();
|
||||
static TaskPool<AsyncOperationHandleConfiguredSource> pool;
|
||||
AsyncOperationHandleConfiguredSource nextNode;
|
||||
public ref AsyncOperationHandleConfiguredSource NextNode => ref nextNode;
|
||||
|
||||
static AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle> continuationAction;
|
||||
AsyncOperationHandle handle;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
IProgress<float> progress;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
@@ -97,31 +123,55 @@ namespace Cysharp.Threading.Tasks
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
var result = pool.TryRent() ?? new AsyncOperationHandleConfiguredSource();
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncOperationHandleConfiguredSource();
|
||||
}
|
||||
|
||||
result.handle = handle;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle _)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
}
|
||||
core.GetResult(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
@@ -141,47 +191,35 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
if (progress != null && handle.IsValid())
|
||||
{
|
||||
progress.Report(handle.PercentComplete);
|
||||
}
|
||||
|
||||
if (handle.IsDone)
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
handle = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
}
|
||||
|
||||
~AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
if (pool.TryReturn(this))
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,80 +227,59 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
#region AsyncOperationHandle_T
|
||||
|
||||
public static AsyncOperationHandleAwaiter<T> GetAwaiter<T>(this AsyncOperationHandle<T> handle)
|
||||
public static UniTask<T>.Awaiter GetAwaiter<T>(this AsyncOperationHandle<T> handle)
|
||||
{
|
||||
return new AsyncOperationHandleAwaiter<T>(handle);
|
||||
return ToUniTask(handle).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle)
|
||||
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token);
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<T> ConfigureAwait<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken))
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellation, out var token), token);
|
||||
}
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
|
||||
|
||||
public struct AsyncOperationHandleAwaiter<T> : ICriticalNotifyCompletion
|
||||
{
|
||||
AsyncOperationHandle<T> handle;
|
||||
Action<AsyncOperationHandle> continuationAction;
|
||||
|
||||
public AsyncOperationHandleAwaiter(AsyncOperationHandle<T> handle)
|
||||
if (!handle.IsValid())
|
||||
{
|
||||
this.handle = handle;
|
||||
this.continuationAction = null;
|
||||
throw new Exception("Attempting to use an invalid operation handle");
|
||||
}
|
||||
|
||||
public bool IsCompleted => handle.IsDone;
|
||||
|
||||
public T GetResult()
|
||||
if (handle.IsDone)
|
||||
{
|
||||
if (continuationAction != null)
|
||||
{
|
||||
handle.CompletedTypeless -= continuationAction;
|
||||
continuationAction = null;
|
||||
}
|
||||
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
var e = handle.OperationException;
|
||||
handle = default;
|
||||
ExceptionDispatchInfo.Capture(e).Throw();
|
||||
return UniTask.FromException<T>(handle.OperationException);
|
||||
}
|
||||
|
||||
var result = handle.Result;
|
||||
handle = default;
|
||||
return result;
|
||||
return UniTask.FromResult(handle.Result);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
UnsafeOnCompleted(continuation);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
||||
handle.CompletedTypeless += continuationAction;
|
||||
}
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, IPromisePoolItem
|
||||
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
|
||||
{
|
||||
static readonly PromisePool<AsyncOperationHandleConfiguredSource<T>> pool = new PromisePool<AsyncOperationHandleConfiguredSource<T>>();
|
||||
static TaskPool<AsyncOperationHandleConfiguredSource<T>> pool;
|
||||
AsyncOperationHandleConfiguredSource<T> nextNode;
|
||||
public ref AsyncOperationHandleConfiguredSource<T> NextNode => ref nextNode;
|
||||
|
||||
static AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle<T>> continuationAction;
|
||||
AsyncOperationHandle<T> handle;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
IProgress<float> progress;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
@@ -272,32 +289,55 @@ namespace Cysharp.Threading.Tasks
|
||||
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
var result = pool.TryRent() ?? new AsyncOperationHandleConfiguredSource<T>();
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncOperationHandleConfiguredSource<T>();
|
||||
}
|
||||
|
||||
result.handle = handle;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
result.progress = progress;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle<T> argHandle)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (argHandle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(argHandle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(argHandle.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
}
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
@@ -322,47 +362,35 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
if (progress != null && handle.IsValid())
|
||||
{
|
||||
progress.Report(handle.PercentComplete);
|
||||
}
|
||||
|
||||
if (handle.IsDone)
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(handle.Result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
handle = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
}
|
||||
|
||||
~AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
if (pool.TryReturn(this))
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
||||
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef
vendored
Normal file
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/UniTask.Addressables.asmdef
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "UniTask.Addressables",
|
||||
"references": [
|
||||
"UniTask",
|
||||
"Unity.ResourceManager"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.addressables",
|
||||
"expression": "",
|
||||
"define": "UNITASK_ADDRESSABLE_SUPPORT"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 593a5b492d29ac6448b1ebf7f035ef33
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween.meta
vendored
Normal file
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25cb2f742bfeb1d48a4e65d3140b955d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
458
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs
vendored
Normal file
458
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
// asmdef Version Defines, enabled when com.demigiant.dotween is imported.
|
||||
|
||||
#if UNITASK_DOTWEEN_SUPPORT
|
||||
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using DG.Tweening;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public enum TweenCancelBehaviour
|
||||
{
|
||||
Kill,
|
||||
KillWithCompleteCallback,
|
||||
Complete,
|
||||
CompleteWithSeqeunceCallback,
|
||||
CancelAwait,
|
||||
|
||||
// AndCancelAwait
|
||||
KillAndCancelAwait,
|
||||
KillWithCompleteCallbackAndCancelAwait,
|
||||
CompleteAndCancelAwait,
|
||||
CompleteWithSeqeunceCallbackAndCancelAwait
|
||||
}
|
||||
|
||||
public static class DOTweenAsyncExtensions
|
||||
{
|
||||
enum CallbackType
|
||||
{
|
||||
Kill,
|
||||
Complete,
|
||||
Pause,
|
||||
Play,
|
||||
Rewind,
|
||||
StepComplete
|
||||
}
|
||||
|
||||
public static TweenAwaiter GetAwaiter(this Tween tween)
|
||||
{
|
||||
return new TweenAwaiter(tween);
|
||||
}
|
||||
|
||||
public static UniTask WithCancellation(this Tween tween, CancellationToken cancellationToken)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, TweenCancelBehaviour.Kill, cancellationToken, CallbackType.Kill, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Kill, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask AwaitForComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Complete, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask AwaitForPause(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Pause, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask AwaitForPlay(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Play, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask AwaitForRewind(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Rewind, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask AwaitForStepComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(tween, nameof(tween));
|
||||
|
||||
if (!tween.IsActive()) return UniTask.CompletedTask;
|
||||
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.StepComplete, out var token), token);
|
||||
}
|
||||
|
||||
public struct TweenAwaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
readonly Tween tween;
|
||||
|
||||
// killed(non active) as completed.
|
||||
public bool IsCompleted => !tween.IsActive();
|
||||
|
||||
public TweenAwaiter(Tween tween)
|
||||
{
|
||||
this.tween = tween;
|
||||
}
|
||||
|
||||
public TweenAwaiter GetAwaiter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public void GetResult()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCompleted(System.Action continuation)
|
||||
{
|
||||
UnsafeOnCompleted(continuation);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(System.Action continuation)
|
||||
{
|
||||
// onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true).
|
||||
tween.onKill = PooledTweenCallback.Create(continuation);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TweenConfiguredSource : IUniTaskSource, ITaskPoolNode<TweenConfiguredSource>
|
||||
{
|
||||
static TaskPool<TweenConfiguredSource> pool;
|
||||
TweenConfiguredSource nextNode;
|
||||
public ref TweenConfiguredSource NextNode => ref nextNode;
|
||||
|
||||
static TweenConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(TweenConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
static readonly TweenCallback EmptyTweenCallback = () => { };
|
||||
|
||||
readonly TweenCallback onCompleteCallbackDelegate;
|
||||
readonly TweenCallback onUpdateDelegate;
|
||||
|
||||
Tween tween;
|
||||
TweenCancelBehaviour cancelBehaviour;
|
||||
CancellationToken cancellationToken;
|
||||
CallbackType callbackType;
|
||||
bool canceled;
|
||||
|
||||
TweenCallback originalUpdateAction;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
TweenConfiguredSource()
|
||||
{
|
||||
onCompleteCallbackDelegate = OnCompleteCallbackDelegate;
|
||||
onUpdateDelegate = OnUpdate;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
DoCancelBeforeCreate(tween, cancelBehaviour);
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new TweenConfiguredSource();
|
||||
}
|
||||
|
||||
result.tween = tween;
|
||||
result.cancelBehaviour = cancelBehaviour;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.callbackType = callbackType;
|
||||
|
||||
result.originalUpdateAction = tween.onUpdate;
|
||||
result.canceled = false;
|
||||
|
||||
if (result.originalUpdateAction == result.onUpdateDelegate)
|
||||
{
|
||||
result.originalUpdateAction = null;
|
||||
}
|
||||
|
||||
tween.onUpdate = result.onUpdateDelegate;
|
||||
|
||||
switch (callbackType)
|
||||
{
|
||||
case CallbackType.Kill:
|
||||
tween.onKill = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
case CallbackType.Complete:
|
||||
tween.onComplete = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
case CallbackType.Pause:
|
||||
tween.onPause = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
case CallbackType.Play:
|
||||
tween.onPlay = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
case CallbackType.Rewind:
|
||||
tween.onRewind = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
case CallbackType.StepComplete:
|
||||
tween.onStepComplete = result.onCompleteCallbackDelegate;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void OnCompleteCallbackDelegate()
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (this.cancelBehaviour == TweenCancelBehaviour.KillAndCancelAwait
|
||||
|| this.cancelBehaviour == TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait
|
||||
|| this.cancelBehaviour == TweenCancelBehaviour.CompleteAndCancelAwait
|
||||
|| this.cancelBehaviour == TweenCancelBehaviour.CompleteWithSeqeunceCallbackAndCancelAwait
|
||||
|| this.cancelBehaviour == TweenCancelBehaviour.CancelAwait)
|
||||
{
|
||||
canceled = true;
|
||||
}
|
||||
}
|
||||
if (canceled)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdate()
|
||||
{
|
||||
originalUpdateAction?.Invoke();
|
||||
|
||||
if (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this.cancelBehaviour)
|
||||
{
|
||||
case TweenCancelBehaviour.Kill:
|
||||
default:
|
||||
this.tween.Kill(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillAndCancelAwait:
|
||||
this.canceled = true;
|
||||
this.tween.Kill(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillWithCompleteCallback:
|
||||
this.tween.Kill(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
|
||||
this.canceled = true;
|
||||
this.tween.Kill(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.Complete:
|
||||
this.tween.Complete(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteAndCancelAwait:
|
||||
this.canceled = true;
|
||||
this.tween.Complete(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteWithSeqeunceCallback:
|
||||
this.tween.Complete(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteWithSeqeunceCallbackAndCancelAwait:
|
||||
this.canceled = true;
|
||||
this.tween.Complete(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.CancelAwait:
|
||||
// replace to empty(avoid callback after Canceled(instance is returned to pool.)
|
||||
switch (callbackType)
|
||||
{
|
||||
case CallbackType.Kill:
|
||||
tween.onKill = EmptyTweenCallback;
|
||||
break;
|
||||
case CallbackType.Complete:
|
||||
tween.onComplete = EmptyTweenCallback;
|
||||
break;
|
||||
case CallbackType.Pause:
|
||||
tween.onPause = EmptyTweenCallback;
|
||||
break;
|
||||
case CallbackType.Play:
|
||||
tween.onPlay = EmptyTweenCallback;
|
||||
break;
|
||||
case CallbackType.Rewind:
|
||||
tween.onRewind = EmptyTweenCallback;
|
||||
break;
|
||||
case CallbackType.StepComplete:
|
||||
tween.onStepComplete = EmptyTweenCallback;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.core.TrySetCanceled(this.cancellationToken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour)
|
||||
{
|
||||
|
||||
switch (tweenCancelBehaviour)
|
||||
{
|
||||
case TweenCancelBehaviour.Kill:
|
||||
default:
|
||||
tween.Kill(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillAndCancelAwait:
|
||||
tween.Kill(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillWithCompleteCallback:
|
||||
tween.Kill(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
|
||||
tween.Kill(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.Complete:
|
||||
tween.Complete(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteAndCancelAwait:
|
||||
tween.Complete(false);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteWithSeqeunceCallback:
|
||||
tween.Complete(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.CompleteWithSeqeunceCallbackAndCancelAwait:
|
||||
tween.Complete(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.CancelAwait:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
tween.onUpdate = originalUpdateAction;
|
||||
|
||||
switch (callbackType)
|
||||
{
|
||||
case CallbackType.Kill:
|
||||
tween.onKill = null;
|
||||
break;
|
||||
case CallbackType.Complete:
|
||||
tween.onComplete = null;
|
||||
break;
|
||||
case CallbackType.Pause:
|
||||
tween.onPause = null;
|
||||
break;
|
||||
case CallbackType.Play:
|
||||
tween.onPlay = null;
|
||||
break;
|
||||
case CallbackType.Rewind:
|
||||
tween.onRewind = null;
|
||||
break;
|
||||
case CallbackType.StepComplete:
|
||||
tween.onStepComplete = null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tween = default;
|
||||
cancellationToken = default;
|
||||
originalUpdateAction = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PooledTweenCallback
|
||||
{
|
||||
static readonly ConcurrentQueue<PooledTweenCallback> pool = new ConcurrentQueue<PooledTweenCallback>();
|
||||
|
||||
readonly TweenCallback runDelegate;
|
||||
|
||||
Action continuation;
|
||||
|
||||
|
||||
PooledTweenCallback()
|
||||
{
|
||||
runDelegate = Run;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TweenCallback Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryDequeue(out var item))
|
||||
{
|
||||
item = new PooledTweenCallback();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item.runDelegate;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run()
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
if (call != null)
|
||||
{
|
||||
pool.Enqueue(this);
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta
vendored
Normal file
11
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/DOTweenAsyncExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f448d5bc5b232e4f98d89d5d1832e8e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef
vendored
Normal file
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "UniTask.DOTween",
|
||||
"references": [
|
||||
"UniTask",
|
||||
"DOTween.Modules"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.demigiant.dotween",
|
||||
"expression": "",
|
||||
"define": "UNITASK_DOTWEEN_SUPPORT"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta
vendored
Normal file
7
src/UniTask/Assets/Plugins/UniTask/Runtime/External/DOTween/UniTask.DOTween.asmdef.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 029c1c1b674aaae47a6841a0b89ad80e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro.meta
vendored
Normal file
8
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f89da606bde9a4e4e94ae1189a029887
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,224 @@
|
||||
#if UNITASK_TEXTMESHPRO_SUPPORT
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using TMPro;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class TextMeshProAsyncExtensions
|
||||
{
|
||||
public static IAsyncValueChangedEventHandler<string> GetAsyncValueChangedEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncValueChangedEventHandler<string> GetAsyncValueChangedEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<string> OnValueChangedAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<string> OnValueChangedAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onValueChanged, cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncEndEditEventHandler<string> GetAsyncEndEditEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncEndEditEventHandler<string> GetAsyncEndEditEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<string> OnEndEditAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<string> OnEndEditAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnEndEditAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnEndEditAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onEndEdit, cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncDeselectEventHandler<string> GetAsyncDeselectEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncDeselectEventHandler<string> GetAsyncDeselectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onDeselect, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<string> OnDeselectAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<string> OnDeselectAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onDeselect, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnDeselectAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnDeselectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onDeselect, cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncSelectEventHandler<string> GetAsyncSelectEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncSelectEventHandler<string> GetAsyncSelectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSelect, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<string> OnSelectAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<string> OnSelectAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSelect, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnSelectAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnSelectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSelect, cancellationToken);
|
||||
}
|
||||
|
||||
public static IAsyncSubmitEventHandler<string> GetAsyncSubmitEventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsyncSubmitEventHandler<string> GetAsyncSubmitEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSubmit, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<string> OnSubmitAsync(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<string> OnSubmitAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<string>(inputField.onSubmit, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnSubmitAsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<string> OnSubmitAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSubmit, cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79f4f2475e0b2c44e97ed1dee760627b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var handlers = new (string name, string type)[] {
|
||||
("ValueChanged", "string"),
|
||||
("EndEdit", "string"),
|
||||
("EndTextSelection", "(string, int, int)"),
|
||||
("TextSelection", "(string, int, int)"),
|
||||
("Deselect", "string"),
|
||||
("Select", "string"),
|
||||
("Submit", "string"),
|
||||
};
|
||||
|
||||
Func<string, bool> shouldConvert = x => x.EndsWith("TextSelection");
|
||||
Func<string, string> eventName = x => shouldConvert(x) ? $"new TextSelectionEventConverter(inputField.on{x})" : $"inputField.on{x}";
|
||||
#>
|
||||
#if UNITASK_TEXTMESHPRO_SUPPORT
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using TMPro;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class TextMeshProAsyncExtensions
|
||||
{
|
||||
<# foreach(var (name, type) in handlers) { #>
|
||||
public static IAsync<#= (name) #>EventHandler<<#= type #>> GetAsync<#= (name) #>EventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsync<#= (name) #>EventHandler<<#= type #>> GetAsync<#= (name) #>EventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<<#= type #>> On<#= (name) #>Async(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<<#= type #>> On<#= (name) #>Async(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<<#= type #>> On<#= (name) #>AsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<<#= type #>> On<#= (name) #>AsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<<#= type #>>(<#= eventName(name) #>, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9bb9fc551a975d44a7180e022a2debe
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs
vendored
Normal file
130
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro/TextMeshProAsyncExtensions.cs
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
#if UNITASK_TEXTMESHPRO_SUPPORT
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using TMPro;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class TextMeshProAsyncExtensions
|
||||
{
|
||||
// <string> -> Text
|
||||
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, TMP_Text text, bool rebindOnError = true)
|
||||
{
|
||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||
}
|
||||
|
||||
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
||||
{
|
||||
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
||||
}
|
||||
|
||||
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<string> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError)
|
||||
{
|
||||
var repeat = false;
|
||||
BIND_AGAIN:
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
bool moveNext;
|
||||
try
|
||||
{
|
||||
moveNext = await e.MoveNextAsync();
|
||||
repeat = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
if (rebindOnError && !repeat)
|
||||
{
|
||||
repeat = true;
|
||||
goto BIND_AGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (!moveNext) return;
|
||||
|
||||
text.text = e.Current;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <T> -> Text
|
||||
|
||||
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, TMP_Text text, bool rebindOnError = true)
|
||||
{
|
||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||
}
|
||||
|
||||
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
||||
{
|
||||
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
||||
}
|
||||
|
||||
public static void BindTo<T>(this AsyncReactiveProperty<T> source, TMP_Text text, bool rebindOnError = true)
|
||||
{
|
||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||
}
|
||||
|
||||
static async UniTaskVoid BindToCore<T>(IUniTaskAsyncEnumerable<T> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError)
|
||||
{
|
||||
var repeat = false;
|
||||
BIND_AGAIN:
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
bool moveNext;
|
||||
try
|
||||
{
|
||||
moveNext = await e.MoveNextAsync();
|
||||
repeat = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is OperationCanceledException) return;
|
||||
|
||||
if (rebindOnError && !repeat)
|
||||
{
|
||||
repeat = true;
|
||||
goto BIND_AGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (!moveNext) return;
|
||||
|
||||
text.text = e.Current.ToString();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6ba480edafb67d4e91bb10feb64fae5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef
vendored
Normal file
22
src/UniTask/Assets/Plugins/UniTask/Runtime/External/TextMeshPro/UniTask.TextMeshPro.asmdef
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "UniTask.TextMeshPro",
|
||||
"references": [
|
||||
"UniTask",
|
||||
"Unity.TextMeshPro"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.textmeshpro",
|
||||
"expression": "",
|
||||
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc47925d1a5fa2946bdd37746b2b5d48
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -28,6 +28,12 @@ namespace Cysharp.Threading.Tasks
|
||||
IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending);
|
||||
}
|
||||
|
||||
public interface IConnectableUniTaskAsyncEnumerable<out T> : IUniTaskAsyncEnumerable<T>
|
||||
{
|
||||
IDisposable Connect();
|
||||
}
|
||||
|
||||
// don't use AsyncGrouping.
|
||||
//public interface IUniTaskAsyncGrouping<out TKey, out TElement> : IUniTaskAsyncEnumerable<TElement>
|
||||
//{
|
||||
// TKey Key { get; }
|
||||
|
||||
@@ -19,17 +19,75 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
// similar as IValueTaskSource
|
||||
public interface IUniTaskSource
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
: System.Threading.Tasks.Sources.IValueTaskSource
|
||||
#pragma warning disable CS0108
|
||||
#endif
|
||||
{
|
||||
UniTaskStatus GetStatus(short token);
|
||||
void OnCompleted(Action<object> continuation, object state, short token);
|
||||
void GetResult(short token);
|
||||
|
||||
UniTaskStatus UnsafeGetStatus(); // only for debug use.
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
#pragma warning restore CS0108
|
||||
|
||||
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token)
|
||||
{
|
||||
return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token);
|
||||
}
|
||||
|
||||
void System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short token)
|
||||
{
|
||||
((IUniTaskSource)this).GetResult(token);
|
||||
}
|
||||
|
||||
void System.Threading.Tasks.Sources.IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
// ignore flags, always none.
|
||||
((IUniTaskSource)this).OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
public interface IUniTaskSource<out T> : IUniTaskSource
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
, System.Threading.Tasks.Sources.IValueTaskSource<T>
|
||||
#endif
|
||||
{
|
||||
new T GetResult(short token);
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
|
||||
new public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return ((IUniTaskSource)this).GetStatus(token);
|
||||
}
|
||||
|
||||
new public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
((IUniTaskSource)this).OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource<T>.GetStatus(short token)
|
||||
{
|
||||
return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token);
|
||||
}
|
||||
|
||||
T System.Threading.Tasks.Sources.IValueTaskSource<T>.GetResult(short token)
|
||||
{
|
||||
return ((IUniTaskSource<T>)this).GetResult(token);
|
||||
}
|
||||
|
||||
void System.Threading.Tasks.Sources.IValueTaskSource<T>.OnCompleted(Action<object> continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
// ignore flags, always none.
|
||||
((IUniTaskSource)this).OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
public static class UniTaskStatusExtensions
|
||||
|
||||
@@ -10,7 +10,9 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
const int MaxArrayLength = 0X7FEFFFFF;
|
||||
const int InitialSize = 16;
|
||||
|
||||
SpinLock gate = new SpinLock();
|
||||
readonly PlayerLoopTiming timing;
|
||||
|
||||
SpinLock gate = new SpinLock(false);
|
||||
bool dequing = false;
|
||||
|
||||
int actionListCount = 0;
|
||||
@@ -19,6 +21,11 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
int waitingListCount = 0;
|
||||
Action[] waitingList = new Action[InitialSize];
|
||||
|
||||
public ContinuationQueue(PlayerLoopTiming timing)
|
||||
{
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
public void Enqueue(Action continuation)
|
||||
{
|
||||
bool lockTaken = false;
|
||||
@@ -63,16 +70,105 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
public int Clear()
|
||||
{
|
||||
var rest = actionListCount + waitingListCount;
|
||||
|
||||
actionListCount = 0;
|
||||
actionList = new Action[InitialSize];
|
||||
|
||||
waitingListCount = 0;
|
||||
waitingList = new Action[InitialSize];
|
||||
|
||||
return rest;
|
||||
}
|
||||
|
||||
// delegate entrypoint.
|
||||
public void Run()
|
||||
{
|
||||
// for debugging, create named stacktrace.
|
||||
#if DEBUG
|
||||
switch (timing)
|
||||
{
|
||||
case PlayerLoopTiming.Initialization:
|
||||
Initialization();
|
||||
break;
|
||||
case PlayerLoopTiming.LastInitialization:
|
||||
LastInitialization();
|
||||
break;
|
||||
case PlayerLoopTiming.EarlyUpdate:
|
||||
EarlyUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastEarlyUpdate:
|
||||
LastEarlyUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.FixedUpdate:
|
||||
FixedUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastFixedUpdate:
|
||||
LastFixedUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PreUpdate:
|
||||
PreUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPreUpdate:
|
||||
LastPreUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.Update:
|
||||
Update();
|
||||
break;
|
||||
case PlayerLoopTiming.LastUpdate:
|
||||
LastUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PreLateUpdate:
|
||||
PreLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPreLateUpdate:
|
||||
LastPreLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PostLateUpdate:
|
||||
PostLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPostLateUpdate:
|
||||
LastPostLateUpdate();
|
||||
break;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
case PlayerLoopTiming.TimeUpdate:
|
||||
TimeUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastTimeUpdate:
|
||||
LastTimeUpdate();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
RunCore();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Initialization() => RunCore();
|
||||
void LastInitialization() => RunCore();
|
||||
void EarlyUpdate() => RunCore();
|
||||
void LastEarlyUpdate() => RunCore();
|
||||
void FixedUpdate() => RunCore();
|
||||
void LastFixedUpdate() => RunCore();
|
||||
void PreUpdate() => RunCore();
|
||||
void LastPreUpdate() => RunCore();
|
||||
void Update() => RunCore();
|
||||
void LastUpdate() => RunCore();
|
||||
void PreLateUpdate() => RunCore();
|
||||
void LastPreLateUpdate() => RunCore();
|
||||
void PostLateUpdate() => RunCore();
|
||||
void LastPostLateUpdate() => RunCore();
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
void TimeUpdate() => RunCore();
|
||||
void LastTimeUpdate() => RunCore();
|
||||
#endif
|
||||
|
||||
[System.Diagnostics.DebuggerHidden]
|
||||
void RunCore()
|
||||
{
|
||||
{
|
||||
bool lockTaken = false;
|
||||
@@ -90,10 +186,17 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
|
||||
for (int i = 0; i < actionListCount; i++)
|
||||
{
|
||||
|
||||
var action = actionList[i];
|
||||
actionList[i] = null;
|
||||
|
||||
action();
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UnityEngine.Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
}
|
||||
else
|
||||
{
|
||||
var fname = fi.FullName.Replace(Path.DirectorySeparatorChar, '/').Replace(Application.dataPath, "");
|
||||
var fname = fi.FullName.Replace(Path.DirectorySeparatorChar, '/').Replace(PlayerLoopHelper.ApplicationDataPath, "");
|
||||
var withAssetsPath = "Assets/" + fname;
|
||||
return "<a href=\"" + withAssetsPath + "\" line=\"" + line + "\">" + withAssetsPath + ":" + line + "</a>";
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER
|
||||
|
||||
using System;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
internal static class FuncExtensions
|
||||
{
|
||||
// avoid lambda capture
|
||||
|
||||
internal static Action<T> AsFuncOfT<T>(this Action action)
|
||||
{
|
||||
return new Action<T>(action.Invoke);
|
||||
}
|
||||
|
||||
static void Invoke<T>(this Action action, T unused)
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
const int InitialSize = 16;
|
||||
|
||||
readonly PlayerLoopTiming timing;
|
||||
readonly object runningAndQueueLock = new object();
|
||||
readonly object arrayLock = new object();
|
||||
readonly Action<Exception> unhandledExceptionCallback;
|
||||
@@ -17,9 +18,12 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
IPlayerLoopItem[] loopItems = new IPlayerLoopItem[InitialSize];
|
||||
MinimumQueue<IPlayerLoopItem> waitQueue = new MinimumQueue<IPlayerLoopItem>(InitialSize);
|
||||
|
||||
public PlayerLoopRunner()
|
||||
|
||||
|
||||
public PlayerLoopRunner(PlayerLoopTiming timing)
|
||||
{
|
||||
this.unhandledExceptionCallback = ex => Debug.LogException(ex);
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
public void AddAction(IPlayerLoopItem item)
|
||||
@@ -44,18 +48,113 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
public int Clear()
|
||||
{
|
||||
lock (arrayLock)
|
||||
{
|
||||
var rest = 0;
|
||||
|
||||
for (var index = 0; index < loopItems.Length; index++)
|
||||
{
|
||||
if (loopItems[index] != null)
|
||||
{
|
||||
rest++;
|
||||
}
|
||||
|
||||
loopItems[index] = null;
|
||||
}
|
||||
|
||||
tail = 0;
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
|
||||
// delegate entrypoint.
|
||||
public void Run()
|
||||
{
|
||||
// for debugging, create named stacktrace.
|
||||
#if DEBUG
|
||||
switch (timing)
|
||||
{
|
||||
case PlayerLoopTiming.Initialization:
|
||||
Initialization();
|
||||
break;
|
||||
case PlayerLoopTiming.LastInitialization:
|
||||
LastInitialization();
|
||||
break;
|
||||
case PlayerLoopTiming.EarlyUpdate:
|
||||
EarlyUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastEarlyUpdate:
|
||||
LastEarlyUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.FixedUpdate:
|
||||
FixedUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastFixedUpdate:
|
||||
LastFixedUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PreUpdate:
|
||||
PreUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPreUpdate:
|
||||
LastPreUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.Update:
|
||||
Update();
|
||||
break;
|
||||
case PlayerLoopTiming.LastUpdate:
|
||||
LastUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PreLateUpdate:
|
||||
PreLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPreLateUpdate:
|
||||
LastPreLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.PostLateUpdate:
|
||||
PostLateUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastPostLateUpdate:
|
||||
LastPostLateUpdate();
|
||||
break;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
case PlayerLoopTiming.TimeUpdate:
|
||||
TimeUpdate();
|
||||
break;
|
||||
case PlayerLoopTiming.LastTimeUpdate:
|
||||
LastTimeUpdate();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
RunCore();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Initialization() => RunCore();
|
||||
void LastInitialization() => RunCore();
|
||||
void EarlyUpdate() => RunCore();
|
||||
void LastEarlyUpdate() => RunCore();
|
||||
void FixedUpdate() => RunCore();
|
||||
void LastFixedUpdate() => RunCore();
|
||||
void PreUpdate() => RunCore();
|
||||
void LastPreUpdate() => RunCore();
|
||||
void Update() => RunCore();
|
||||
void LastUpdate() => RunCore();
|
||||
void PreLateUpdate() => RunCore();
|
||||
void LastPreLateUpdate() => RunCore();
|
||||
void PostLateUpdate() => RunCore();
|
||||
void LastPostLateUpdate() => RunCore();
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
void TimeUpdate() => RunCore();
|
||||
void LastTimeUpdate() => RunCore();
|
||||
#endif
|
||||
|
||||
[System.Diagnostics.DebuggerHidden]
|
||||
void RunCore()
|
||||
{
|
||||
lock (runningAndQueueLock)
|
||||
{
|
||||
@@ -66,7 +165,6 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
var j = tail - 1;
|
||||
|
||||
// eliminate array-bound check for i
|
||||
for (int i = 0; i < loopItems.Length; i++)
|
||||
{
|
||||
var action = loopItems[i];
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
internal sealed class PooledDelegate<T> : ITaskPoolNode<PooledDelegate<T>>
|
||||
{
|
||||
static TaskPool<PooledDelegate<T>> pool;
|
||||
|
||||
PooledDelegate<T> nextNode;
|
||||
public ref PooledDelegate<T> NextNode => ref nextNode;
|
||||
|
||||
static PooledDelegate()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(PooledDelegate<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<T> runDelegate;
|
||||
Action continuation;
|
||||
|
||||
PooledDelegate()
|
||||
{
|
||||
runDelegate = Run;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Action<T> Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryPop(out var item))
|
||||
{
|
||||
item = new PooledDelegate<T>();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item.runDelegate;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run(T _)
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
if (call != null)
|
||||
{
|
||||
pool.TryPush(this);
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8932579438742fa40b010edd412dbfba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,55 +0,0 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
// public, allow to user create custom operator with pool.
|
||||
|
||||
public interface IPromisePoolItem
|
||||
{
|
||||
void Reset();
|
||||
}
|
||||
|
||||
public class PromisePool<T>
|
||||
where T : class, IPromisePoolItem
|
||||
{
|
||||
int count = 0;
|
||||
readonly ConcurrentQueue<T> queue = new ConcurrentQueue<T>();
|
||||
readonly int maxSize;
|
||||
|
||||
public PromisePool(int maxSize = 256)
|
||||
{
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public T TryRent()
|
||||
{
|
||||
if (queue.TryDequeue(out var value))
|
||||
{
|
||||
Interlocked.Decrement(ref count);
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryReturn(T value)
|
||||
{
|
||||
value.Reset(); // reset when return.
|
||||
|
||||
if (count < maxSize)
|
||||
{
|
||||
queue.Enqueue(value);
|
||||
Interlocked.Increment(ref count);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
@@ -59,9 +60,9 @@ namespace Cysharp.Threading.Tasks
|
||||
#endif
|
||||
|
||||
|
||||
static List<KeyValuePair<IUniTaskSource, (int trackingId, DateTime addTime, string stackTrace)>> listPool = new List<KeyValuePair<IUniTaskSource, (int trackingId, DateTime addTime, string stackTrace)>>();
|
||||
static List<KeyValuePair<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>> listPool = new List<KeyValuePair<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>>();
|
||||
|
||||
static readonly WeakDictionary<IUniTaskSource, (int trackingId, DateTime addTime, string stackTrace)> tracking = new WeakDictionary<IUniTaskSource, (int trackingId, DateTime addTime, string stackTrace)>();
|
||||
static readonly WeakDictionary<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)> tracking = new WeakDictionary<IUniTaskSource, (string formattedType, int trackingId, DateTime addTime, string stackTrace)>();
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
public static void TrackActiveTask(IUniTaskSource task, int skipFrame)
|
||||
@@ -70,7 +71,19 @@ namespace Cysharp.Threading.Tasks
|
||||
dirty = true;
|
||||
if (!EditorEnableState.EnableTracking) return;
|
||||
var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : "";
|
||||
tracking.TryAdd(task, (Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
|
||||
|
||||
string typeName;
|
||||
if (EditorEnableState.EnableStackTrace)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
TypeBeautify(task.GetType(), sb);
|
||||
typeName = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = task.GetType().Name;
|
||||
}
|
||||
tracking.TryAdd(task, (typeName, Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,19 +116,8 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string typeName = null;
|
||||
var keyType = listPool[i].Key.GetType();
|
||||
if (keyType.IsNested)
|
||||
{
|
||||
typeName = keyType.DeclaringType.Name + "." + keyType.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = keyType.Name;
|
||||
}
|
||||
|
||||
action(listPool[i].Value.trackingId, typeName, listPool[i].Key.UnsafeGetStatus(), listPool[i].Value.addTime, listPool[i].Value.stackTrace);
|
||||
listPool[i] = new KeyValuePair<IUniTaskSource, (int trackingId, DateTime addTime, string stackTrace)>(null, (0, default(DateTime), null)); // clear
|
||||
action(listPool[i].Value.trackingId, listPool[i].Value.formattedType, listPool[i].Key.UnsafeGetStatus(), listPool[i].Value.addTime, listPool[i].Value.stackTrace);
|
||||
listPool[i] = default;
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -125,6 +127,52 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TypeBeautify(Type type, StringBuilder sb)
|
||||
{
|
||||
if (type.IsNested)
|
||||
{
|
||||
// TypeBeautify(type.DeclaringType, sb);
|
||||
sb.Append(type.DeclaringType.Name.ToString());
|
||||
sb.Append(".");
|
||||
}
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
var genericsStart = type.Name.IndexOf("`");
|
||||
if (genericsStart != -1)
|
||||
{
|
||||
sb.Append(type.Name.Substring(0, genericsStart));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(type.Name);
|
||||
}
|
||||
sb.Append("<");
|
||||
var first = true;
|
||||
foreach (var item in type.GetGenericArguments())
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
first = false;
|
||||
TypeBeautify(item, sb);
|
||||
}
|
||||
sb.Append(">");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(type.Name);
|
||||
}
|
||||
}
|
||||
|
||||
//static string RemoveUniTaskNamespace(string str)
|
||||
//{
|
||||
// return str.Replace("Cysharp.Threading.Tasks.CompilerServices", "")
|
||||
// .Replace("Cysharp.Threading.Tasks.Linq", "")
|
||||
// .Replace("Cysharp.Threading.Tasks", "");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
||||
|
||||
internal static class UnityWebRequestResultExtensions
|
||||
{
|
||||
public static bool IsError(this UnityWebRequest unityWebRequest)
|
||||
{
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
var result = unityWebRequest.result;
|
||||
return (result == UnityWebRequest.Result.ConnectionError)
|
||||
|| (result == UnityWebRequest.Result.DataProcessingError)
|
||||
|| (result == UnityWebRequest.Result.ProtocolError);
|
||||
#else
|
||||
return unityWebRequest.isHttpError || unityWebRequest.isNetworkError;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 111ba0e639de1d7428af6c823ead4918
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
internal readonly struct ValueStopwatch
|
||||
{
|
||||
static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
|
||||
|
||||
readonly long startTimestamp;
|
||||
|
||||
public static ValueStopwatch StartNew() => new ValueStopwatch(Stopwatch.GetTimestamp());
|
||||
|
||||
ValueStopwatch(long startTimestamp)
|
||||
{
|
||||
this.startTimestamp = startTimestamp;
|
||||
}
|
||||
|
||||
public TimeSpan Elapsed => TimeSpan.FromTicks(this.ElapsedTicks);
|
||||
|
||||
public bool IsInvalid => startTimestamp == 0;
|
||||
|
||||
public long ElapsedTicks
|
||||
{
|
||||
get
|
||||
{
|
||||
if (startTimestamp == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Detected invalid initialization(use 'default'), only to create from StartNew().");
|
||||
}
|
||||
|
||||
var delta = Stopwatch.GetTimestamp() - startTimestamp;
|
||||
return (long)(delta * TimestampToTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f16fb466974ad034c8732c79c7fd67ea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -12,7 +12,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAsync(source, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TAccumulate> AggregateAsync<TSource, TAccumulate>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, CancellationToken cancellationToken = default)
|
||||
@@ -20,7 +20,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAsync(source, seed, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TResult> AggregateAsync<TSource, TAccumulate, TResult>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector, CancellationToken cancellationToken = default)
|
||||
@@ -29,7 +29,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(resultSelector));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
return Aggregate.AggregateAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TSource> AggregateAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, UniTask<TSource>> accumulator, CancellationToken cancellationToken = default)
|
||||
@@ -37,7 +37,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAwaitAsync(source, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TAccumulate> AggregateAwaitAsync<TSource, TAccumulate>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken = default)
|
||||
@@ -45,7 +45,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAwaitAsync(source, seed, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TResult> AggregateAwaitAsync<TSource, TAccumulate, TResult>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, Func<TAccumulate, UniTask<TResult>> resultSelector, CancellationToken cancellationToken = default)
|
||||
@@ -54,7 +54,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(resultSelector));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
return Aggregate.AggregateAwaitAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TSource> AggregateAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, CancellationToken, UniTask<TSource>> accumulator, CancellationToken cancellationToken = default)
|
||||
@@ -62,7 +62,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAwaitWithCancellationAsync(source, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TAccumulate> AggregateAwaitWithCancellationAsync<TSource, TAccumulate>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken = default)
|
||||
@@ -70,7 +70,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, cancellationToken);
|
||||
return Aggregate.AggregateAwaitWithCancellationAsync(source, seed, accumulator, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<TResult> AggregateAwaitWithCancellationAsync<TSource, TAccumulate, TResult>(this IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, Func<TAccumulate, CancellationToken, UniTask<TResult>> resultSelector, CancellationToken cancellationToken = default)
|
||||
@@ -79,13 +79,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(accumulator));
|
||||
Error.ThrowArgumentNullException(accumulator, nameof(resultSelector));
|
||||
|
||||
return Aggregate.InvokeAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
return Aggregate.AggregateAwaitWithCancellationAsync(source, seed, accumulator, resultSelector, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Aggregate
|
||||
{
|
||||
internal static async UniTask<TSource> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TSource> AggregateAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -116,7 +116,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TAccumulate> InvokeAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TAccumulate> AggregateAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -138,7 +138,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TResult> InvokeAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TResult> AggregateAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -162,7 +162,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
// with async
|
||||
|
||||
internal static async UniTask<TSource> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, UniTask<TSource>> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TSource> AggregateAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, UniTask<TSource>> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -193,7 +193,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TAccumulate> InvokeAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TAccumulate> AggregateAwaitAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -215,7 +215,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TResult> InvokeAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, Func<TAccumulate, UniTask<TResult>> resultSelector, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TResult> AggregateAwaitAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, UniTask<TAccumulate>> accumulator, Func<TAccumulate, UniTask<TResult>> resultSelector, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -240,7 +240,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
// with cancellation
|
||||
|
||||
internal static async UniTask<TSource> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, CancellationToken, UniTask<TSource>> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TSource> AggregateAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TSource, CancellationToken, UniTask<TSource>> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -271,7 +271,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TAccumulate> InvokeAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TAccumulate> AggregateAwaitWithCancellationAsync<TSource, TAccumulate>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -293,7 +293,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<TResult> InvokeAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, Func<TAccumulate, CancellationToken, UniTask<TResult>> resultSelector, CancellationToken cancellationToken)
|
||||
internal static async UniTask<TResult> AggregateAwaitWithCancellationAsync<TSource, TAccumulate, TResult>(IUniTaskAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, CancellationToken, UniTask<TAccumulate>> accumulator, Func<TAccumulate, CancellationToken, UniTask<TResult>> resultSelector, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return All.InvokeAsync(source, predicate, cancellationToken);
|
||||
return All.AllAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<Boolean> AllAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
|
||||
@@ -19,7 +19,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return All.InvokeAsync(source, predicate, cancellationToken);
|
||||
return All.AllAwaitAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<Boolean> AllAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
|
||||
@@ -27,13 +27,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return All.InvokeAsync(source, predicate, cancellationToken);
|
||||
return All.AllAwaitWithCancellationAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class All
|
||||
{
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AllAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -57,7 +57,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AllAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -81,7 +81,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AllAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Any.InvokeAsync(source, cancellationToken);
|
||||
return Any.AnyAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<Boolean> AnyAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken = default)
|
||||
@@ -18,7 +18,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return Any.InvokeAsync(source, predicate, cancellationToken);
|
||||
return Any.AnyAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<Boolean> AnyAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
|
||||
@@ -26,7 +26,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return Any.InvokeAsync(source, predicate, cancellationToken);
|
||||
return Any.AnyAwaitAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<Boolean> AnyAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
|
||||
@@ -34,13 +34,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(predicate, nameof(predicate));
|
||||
|
||||
return Any.InvokeAsync(source, predicate, cancellationToken);
|
||||
return Any.AnyAwaitWithCancellationAsync(source, predicate, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Any
|
||||
{
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AnyAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -61,7 +61,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AnyAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -85,7 +85,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AnyAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
@@ -109,7 +109,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
internal static async UniTask<bool> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
internal static async UniTask<bool> AnyAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source, element, append, cancellationToken);
|
||||
return new _AppendPrepend(source, element, append, cancellationToken);
|
||||
}
|
||||
|
||||
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
|
||||
sealed class _AppendPrepend : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
|
||||
{
|
||||
enum State : byte
|
||||
{
|
||||
@@ -59,12 +59,14 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
IUniTaskAsyncEnumerator<TSource> enumerator;
|
||||
UniTask<bool>.Awaiter awaiter;
|
||||
|
||||
public Enumerator(IUniTaskAsyncEnumerable<TSource> source, TSource element, bool append, CancellationToken cancellationToken)
|
||||
public _AppendPrepend(IUniTaskAsyncEnumerable<TSource> source, TSource element, bool append, CancellationToken cancellationToken)
|
||||
{
|
||||
this.source = source;
|
||||
this.element = element;
|
||||
this.state = append ? State.RequireAppend : State.RequirePrepend;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
}
|
||||
|
||||
public TSource Current { get; private set; }
|
||||
@@ -108,7 +110,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
static void MoveNextCore(object state)
|
||||
{
|
||||
var self = (Enumerator)state;
|
||||
var self = (_AppendPrepend)state;
|
||||
|
||||
if (self.TryGetResult(self.awaiter, out var result))
|
||||
{
|
||||
@@ -136,6 +138,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
if (enumerator != null)
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
|
||||
@@ -3,66 +3,9 @@ using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public abstract class MoveNextSource : IUniTaskSource<bool>
|
||||
{
|
||||
protected UniTaskCompletionSourceCore<bool> completionSource;
|
||||
|
||||
public bool GetResult(short token)
|
||||
{
|
||||
return completionSource.GetResult(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return completionSource.GetStatus(token);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
completionSource.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return completionSource.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
completionSource.GetResult(token);
|
||||
}
|
||||
|
||||
protected bool TryGetResult<T>(UniTask<T>.Awaiter awaiter, out T result)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = awaiter.GetResult();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool TryGetResult(UniTask.Awaiter awaiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
awaiter.GetResult();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
completionSource.TrySetException(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AsyncEnumeratorBase<TSource, TResult> : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
|
||||
// note: refactor all inherit class and should remove this.
|
||||
// see Select and Where.
|
||||
internal abstract class AsyncEnumeratorBase<TSource, TResult> : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
|
||||
{
|
||||
static readonly Action<object> moveNextCallbackDelegate = MoveNextCallBack;
|
||||
|
||||
@@ -76,6 +19,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
this.source = source;
|
||||
this.cancellationToken = cancellationToken;
|
||||
TaskTracker.TrackActiveTask(this, 4);
|
||||
}
|
||||
|
||||
// abstract
|
||||
@@ -178,6 +122,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
// if require additional resource to dispose, override and call base.DisposeAsync.
|
||||
public virtual UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
if (enumerator != null)
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
@@ -186,7 +131,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AsyncEnumeratorAwaitSelectorBase<TSource, TResult, TAwait> : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
|
||||
internal abstract class AsyncEnumeratorAwaitSelectorBase<TSource, TResult, TAwait> : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
|
||||
{
|
||||
static readonly Action<object> moveNextCallbackDelegate = MoveNextCallBack;
|
||||
static readonly Action<object> setCurrentCallbackDelegate = SetCurrentCallBack;
|
||||
@@ -204,6 +149,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
this.source = source;
|
||||
this.cancellationToken = cancellationToken;
|
||||
TaskTracker.TrackActiveTask(this, 4);
|
||||
}
|
||||
|
||||
// abstract
|
||||
@@ -399,6 +345,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
// if require additional resource to dispose, override and call base.DisposeAsync.
|
||||
public virtual UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
if (enumerator != null)
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
@@ -406,5 +353,4 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32> selector, CancellationToken cancellationToken = default)
|
||||
@@ -18,7 +18,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -26,22 +26,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAsync(this IUniTaskAsyncEnumerable<Int64> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64> selector, CancellationToken cancellationToken = default)
|
||||
@@ -49,7 +49,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -57,22 +57,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float> AverageAsync(this IUniTaskAsyncEnumerable<Single> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single> selector, CancellationToken cancellationToken = default)
|
||||
@@ -80,7 +80,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -88,22 +88,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<float> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAsync(this IUniTaskAsyncEnumerable<Double> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double> selector, CancellationToken cancellationToken = default)
|
||||
@@ -111,7 +111,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -119,22 +119,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal> AverageAsync(this IUniTaskAsyncEnumerable<Decimal> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal> selector, CancellationToken cancellationToken = default)
|
||||
@@ -142,7 +142,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -150,22 +150,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<decimal> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync(this IUniTaskAsyncEnumerable<Int32?> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32?> selector, CancellationToken cancellationToken = default)
|
||||
@@ -173,7 +173,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32?>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -181,22 +181,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32?>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32?>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync(this IUniTaskAsyncEnumerable<Int64?> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64?> selector, CancellationToken cancellationToken = default)
|
||||
@@ -204,7 +204,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64?>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -212,22 +212,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64?>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64?>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float?> AverageAsync(this IUniTaskAsyncEnumerable<Single?> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float?> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single?> selector, CancellationToken cancellationToken = default)
|
||||
@@ -235,7 +235,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float?> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single?>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -243,22 +243,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<float?> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single?>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<float?> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single?>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync(this IUniTaskAsyncEnumerable<Double?> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double?> selector, CancellationToken cancellationToken = default)
|
||||
@@ -266,7 +266,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double?>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -274,22 +274,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<double?> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double?>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double?>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal?> AverageAsync(this IUniTaskAsyncEnumerable<Decimal?> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal?> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal?> selector, CancellationToken cancellationToken = default)
|
||||
@@ -297,7 +297,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal?> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal?>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -305,22 +305,22 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<decimal?> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal?>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<decimal?> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal?>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static class Average
|
||||
{
|
||||
public static async UniTask<double> InvokeAsync(IUniTaskAsyncEnumerable<Int32> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync(IUniTaskAsyncEnumerable<Int32> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32 sum = 0;
|
||||
@@ -348,7 +348,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32 sum = 0;
|
||||
@@ -376,7 +376,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32 sum = 0;
|
||||
@@ -404,7 +404,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32 sum = 0;
|
||||
@@ -432,7 +432,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync(IUniTaskAsyncEnumerable<Int64> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync(IUniTaskAsyncEnumerable<Int64> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64 sum = 0;
|
||||
@@ -460,7 +460,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64 sum = 0;
|
||||
@@ -488,7 +488,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64 sum = 0;
|
||||
@@ -516,7 +516,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64 sum = 0;
|
||||
@@ -544,7 +544,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<float> InvokeAsync(IUniTaskAsyncEnumerable<Single> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<float> AverageAsync(IUniTaskAsyncEnumerable<Single> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single sum = 0;
|
||||
@@ -572,7 +572,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single sum = 0;
|
||||
@@ -600,7 +600,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single sum = 0;
|
||||
@@ -628,7 +628,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single sum = 0;
|
||||
@@ -656,7 +656,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync(IUniTaskAsyncEnumerable<Double> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync(IUniTaskAsyncEnumerable<Double> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double sum = 0;
|
||||
@@ -684,7 +684,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double sum = 0;
|
||||
@@ -712,7 +712,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double sum = 0;
|
||||
@@ -740,7 +740,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double sum = 0;
|
||||
@@ -768,7 +768,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal> InvokeAsync(IUniTaskAsyncEnumerable<Decimal> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal> AverageAsync(IUniTaskAsyncEnumerable<Decimal> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal sum = 0;
|
||||
@@ -796,7 +796,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal sum = 0;
|
||||
@@ -824,7 +824,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal sum = 0;
|
||||
@@ -852,7 +852,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal sum = 0;
|
||||
@@ -880,7 +880,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync(IUniTaskAsyncEnumerable<Int32?> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync(IUniTaskAsyncEnumerable<Int32?> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32? sum = 0;
|
||||
@@ -893,7 +893,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -912,7 +912,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32?> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32?> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32? sum = 0;
|
||||
@@ -925,7 +925,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -944,7 +944,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int32?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32? sum = 0;
|
||||
@@ -957,7 +957,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -976,7 +976,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int32?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int32? sum = 0;
|
||||
@@ -989,7 +989,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1008,7 +1008,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync(IUniTaskAsyncEnumerable<Int64?> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync(IUniTaskAsyncEnumerable<Int64?> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64? sum = 0;
|
||||
@@ -1021,7 +1021,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1040,7 +1040,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64?> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int64?> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64? sum = 0;
|
||||
@@ -1053,7 +1053,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1072,7 +1072,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Int64?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64? sum = 0;
|
||||
@@ -1085,7 +1085,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1104,7 +1104,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Int64?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Int64? sum = 0;
|
||||
@@ -1117,7 +1117,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1136,7 +1136,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (double)sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<float?> InvokeAsync(IUniTaskAsyncEnumerable<Single?> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<float?> AverageAsync(IUniTaskAsyncEnumerable<Single?> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single? sum = 0;
|
||||
@@ -1149,7 +1149,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1168,7 +1168,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single?> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float?> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Single?> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single? sum = 0;
|
||||
@@ -1181,7 +1181,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1200,7 +1200,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float?> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Single?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single? sum = 0;
|
||||
@@ -1213,7 +1213,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1232,7 +1232,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<float?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<float?> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Single?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Single? sum = 0;
|
||||
@@ -1245,7 +1245,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1264,7 +1264,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return (float)(sum / count);
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync(IUniTaskAsyncEnumerable<Double?> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync(IUniTaskAsyncEnumerable<Double?> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double? sum = 0;
|
||||
@@ -1277,7 +1277,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1296,7 +1296,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double?> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Double?> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double? sum = 0;
|
||||
@@ -1309,7 +1309,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1328,7 +1328,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Double?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double? sum = 0;
|
||||
@@ -1341,7 +1341,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1360,7 +1360,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<double?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<double?> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Double?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Double? sum = 0;
|
||||
@@ -1373,7 +1373,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1392,7 +1392,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal?> InvokeAsync(IUniTaskAsyncEnumerable<Decimal?> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal?> AverageAsync(IUniTaskAsyncEnumerable<Decimal?> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal? sum = 0;
|
||||
@@ -1405,7 +1405,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1424,7 +1424,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal?> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal?> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Decimal?> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal? sum = 0;
|
||||
@@ -1437,7 +1437,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1456,7 +1456,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal?> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Decimal?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal? sum = 0;
|
||||
@@ -1469,7 +1469,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
@@ -1488,7 +1488,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
public static async UniTask<decimal?> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal?>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<decimal?> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Decimal?>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
Decimal? sum = 0;
|
||||
@@ -1501,7 +1501,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.InvokeAsync(source, cancellationToken);
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -47,7 +47,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
@@ -55,15 +55,15 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
public static UniTask<<#= ret #>> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.InvokeAsync(source, selector, cancellationToken);
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
@@ -72,7 +72,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
internal static class Average
|
||||
{
|
||||
<# foreach(var (t, ret) in types) { #>
|
||||
public static async UniTask<<#= ret #>> InvokeAsync(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
|
||||
public static async UniTask<<#= ret #>> AverageAsync(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
@@ -112,7 +112,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<<#= ret #>> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
@@ -152,7 +152,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<<#= ret #>> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
@@ -192,7 +192,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
public static async UniTask<<#= ret #>> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public IUniTaskAsyncEnumerator<IList<TSource>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source, count, cancellationToken);
|
||||
return new _Buffer(source, count, cancellationToken);
|
||||
}
|
||||
|
||||
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<IList<TSource>>
|
||||
sealed class _Buffer : MoveNextSource, IUniTaskAsyncEnumerator<IList<TSource>>
|
||||
{
|
||||
static readonly Action<object> MoveNextCoreDelegate = MoveNextCore;
|
||||
|
||||
@@ -56,11 +56,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
bool completed;
|
||||
List<TSource> buffer;
|
||||
|
||||
public Enumerator(IUniTaskAsyncEnumerable<TSource> source, int count, CancellationToken cancellationToken)
|
||||
public _Buffer(IUniTaskAsyncEnumerable<TSource> source, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
this.source = source;
|
||||
this.count = count;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
}
|
||||
|
||||
public IList<TSource> Current { get; private set; }
|
||||
@@ -128,7 +130,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
static void MoveNextCore(object state)
|
||||
{
|
||||
var self = (Enumerator)state;
|
||||
var self = (_Buffer)state;
|
||||
|
||||
if (self.TryGetResult(self.awaiter, out var result))
|
||||
{
|
||||
@@ -167,6 +169,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
if (enumerator != null)
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
@@ -191,10 +194,10 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public IUniTaskAsyncEnumerator<IList<TSource>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source, count, skip, cancellationToken);
|
||||
return new _BufferSkip(source, count, skip, cancellationToken);
|
||||
}
|
||||
|
||||
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<IList<TSource>>
|
||||
sealed class _BufferSkip : MoveNextSource, IUniTaskAsyncEnumerator<IList<TSource>>
|
||||
{
|
||||
static readonly Action<object> MoveNextCoreDelegate = MoveNextCore;
|
||||
|
||||
@@ -211,12 +214,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
Queue<List<TSource>> buffers;
|
||||
int index = 0;
|
||||
|
||||
public Enumerator(IUniTaskAsyncEnumerable<TSource> source, int count, int skip, CancellationToken cancellationToken)
|
||||
public _BufferSkip(IUniTaskAsyncEnumerable<TSource> source, int count, int skip, CancellationToken cancellationToken)
|
||||
{
|
||||
this.source = source;
|
||||
this.count = count;
|
||||
this.skip = skip;
|
||||
this.cancellationToken = cancellationToken;
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
}
|
||||
|
||||
public IList<TSource> Current { get; private set; }
|
||||
@@ -282,7 +286,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
static void MoveNextCore(object state)
|
||||
{
|
||||
var self = (Enumerator)state;
|
||||
var self = (_BufferSkip)state;
|
||||
|
||||
if (self.TryGetResult(self.awaiter, out var result))
|
||||
{
|
||||
@@ -329,6 +333,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
if (enumerator != null)
|
||||
{
|
||||
return enumerator.DisposeAsync();
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source, cancellationToken);
|
||||
return new _Cast(source, cancellationToken);
|
||||
}
|
||||
|
||||
class Enumerator : AsyncEnumeratorBase<object, TResult>
|
||||
class _Cast : AsyncEnumeratorBase<object, TResult>
|
||||
{
|
||||
public Enumerator(IUniTaskAsyncEnumerable<object> source, CancellationToken cancellationToken)
|
||||
public _Cast(IUniTaskAsyncEnumerable<object> source, CancellationToken cancellationToken)
|
||||
|
||||
: base(source, cancellationToken)
|
||||
{
|
||||
|
||||
11372
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/CombineLatest.cs
Normal file
11372
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/CombineLatest.cs
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user