mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-16 03:50:11 +00:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfe509a556 | ||
|
|
a46a4cac01 | ||
|
|
3ed28e534a | ||
|
|
be8dbe8804 | ||
|
|
64f7eec4e9 | ||
|
|
3a93f4a49f | ||
|
|
71958adc3d | ||
|
|
acc71550c9 | ||
|
|
3ba64412f8 | ||
|
|
90c5e5a6ad | ||
|
|
8a022ee02d | ||
|
|
6a89ea8139 | ||
|
|
90c81613ac | ||
|
|
7c62904a74 | ||
|
|
4f6344a12f | ||
|
|
937d3adf66 | ||
|
|
3bac16229f | ||
|
|
ea57847c97 | ||
|
|
730d68132d | ||
|
|
6db872236e | ||
|
|
ba7e676c6f | ||
|
|
6e99accf99 | ||
|
|
b195df9773 | ||
|
|
f303d9d7e8 | ||
|
|
62a2a2e8f9 | ||
|
|
ffbadbcc4c | ||
|
|
50ad2ee9d6 | ||
|
|
c170af5642 | ||
|
|
242bceecd3 | ||
|
|
06346b8a2a | ||
|
|
b071eeadfb | ||
|
|
e7f23d8328 | ||
|
|
47a3f09abf | ||
|
|
a7a6af0a68 | ||
|
|
f203b6c051 | ||
|
|
07211f1fc3 | ||
|
|
bc27f6c0d8 | ||
|
|
c65f9c3497 | ||
|
|
afe5f57adc | ||
|
|
9135c7ce56 | ||
|
|
7fae415689 | ||
|
|
e5cc8667ac | ||
|
|
0ea18d0e16 | ||
|
|
2d674999f0 | ||
|
|
3121903fa3 | ||
|
|
af2e49aa29 | ||
|
|
22940635fe | ||
|
|
c1042b32b7 | ||
|
|
29a144694d | ||
|
|
548d56e654 | ||
|
|
6fb4f2d6d2 | ||
|
|
8eac07ad24 | ||
|
|
716402a180 | ||
|
|
4c3d6938ed | ||
|
|
b4486802f2 | ||
|
|
d210e3d76a | ||
|
|
f2773f585e | ||
|
|
305695ad5d | ||
|
|
418ab36a72 | ||
|
|
563b4fbbd5 | ||
|
|
878d33115f | ||
|
|
356a4ee62e | ||
|
|
eb32ae25e0 | ||
|
|
3ca4062536 | ||
|
|
019f8aaf30 | ||
|
|
663fa737f3 | ||
|
|
73d86259ce | ||
|
|
c7eedf85c7 | ||
|
|
8dc3ffd552 | ||
|
|
b992a061fb | ||
|
|
4fc09a6f61 | ||
|
|
e57176a43c | ||
|
|
710d0d9012 | ||
|
|
039de3ef65 | ||
|
|
de38f63a55 | ||
|
|
38f8193199 | ||
|
|
15cffb7357 | ||
|
|
d55748e05b | ||
|
|
5602861dd4 | ||
|
|
d2245bc38b | ||
|
|
f092f6a112 | ||
|
|
ed617a04a6 | ||
|
|
340736795c | ||
|
|
dc804ffb13 | ||
|
|
a879989d1c | ||
|
|
ee54559532 | ||
|
|
4a72ec2a1a | ||
|
|
e999268305 | ||
|
|
8300c1b1e6 | ||
|
|
daa0c7b9a0 | ||
|
|
9b9a4ec76a | ||
|
|
3f8e43b83f | ||
|
|
cf6f0799e9 | ||
|
|
91ba4f003a | ||
|
|
f48cb4b03e | ||
|
|
70a243d978 | ||
|
|
9b95f3b9f6 | ||
|
|
a25adb601b | ||
|
|
e6240879c4 | ||
|
|
a94e8cceac | ||
|
|
0595a4182a | ||
|
|
df96c119c1 | ||
|
|
534f4a2588 | ||
|
|
873485ad1a | ||
|
|
f6037d6c9b | ||
|
|
78db78c7bd | ||
|
|
226e272787 | ||
|
|
9e2163616b | ||
|
|
52df6fbf3f | ||
|
|
33d32baea4 | ||
|
|
b0250cfe75 | ||
|
|
7a35f121cd |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
github: [neuecc]
|
||||||
55
.github/workflows/build-debug.yml
vendored
55
.github/workflows/build-debug.yml
vendored
@@ -4,8 +4,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "master"
|
- "master"
|
||||||
tags:
|
|
||||||
- "!*" # not a tag push
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- "master"
|
- "master"
|
||||||
@@ -13,67 +11,60 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-dotnet:
|
build-dotnet:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
timeout-minutes: 10
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
||||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
|
||||||
NUGET_XMLDOC_MODE: skip
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- run: dotnet test -c Debug ./src/UniTask.NetCoreTests/UniTask.NetCoreTests.csproj
|
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
6.0.x
|
||||||
|
7.0.x
|
||||||
|
- run: dotnet build -c Debug
|
||||||
|
- run: dotnet test -c Debug
|
||||||
|
|
||||||
build-unity:
|
build-unity:
|
||||||
if: "((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))"
|
if: "((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))"
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
unity: ["2019.3.9f1", "2019.4.13f1", "2020.1.12f1"]
|
unity: ["2019.3.9f1", "2019.4.13f1", "2020.1.12f1"]
|
||||||
include:
|
|
||||||
- unity: 2019.3.9f1
|
|
||||||
license: UNITY_LICENSE_2019
|
|
||||||
- unity: 2019.4.13f1
|
|
||||||
license: UNITY_LICENSE_2019
|
|
||||||
- unity: 2020.1.12f1
|
|
||||||
license: UNITY_LICENSE_2020
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
# Execute scripts: RuntimeUnitTestToolkit
|
# Execute scripts: RuntimeUnitTestToolkit
|
||||||
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend mono /BuildTarget StandaloneLinux64
|
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend mono /BuildTarget StandaloneLinux64
|
||||||
- name: Build UnitTest(Linux64, mono)
|
- name: Build UnitTest(Linux64, mono)
|
||||||
uses: game-ci/unity-builder@v2.0-alpha-6
|
uses: Cysharp/Actions/.github/actions/unity-builder@main
|
||||||
env:
|
env:
|
||||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
with:
|
with:
|
||||||
projectPath: src/UniTask
|
projectPath: src/UniTask
|
||||||
unityVersion: ${{ matrix.unity }}
|
unityVersion: ${{ matrix.unity }}
|
||||||
targetPlatform: StandaloneLinux64
|
targetPlatform: StandaloneLinux64
|
||||||
buildMethod: UnitTestBuilder.BuildUnitTest
|
buildMethod: UnitTestBuilder.BuildUnitTest
|
||||||
customParameters: /headless /ScriptBackend mono
|
customParameters: /headless /ScriptBackend mono
|
||||||
versioning: None
|
|
||||||
- name: Execute UnitTest
|
- name: Execute UnitTest
|
||||||
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_Mono2x/test
|
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_Mono2x/test
|
||||||
|
|
||||||
# Execute scripts: Export Package
|
# Execute scripts: Export Package
|
||||||
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
||||||
- name: Export unitypackage
|
- name: Build Unity (.unitypacakge)
|
||||||
uses: game-ci/unity-builder@v2.0-alpha-6
|
uses: Cysharp/Actions/.github/actions/unity-builder@main
|
||||||
env:
|
env:
|
||||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
with:
|
with:
|
||||||
projectPath: src/UniTask
|
projectPath: src/UniTask
|
||||||
unityVersion: ${{ matrix.unity }}
|
unityVersion: ${{ matrix.unity }}
|
||||||
targetPlatform: StandaloneLinux64
|
targetPlatform: StandaloneLinux64
|
||||||
buildMethod: PackageExporter.Export
|
buildMethod: PackageExporter.Export
|
||||||
versioning: None
|
|
||||||
|
|
||||||
- name: check all .meta is commited
|
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
|
||||||
run: |
|
with:
|
||||||
if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then
|
directory: src/UniTask
|
||||||
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.
|
# Store artifacts.
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
|
|||||||
5
.github/workflows/build-docs.yml
vendored
5
.github/workflows/build-docs.yml
vendored
@@ -9,9 +9,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
run-docfx:
|
run-docfx:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: Cysharp/DocfxTemplate
|
repository: Cysharp/DocfxTemplate
|
||||||
path: docs/_DocfxTemplate
|
path: docs/_DocfxTemplate
|
||||||
|
|||||||
128
.github/workflows/build-release.yml
vendored
128
.github/workflows/build-release.yml
vendored
@@ -6,90 +6,44 @@ on:
|
|||||||
tag:
|
tag:
|
||||||
description: "tag: git tag you want create. (sample 1.0.0)"
|
description: "tag: git tag you want create. (sample 1.0.0)"
|
||||||
required: true
|
required: true
|
||||||
dry_run:
|
dry-run:
|
||||||
description: "dry_run: true will never create relase/nuget."
|
description: "dry-run: true will never create relase/nuget."
|
||||||
required: true
|
required: true
|
||||||
default: "false"
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GIT_TAG: ${{ github.event.inputs.tag }}
|
GIT_TAG: ${{ github.event.inputs.tag }}
|
||||||
DRY_RUN: ${{ github.event.inputs.dry_run }}
|
DRY_RUN: ${{ github.event.inputs.dry-run }}
|
||||||
DRY_RUN_BRANCH_PREFIX: "test_release"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-packagejson:
|
update-packagejson:
|
||||||
runs-on: ubuntu-latest
|
uses: Cysharp/Actions/.github/workflows/update-packagejson.yaml@main
|
||||||
env:
|
with:
|
||||||
TARGET_FILE: ./src/UniTask/Assets/Plugins/UniTask/package.json
|
file-path: ./src/UniTask/Assets/Plugins/UniTask/package.json
|
||||||
outputs:
|
tag: ${{ github.event.inputs.tag }}
|
||||||
sha: ${{ steps.commit.outputs.sha }}
|
dry-run: ${{ fromJson(github.event.inputs.dry-run) }}
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Output package.json (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: Check update
|
|
||||||
id: check_update
|
|
||||||
run: |
|
|
||||||
cat ${{ env.TARGET_FILE}}
|
|
||||||
git diff --exit-code || echo "::set-output name=changed::1"
|
|
||||||
|
|
||||||
- name: Commit files
|
|
||||||
id: commit
|
|
||||||
if: steps.check_update.outputs.changed == '1'
|
|
||||||
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: Create Tag
|
|
||||||
if: steps.check_update.outputs.changed == '1'
|
|
||||||
run: git tag ${{ env.GIT_TAG }}
|
|
||||||
|
|
||||||
- name: Push changes
|
|
||||||
if: env.DRY_RUN == 'false' && steps.check_update.outputs.changed == '1'
|
|
||||||
uses: ad-m/github-push-action@master
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
branch: ${{ github.ref }}
|
|
||||||
tags: true
|
|
||||||
|
|
||||||
- name: Push changes (dry_run)
|
|
||||||
if: env.DRY_RUN == 'true' && steps.check_update.outputs.changed == '1'
|
|
||||||
uses: ad-m/github-push-action@master
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
branch: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }}
|
|
||||||
tags: false
|
|
||||||
|
|
||||||
build-dotnet:
|
build-dotnet:
|
||||||
needs: [update-packagejson]
|
needs: [update-packagejson]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
||||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
|
||||||
NUGET_XMLDOC_MODE: skip
|
|
||||||
steps:
|
steps:
|
||||||
- run: echo ${{ needs.update-packagejson.outputs.sha }}
|
- run: echo ${{ needs.update-packagejson.outputs.sha }}
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.update-packagejson.outputs.sha }}
|
ref: ${{ needs.update-packagejson.outputs.sha }}
|
||||||
|
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
3.1.x
|
||||||
|
6.0.x
|
||||||
# build and pack
|
# build and pack
|
||||||
- run: dotnet build -c Release -p:Version=${{ env.GIT_TAG }}
|
- run: dotnet build -c Release -p:Version=${{ env.GIT_TAG }}
|
||||||
- run: dotnet test -c Release --no-build
|
- run: dotnet test -c Release --no-build
|
||||||
- run: dotnet pack ./src/UniTask.NetCore/UniTask.NetCore.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish
|
- run: dotnet pack ./src/UniTask.NetCore/UniTask.NetCore.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish
|
||||||
# Store artifacts.
|
# Store artifacts.
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: nuget
|
name: nuget
|
||||||
path: ./publish/
|
path: ./publish/
|
||||||
@@ -99,38 +53,30 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
unity: ["2019.3.9f1"]
|
unity: ["2019.3.9f1"]
|
||||||
include:
|
|
||||||
- unity: 2019.3.9f1
|
|
||||||
license: UNITY_LICENSE_2019
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- run: echo ${{ needs.update-packagejson.outputs.sha }}
|
- run: echo ${{ needs.update-packagejson.outputs.sha }}
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ needs.update-packagejson.outputs.sha }}
|
ref: ${{ needs.update-packagejson.outputs.sha }}
|
||||||
# Execute scripts: Export Package
|
# Execute scripts: Export Package
|
||||||
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
|
||||||
- name: Export unitypackage
|
- name: Build Unity (.unitypacakge)
|
||||||
uses: game-ci/unity-builder@v2.0-alpha-6
|
uses: Cysharp/Actions/.github/actions/unity-builder@main
|
||||||
env:
|
env:
|
||||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
|
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
|
||||||
with:
|
with:
|
||||||
projectPath: src/UniTask
|
projectPath: src/UniTask
|
||||||
unityVersion: ${{ matrix.unity }}
|
unityVersion: ${{ matrix.unity }}
|
||||||
targetPlatform: StandaloneLinux64
|
targetPlatform: StandaloneLinux64
|
||||||
buildMethod: PackageExporter.Export
|
buildMethod: PackageExporter.Export
|
||||||
versioning: None
|
|
||||||
|
|
||||||
- name: check all .meta is commited
|
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
|
||||||
run: |
|
with:
|
||||||
if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then
|
directory: src/UniTask
|
||||||
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.
|
# Store artifacts.
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
@@ -139,14 +85,12 @@ jobs:
|
|||||||
path: ./src/UniTask/UniTask.${{ env.GIT_TAG }}.unitypackage
|
path: ./src/UniTask/UniTask.${{ env.GIT_TAG }}.unitypackage
|
||||||
|
|
||||||
create-release:
|
create-release:
|
||||||
if: github.event.inputs.dry_run == 'false'
|
if: github.event.inputs.dry-run == 'false'
|
||||||
needs: [update-packagejson, build-dotnet, build-unity]
|
needs: [update-packagejson, build-dotnet, build-unity]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
timeout-minutes: 10
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
||||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
|
||||||
NUGET_XMLDOC_MODE: skip
|
|
||||||
steps:
|
steps:
|
||||||
|
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
|
||||||
# Create Releases
|
# Create Releases
|
||||||
- uses: actions/create-release@v1
|
- uses: actions/create-release@v1
|
||||||
id: create_release
|
id: create_release
|
||||||
@@ -173,12 +117,8 @@ jobs:
|
|||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if: github.event.inputs.dry_run == 'true'
|
if: needs.update-packagejson.outputs.is-branch-created == 'true'
|
||||||
needs: [build-dotnet, build-unity]
|
needs: [update-packagejson, build-dotnet, build-unity]
|
||||||
runs-on: ubuntu-latest
|
uses: Cysharp/Actions/.github/workflows/clean-packagejson-branch.yaml@main
|
||||||
steps:
|
with:
|
||||||
- name: Delete branch
|
branch: ${{ needs.update-packagejson.outputs.branch-name }}
|
||||||
uses: dawidd6/action-delete-branch@v3
|
|
||||||
with:
|
|
||||||
github_token: ${{ github.token }}
|
|
||||||
branches: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }}
|
|
||||||
|
|||||||
10
.github/workflows/prevent-github-change.yml
vendored
Normal file
10
.github/workflows/prevent-github-change.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: Prevent github change
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- ".github/**/*.yaml"
|
||||||
|
- ".github/**/*.yml"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
detect:
|
||||||
|
uses: Cysharp/Actions/.github/workflows/prevent-github-change.yaml@main
|
||||||
18
.github/workflows/stale.yml
vendored
18
.github/workflows/stale.yml
vendored
@@ -1,24 +1,10 @@
|
|||||||
name: "Close stale issues"
|
name: "Close stale issues"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
uses: Cysharp/Actions/.github/workflows/stale-issue.yaml@main
|
||||||
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
|
|
||||||
|
|||||||
26
README.md
26
README.md
@@ -1,6 +1,6 @@
|
|||||||
UniTask
|
UniTask
|
||||||
===
|
===
|
||||||
[](https://github.com/Cysharp/UniTask/actions) [](https://github.com/Cysharp/UniTask/releases)
|
[](https://github.com/Cysharp/UniTask/actions) [](https://github.com/Cysharp/UniTask/releases) [](https://github.com/Cysharp/UniTask/blob/master/README_CN.md)
|
||||||
|
|
||||||
Provides an efficient allocation free async/await integration for Unity.
|
Provides an efficient allocation free async/await integration for Unity.
|
||||||
|
|
||||||
@@ -44,7 +44,6 @@ For advanced tips, see blog post: [Extends UnityWebRequest via async decorator p
|
|||||||
- [API References](#api-references)
|
- [API References](#api-references)
|
||||||
- [UPM Package](#upm-package)
|
- [UPM Package](#upm-package)
|
||||||
- [Install via git URL](#install-via-git-url)
|
- [Install via git URL](#install-via-git-url)
|
||||||
- [Install via OpenUPM](#install-via-openupm)
|
|
||||||
- [.NET Core](#net-core)
|
- [.NET Core](#net-core)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
|
|
||||||
@@ -86,8 +85,13 @@ async UniTask<string> DemoAsync()
|
|||||||
await UniTask.Yield();
|
await UniTask.Yield();
|
||||||
await UniTask.NextFrame();
|
await UniTask.NextFrame();
|
||||||
|
|
||||||
// replacement of WaitForEndOfFrame(requires MonoBehaviour(CoroutineRunner))
|
// replacement of WaitForEndOfFrame
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
await UniTask.WaitForEndOfFrame();
|
||||||
|
#else
|
||||||
|
// requires MonoBehaviour(CoroutineRunner))
|
||||||
await UniTask.WaitForEndOfFrame(this); // this is MonoBehaviour
|
await UniTask.WaitForEndOfFrame(this); // this is MonoBehaviour
|
||||||
|
#endif
|
||||||
|
|
||||||
// replacement of yield return new WaitForFixedUpdate(same as UniTask.Yield(PlayerLoopTiming.FixedUpdate))
|
// replacement of yield return new WaitForFixedUpdate(same as UniTask.Yield(PlayerLoopTiming.FixedUpdate))
|
||||||
await UniTask.WaitForFixedUpdate();
|
await UniTask.WaitForFixedUpdate();
|
||||||
@@ -499,6 +503,8 @@ It indicates when to run, you can check [PlayerLoopList.md](https://gist.github.
|
|||||||
`PlayerLoopTiming.Update` is similar to `yield return null` in a coroutine, but it is called before Update(Update and uGUI events(button.onClick, etc...) are called on `ScriptRunBehaviourUpdate`, yield return null is called on `ScriptRunDelayedDynamicFrameRate`). `PlayerLoopTiming.FixedUpdate` is similar to `WaitForFixedUpdate`.
|
`PlayerLoopTiming.Update` is similar to `yield return null` in a coroutine, but it is called before Update(Update and uGUI events(button.onClick, etc...) are called on `ScriptRunBehaviourUpdate`, yield return null is called on `ScriptRunDelayedDynamicFrameRate`). `PlayerLoopTiming.FixedUpdate` is similar to `WaitForFixedUpdate`.
|
||||||
|
|
||||||
> `PlayerLoopTiming.LastPostLateUpdate` is not equivalent to coroutine's `yield return new WaitForEndOfFrame()`. Coroutine's WaitForEndOfFrame seems to run after the PlayerLoop is done. Some methods that require coroutine's end of frame(`Texture2D.ReadPixels`, `ScreenCapture.CaptureScreenshotAsTexture`, `CommandBuffer`, etc) do not work correctly when replaced with async/await. In these cases, pass MonoBehaviour(coroutine runnner) to `UniTask.WaitForEndOfFrame`. For example, `await UniTask.WaitForEndOfFrame(this);` is lightweight allocation free alternative of `yield return new WaitForEndOfFrame()`.
|
> `PlayerLoopTiming.LastPostLateUpdate` is not equivalent to coroutine's `yield return new WaitForEndOfFrame()`. Coroutine's WaitForEndOfFrame seems to run after the PlayerLoop is done. Some methods that require coroutine's end of frame(`Texture2D.ReadPixels`, `ScreenCapture.CaptureScreenshotAsTexture`, `CommandBuffer`, etc) do not work correctly when replaced with async/await. In these cases, pass MonoBehaviour(coroutine runnner) to `UniTask.WaitForEndOfFrame`. For example, `await UniTask.WaitForEndOfFrame(this);` is lightweight allocation free alternative of `yield return new WaitForEndOfFrame()`.
|
||||||
|
>
|
||||||
|
> Note: In Unity 2023.1 or newer, `await UniTask.WaitForEndOfFrame();` no longer requires MonoBehaviour. It uses `UnityEngine.Awaitable.EndOfFrameAsync`.
|
||||||
|
|
||||||
`yield return null` and `UniTask.Yield` are similar but different. `yield return null` always returns next frame but `UniTask.Yield` returns next called. That is, call `UniTask.Yield(PlayerLoopTiming.Update)` on `PreUpdate`, it returns same frame. `UniTask.NextFrame()` guarantees return next frame, you can expect this to behave exactly the same as `yield return null`.
|
`yield return null` and `UniTask.Yield` are similar but different. `yield return null` always returns next frame but `UniTask.Yield` returns next called. That is, call `UniTask.Yield(PlayerLoopTiming.Update)` on `PreUpdate`, it returns same frame. `UniTask.NextFrame()` guarantees return next frame, you can expect this to behave exactly the same as `yield return null`.
|
||||||
|
|
||||||
@@ -658,7 +664,8 @@ By default, UniTask supports TextMeshPro(`BindTo(TMP_Text)` and `TMP_InputField`
|
|||||||
|
|
||||||
There are defined in separated asmdefs like `UniTask.TextMeshPro`, `UniTask.DOTween`, `UniTask.Addressables`.
|
There are defined in separated asmdefs like `UniTask.TextMeshPro`, `UniTask.DOTween`, `UniTask.Addressables`.
|
||||||
|
|
||||||
TextMeshPro and Addressables support are automatically enabled when importing their packages from package manager. However for DOTween support, it is required to import `com.demigiant.dotween` from [OpenUPM](https://openupm.com/packages/com.demigiant.dotween/) or to define `UNITASK_DOTWEEN_SUPPORT` to enable it.
|
TextMeshPro and Addressables support are automatically enabled when importing their packages from package manager.
|
||||||
|
However for DOTween support, after importing from the [DOTWeen assets](https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676r) and define the scripting define symbol `UNITASK_DOTWEEN_SUPPORT` to enable it.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// sequential
|
// sequential
|
||||||
@@ -717,7 +724,7 @@ Async LINQ is enabled when `using Cysharp.Threading.Tasks.Linq;`, and `UniTaskAs
|
|||||||
|
|
||||||
It's closer to UniRx (Reactive Extensions), but UniTaskAsyncEnumerable is a pull-based asynchronous stream, whereas Rx was a push-based asynchronous stream. Note that although similar, the characteristics are different and the details behave differently along with them.
|
It's closer to UniRx (Reactive Extensions), but UniTaskAsyncEnumerable is a pull-based asynchronous stream, whereas Rx was a push-based asynchronous stream. Note that although similar, the characteristics are different and the details behave differently along with them.
|
||||||
|
|
||||||
`UniTaskAsyncEnumerable` is the entry point like `Enumerable`. In addition to the standard query operators, there are other generators for Unity such as `EveryUpdate`, `Timer`, `TimerFrame`, `Interval`, `IntervalFrame`, and `EveryValueChanged`. And also added additional UniTask original query operators like `Append`, `Prepend`, `DistinctUntilChanged`, `ToHashSet`, `Buffer`, `CombineLatest`, `Do`, `Never`, `ForEachAsync`, `Pairwise`, `Publish`, `Queue`, `Return`, `SkipUntil`, `TakeUntil`, `SkipUntilCanceled`, `TakeUntilCanceled`, `TakeLast`, `Subscribe`.
|
`UniTaskAsyncEnumerable` is the entry point like `Enumerable`. In addition to the standard query operators, there are other generators for Unity such as `EveryUpdate`, `Timer`, `TimerFrame`, `Interval`, `IntervalFrame`, and `EveryValueChanged`. And also added additional UniTask original query operators like `Append`, `Prepend`, `DistinctUntilChanged`, `ToHashSet`, `Buffer`, `CombineLatest`,`Merge` `Do`, `Never`, `ForEachAsync`, `Pairwise`, `Publish`, `Queue`, `Return`, `SkipUntil`, `TakeUntil`, `SkipUntilCanceled`, `TakeUntilCanceled`, `TakeLast`, `Subscribe`.
|
||||||
|
|
||||||
The method with Func as an argument has three additional overloads, `***Await`, `***AwaitWithCancellation`.
|
The method with Func as an argument has three additional overloads, `***Await`, `***AwaitWithCancellation`.
|
||||||
|
|
||||||
@@ -1072,13 +1079,6 @@ or add `"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/
|
|||||||
|
|
||||||
If you want to set a target version, UniTask uses the `*.*.*` release tag so you can specify a version like `#2.1.0`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.1.0`.
|
If you want to set a target version, UniTask uses the `*.*.*` release tag so you can specify a version like `#2.1.0`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.1.0`.
|
||||||
|
|
||||||
### Install via OpenUPM
|
|
||||||
|
|
||||||
The package is available on the [openupm registry](https://openupm.com). It's recommended to install it via [openupm-cli](https://github.com/openupm/openupm-cli).
|
|
||||||
|
|
||||||
```
|
|
||||||
openupm add com.cysharp.unitask
|
|
||||||
```
|
|
||||||
|
|
||||||
.NET Core
|
.NET Core
|
||||||
---
|
---
|
||||||
@@ -1088,7 +1088,7 @@ For .NET Core, use NuGet.
|
|||||||
|
|
||||||
UniTask of .NET Core version is a subset of Unity UniTask with PlayerLoop dependent methods removed.
|
UniTask of .NET Core version is a subset of Unity UniTask with PlayerLoop dependent methods removed.
|
||||||
|
|
||||||
It runs at higher performance than the standard Task/ValueTask, but you should be careful to ignore the ExecutionContext/SynchronizationContext when using it. `AysncLocal` also does not work because it ignores ExecutionContext.
|
It runs at higher performance than the standard Task/ValueTask, but you should be careful to ignore the ExecutionContext/SynchronizationContext when using it. `AsyncLocal` also does not work because it ignores ExecutionContext.
|
||||||
|
|
||||||
If you use UniTask internally, but provide ValueTask as an external API, you can write it like the following(Inspired by [PooledAwait](https://github.com/mgravell/PooledAwait)).
|
If you use UniTask internally, but provide ValueTask as an external API, you can write it like the following(Inspired by [PooledAwait](https://github.com/mgravell/PooledAwait)).
|
||||||
|
|
||||||
|
|||||||
1134
README_CN.md
Normal file
1134
README_CN.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netcoreapp3.1;netstandard2.1;netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>net6.0;net7.0;netstandard2.1;netstandard2.0</TargetFrameworks>
|
||||||
<AssemblyName>UniTask</AssemblyName>
|
<AssemblyName>UniTask</AssemblyName>
|
||||||
<LangVersion>8.0</LangVersion>
|
<LangVersion>8.0</LangVersion>
|
||||||
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
|
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<PackageIcon>Icon.png</PackageIcon>
|
<PackageIcon>Icon.png</PackageIcon>
|
||||||
<SignAssembly>true</SignAssembly>
|
<SignAssembly>true</SignAssembly>
|
||||||
<AssemblyOriginatorKeyFile>opensource.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>opensource.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace NetCoreSandbox
|
|||||||
await FooAsync(10, cts.Token);
|
await FooAsync(10, cts.Token);
|
||||||
|
|
||||||
// NG(Compiler Error)
|
// NG(Compiler Error)
|
||||||
await FooAsync(10);
|
// await FooAsync(10);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<RootNamespace>NetCoreSandbox</RootNamespace>
|
<RootNamespace>NetCoreSandbox</RootNamespace>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -159,6 +159,30 @@ namespace NetCoreTests.Linq
|
|||||||
list.Should().Equal(100, 200, 300, 400);
|
list.Should().Equal(100, 200, 300, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AwaitForeachBreak()
|
||||||
|
{
|
||||||
|
var finallyCalled = false;
|
||||||
|
var enumerable = UniTaskAsyncEnumerable.Create<int>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await writer.YieldAsync(1);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
finallyCalled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await foreach (var x in enumerable)
|
||||||
|
{
|
||||||
|
x.Should().Be(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
finallyCalled.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
async IAsyncEnumerable<int> Range(int from, int count)
|
async IAsyncEnumerable<int> Range(int from, int count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
|||||||
137
src/UniTask.NetCoreTests/Linq/Merge.cs
Normal file
137
src/UniTask.NetCoreTests/Linq/Merge.cs
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Cysharp.Threading.Tasks.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace NetCoreTests.Linq
|
||||||
|
{
|
||||||
|
public class MergeTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task TwoSource()
|
||||||
|
{
|
||||||
|
var semaphore = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToThreadPool();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("A1");
|
||||||
|
semaphore.Release();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("A2");
|
||||||
|
semaphore.Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToThreadPool();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("B1");
|
||||||
|
await writer.YieldAsync("B2");
|
||||||
|
semaphore.Release();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("B3");
|
||||||
|
semaphore.Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
var result = await a.Merge(b).ToArrayAsync();
|
||||||
|
result.Should().Equal("A1", "B1", "B2", "A2", "B3");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ThreeSource()
|
||||||
|
{
|
||||||
|
var semaphore = new SemaphoreSlim(0, 1);
|
||||||
|
|
||||||
|
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToThreadPool();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("A1");
|
||||||
|
semaphore.Release();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("A2");
|
||||||
|
semaphore.Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToThreadPool();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("B1");
|
||||||
|
await writer.YieldAsync("B2");
|
||||||
|
semaphore.Release();
|
||||||
|
|
||||||
|
await semaphore.WaitAsync();
|
||||||
|
await writer.YieldAsync("B3");
|
||||||
|
semaphore.Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
var c = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToThreadPool();
|
||||||
|
|
||||||
|
await writer.YieldAsync("C1");
|
||||||
|
semaphore.Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
var result = await a.Merge(b, c).ToArrayAsync();
|
||||||
|
result.Should().Equal("C1", "A1", "B1", "B2", "A2", "B3");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Throw()
|
||||||
|
{
|
||||||
|
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await writer.YieldAsync("A1");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
throw new UniTaskTestException();
|
||||||
|
});
|
||||||
|
|
||||||
|
var enumerator = a.Merge(b).GetAsyncEnumerator();
|
||||||
|
(await enumerator.MoveNextAsync()).Should().Be(true);
|
||||||
|
enumerator.Current.Should().Be("A1");
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<UniTaskTestException>(async () => await enumerator.MoveNextAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Cancel()
|
||||||
|
{
|
||||||
|
var cts = new CancellationTokenSource();
|
||||||
|
|
||||||
|
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await writer.YieldAsync("A1");
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
|
||||||
|
{
|
||||||
|
await writer.YieldAsync("B1");
|
||||||
|
});
|
||||||
|
|
||||||
|
var enumerator = a.Merge(b).GetAsyncEnumerator(cts.Token);
|
||||||
|
(await enumerator.MoveNextAsync()).Should().Be(true);
|
||||||
|
enumerator.Current.Should().Be("A1");
|
||||||
|
|
||||||
|
cts.Cancel();
|
||||||
|
await Assert.ThrowsAsync<OperationCanceledException>(async () => await enumerator.MoveNextAsync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/UniTask.NetCoreTests/TaskExtensionsTest.cs
Normal file
43
src/UniTask.NetCoreTests/TaskExtensionsTest.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace NetCoreTests
|
||||||
|
{
|
||||||
|
public class TaskExtensionsTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task PropagateException()
|
||||||
|
{
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||||||
|
{
|
||||||
|
await ThrowAsync().AsUniTask();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||||||
|
{
|
||||||
|
await ThrowOrValueAsync().AsUniTask();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PropagateExceptionWhenAll()
|
||||||
|
{
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||||||
|
{
|
||||||
|
await Task.WhenAll(ThrowAsync(), ThrowAsync()).AsUniTask();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task ThrowAsync()
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<int> ThrowOrValueAsync()
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
|
|||||||
80
src/UniTask.NetCoreTests/UniTaskCompletionSourceTest.cs
Normal file
80
src/UniTask.NetCoreTests/UniTaskCompletionSourceTest.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NetCoreTests.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace NetCoreTests
|
||||||
|
{
|
||||||
|
public class AutoResetUniTaskCompletionSourceTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task SetResultAfterReturn()
|
||||||
|
{
|
||||||
|
var source1 = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
source1.TrySetResult();
|
||||||
|
await source1.Task;
|
||||||
|
|
||||||
|
source1.TrySetResult().Should().BeFalse();
|
||||||
|
|
||||||
|
var source2 = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
source2.TrySetResult();
|
||||||
|
await source2.Task;
|
||||||
|
|
||||||
|
source2.TrySetResult().Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SetCancelAfterReturn()
|
||||||
|
{
|
||||||
|
var source = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
source.TrySetResult();
|
||||||
|
await source.Task;
|
||||||
|
|
||||||
|
source.TrySetCanceled().Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SetExceptionAfterReturn()
|
||||||
|
{
|
||||||
|
var source = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
source.TrySetResult();
|
||||||
|
await source.Task;
|
||||||
|
|
||||||
|
source.TrySetException(new UniTaskTestException()).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SetResultWithValueAfterReturn()
|
||||||
|
{
|
||||||
|
var source1 = AutoResetUniTaskCompletionSource<int>.Create();
|
||||||
|
source1.TrySetResult(100);
|
||||||
|
(await source1.Task).Should().Be(100);
|
||||||
|
|
||||||
|
source1.TrySetResult(100).Should().BeFalse();
|
||||||
|
|
||||||
|
var source2 = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
source2.TrySetResult();
|
||||||
|
await source2.Task;
|
||||||
|
source2.TrySetResult().Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SetCancelWithValueAfterReturn()
|
||||||
|
{
|
||||||
|
var source = AutoResetUniTaskCompletionSource<int>.Create();
|
||||||
|
source.TrySetResult(100);
|
||||||
|
(await source.Task).Should().Be(100);
|
||||||
|
source.TrySetCanceled().Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SetExceptionWithValueAfterReturn()
|
||||||
|
{
|
||||||
|
var source = AutoResetUniTaskCompletionSource<int>.Create();
|
||||||
|
source.TrySetResult(100);
|
||||||
|
(await source.Task).Should().Be(100);
|
||||||
|
source.TrySetException(new UniTaskTestException()).Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,12 @@
|
|||||||
"name": "com.unity.addressables",
|
"name": "com.unity.addressables",
|
||||||
"expression": "",
|
"expression": "",
|
||||||
"define": "UNITASK_ADDRESSABLE_SUPPORT"
|
"define": "UNITASK_ADDRESSABLE_SUPPORT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "com.unity.addressables.cn",
|
||||||
|
"expression": "",
|
||||||
|
"define": "UNITASK_ADDRESSABLE_SUPPORT"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,22 +144,20 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly TweenCallback onCompleteCallbackDelegate;
|
readonly TweenCallback onCompleteCallbackDelegate;
|
||||||
readonly TweenCallback onUpdateDelegate;
|
|
||||||
|
|
||||||
Tween tween;
|
Tween tween;
|
||||||
TweenCancelBehaviour cancelBehaviour;
|
TweenCancelBehaviour cancelBehaviour;
|
||||||
CancellationToken cancellationToken;
|
CancellationToken cancellationToken;
|
||||||
|
CancellationTokenRegistration cancellationRegistration;
|
||||||
CallbackType callbackType;
|
CallbackType callbackType;
|
||||||
bool canceled;
|
bool canceled;
|
||||||
|
|
||||||
TweenCallback originalUpdateAction;
|
|
||||||
TweenCallback originalCompleteAction;
|
TweenCallback originalCompleteAction;
|
||||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||||
|
|
||||||
TweenConfiguredSource()
|
TweenConfiguredSource()
|
||||||
{
|
{
|
||||||
onCompleteCallbackDelegate = OnCompleteCallbackDelegate;
|
onCompleteCallbackDelegate = OnCompleteCallbackDelegate;
|
||||||
onUpdateDelegate = OnUpdate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token)
|
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token)
|
||||||
@@ -179,17 +177,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
result.cancelBehaviour = cancelBehaviour;
|
result.cancelBehaviour = cancelBehaviour;
|
||||||
result.cancellationToken = cancellationToken;
|
result.cancellationToken = cancellationToken;
|
||||||
result.callbackType = callbackType;
|
result.callbackType = callbackType;
|
||||||
|
|
||||||
result.originalUpdateAction = tween.onUpdate;
|
|
||||||
result.canceled = false;
|
result.canceled = false;
|
||||||
|
|
||||||
if (result.originalUpdateAction == result.onUpdateDelegate)
|
|
||||||
{
|
|
||||||
result.originalUpdateAction = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
tween.onUpdate = result.onUpdateDelegate;
|
|
||||||
|
|
||||||
switch (callbackType)
|
switch (callbackType)
|
||||||
{
|
{
|
||||||
case CallbackType.Kill:
|
case CallbackType.Kill:
|
||||||
@@ -225,6 +214,50 @@ namespace Cysharp.Threading.Tasks
|
|||||||
result.originalCompleteAction = null;
|
result.originalCompleteAction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cancellationToken.CanBeCanceled)
|
||||||
|
{
|
||||||
|
result.cancellationRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
|
||||||
|
{
|
||||||
|
var source = (TweenConfiguredSource)x;
|
||||||
|
switch (source.cancelBehaviour)
|
||||||
|
{
|
||||||
|
case TweenCancelBehaviour.Kill:
|
||||||
|
default:
|
||||||
|
source.tween.Kill(false);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.KillAndCancelAwait:
|
||||||
|
source.canceled = true;
|
||||||
|
source.tween.Kill(false);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.KillWithCompleteCallback:
|
||||||
|
source.tween.Kill(true);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
|
||||||
|
source.canceled = true;
|
||||||
|
source.tween.Kill(true);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.Complete:
|
||||||
|
source.tween.Complete(false);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.CompleteAndCancelAwait:
|
||||||
|
source.canceled = true;
|
||||||
|
source.tween.Complete(false);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.CompleteWithSequenceCallback:
|
||||||
|
source.tween.Complete(true);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
|
||||||
|
source.canceled = true;
|
||||||
|
source.tween.Complete(true);
|
||||||
|
break;
|
||||||
|
case TweenCancelBehaviour.CancelAwait:
|
||||||
|
source.RestoreOriginalCallback();
|
||||||
|
source.core.TrySetCanceled(source.cancellationToken);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, result);
|
||||||
|
}
|
||||||
|
|
||||||
TaskTracker.TrackActiveTask(result, 3);
|
TaskTracker.TrackActiveTask(result, 3);
|
||||||
|
|
||||||
token = result.core.Version;
|
token = result.core.Version;
|
||||||
@@ -255,77 +288,6 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.CompleteWithSequenceCallback:
|
|
||||||
this.tween.Complete(true);
|
|
||||||
break;
|
|
||||||
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
|
|
||||||
this.canceled = true;
|
|
||||||
this.tween.Complete(true);
|
|
||||||
break;
|
|
||||||
case TweenCancelBehaviour.CancelAwait:
|
|
||||||
// restore to original callback
|
|
||||||
switch (callbackType)
|
|
||||||
{
|
|
||||||
case CallbackType.Kill:
|
|
||||||
tween.onKill = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
case CallbackType.Complete:
|
|
||||||
tween.onComplete = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
case CallbackType.Pause:
|
|
||||||
tween.onPause = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
case CallbackType.Play:
|
|
||||||
tween.onPlay = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
case CallbackType.Rewind:
|
|
||||||
tween.onRewind = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
case CallbackType.StepComplete:
|
|
||||||
tween.onStepComplete = originalCompleteAction;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.core.TrySetCanceled(this.cancellationToken);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour)
|
static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -392,8 +354,18 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
TaskTracker.RemoveTracking(this);
|
TaskTracker.RemoveTracking(this);
|
||||||
core.Reset();
|
core.Reset();
|
||||||
tween.onUpdate = originalUpdateAction;
|
cancellationRegistration.Dispose();
|
||||||
|
|
||||||
|
RestoreOriginalCallback();
|
||||||
|
|
||||||
|
tween = default;
|
||||||
|
cancellationToken = default;
|
||||||
|
originalCompleteAction = default;
|
||||||
|
return pool.TryPush(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestoreOriginalCallback()
|
||||||
|
{
|
||||||
switch (callbackType)
|
switch (callbackType)
|
||||||
{
|
{
|
||||||
case CallbackType.Kill:
|
case CallbackType.Kill:
|
||||||
@@ -417,12 +389,6 @@ namespace Cysharp.Threading.Tasks
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tween = default;
|
|
||||||
cancellationToken = default;
|
|
||||||
originalUpdateAction = default;
|
|
||||||
originalCompleteAction = default;
|
|
||||||
return pool.TryPush(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static void ThrowArgumentException<T>(string message)
|
public static void ThrowArgumentException(string message)
|
||||||
{
|
{
|
||||||
throw new ArgumentException(message);
|
throw new ArgumentException(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
TaskTracker.RemoveTracking(this);
|
TaskTracker.RemoveTracking(this);
|
||||||
|
writer.Dispose();
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class AsyncWriter : IUniTaskSource, IAsyncWriter<T>
|
sealed class AsyncWriter : IUniTaskSource, IAsyncWriter<T>, IDisposable
|
||||||
{
|
{
|
||||||
readonly _Create enumerator;
|
readonly _Create enumerator;
|
||||||
|
|
||||||
@@ -137,6 +138,15 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
{
|
{
|
||||||
this.enumerator = enumerator;
|
this.enumerator = enumerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
var status = core.GetStatus(core.Version);
|
||||||
|
if (status == UniTaskStatus.Pending)
|
||||||
|
{
|
||||||
|
core.TrySetCanceled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void GetResult(short token)
|
public void GetResult(short token)
|
||||||
{
|
{
|
||||||
|
|||||||
232
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/Merge.cs
Normal file
232
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/Merge.cs
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using Cysharp.Threading.Tasks.Internal;
|
||||||
|
|
||||||
|
namespace Cysharp.Threading.Tasks.Linq
|
||||||
|
{
|
||||||
|
public static partial class UniTaskAsyncEnumerable
|
||||||
|
{
|
||||||
|
public static IUniTaskAsyncEnumerable<T> Merge<T>(this IUniTaskAsyncEnumerable<T> first, IUniTaskAsyncEnumerable<T> second)
|
||||||
|
{
|
||||||
|
Error.ThrowArgumentNullException(first, nameof(first));
|
||||||
|
Error.ThrowArgumentNullException(second, nameof(second));
|
||||||
|
|
||||||
|
return new Merge<T>(new [] { first, second });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskAsyncEnumerable<T> Merge<T>(this IUniTaskAsyncEnumerable<T> first, IUniTaskAsyncEnumerable<T> second, IUniTaskAsyncEnumerable<T> third)
|
||||||
|
{
|
||||||
|
Error.ThrowArgumentNullException(first, nameof(first));
|
||||||
|
Error.ThrowArgumentNullException(second, nameof(second));
|
||||||
|
Error.ThrowArgumentNullException(third, nameof(third));
|
||||||
|
|
||||||
|
return new Merge<T>(new[] { first, second, third });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskAsyncEnumerable<T> Merge<T>(this IEnumerable<IUniTaskAsyncEnumerable<T>> sources)
|
||||||
|
{
|
||||||
|
return new Merge<T>(sources.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskAsyncEnumerable<T> Merge<T>(params IUniTaskAsyncEnumerable<T>[] sources)
|
||||||
|
{
|
||||||
|
return new Merge<T>(sources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Merge<T> : IUniTaskAsyncEnumerable<T>
|
||||||
|
{
|
||||||
|
readonly IUniTaskAsyncEnumerable<T>[] sources;
|
||||||
|
|
||||||
|
public Merge(IUniTaskAsyncEnumerable<T>[] sources)
|
||||||
|
{
|
||||||
|
if (sources.Length <= 0)
|
||||||
|
{
|
||||||
|
Error.ThrowArgumentException("No source async enumerable to merge");
|
||||||
|
}
|
||||||
|
this.sources = sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||||
|
=> new _Merge(sources, cancellationToken);
|
||||||
|
|
||||||
|
enum MergeSourceState
|
||||||
|
{
|
||||||
|
Pending,
|
||||||
|
Running,
|
||||||
|
Completed,
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class _Merge : MoveNextSource, IUniTaskAsyncEnumerator<T>
|
||||||
|
{
|
||||||
|
static readonly Action<object> GetResultAtAction = GetResultAt;
|
||||||
|
|
||||||
|
readonly int length;
|
||||||
|
readonly IUniTaskAsyncEnumerator<T>[] enumerators;
|
||||||
|
readonly MergeSourceState[] states;
|
||||||
|
readonly Queue<(T, Exception, bool)> queuedResult = new Queue<(T, Exception, bool)>();
|
||||||
|
readonly CancellationToken cancellationToken;
|
||||||
|
|
||||||
|
int moveNextCompleted;
|
||||||
|
|
||||||
|
public T Current { get; private set; }
|
||||||
|
|
||||||
|
public _Merge(IUniTaskAsyncEnumerable<T>[] sources, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
this.cancellationToken = cancellationToken;
|
||||||
|
length = sources.Length;
|
||||||
|
states = ArrayPool<MergeSourceState>.Shared.Rent(length);
|
||||||
|
enumerators = ArrayPool<IUniTaskAsyncEnumerator<T>>.Shared.Rent(length);
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
enumerators[i] = sources[i].GetAsyncEnumerator(cancellationToken);
|
||||||
|
states[i] = (int)MergeSourceState.Pending;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTask<bool> MoveNextAsync()
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
completionSource.Reset();
|
||||||
|
Interlocked.Exchange(ref moveNextCompleted, 0);
|
||||||
|
|
||||||
|
if (HasQueuedResult() && Interlocked.CompareExchange(ref moveNextCompleted, 1, 0) == 0)
|
||||||
|
{
|
||||||
|
(T, Exception, bool) value;
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
value = queuedResult.Dequeue();
|
||||||
|
}
|
||||||
|
var resultValue = value.Item1;
|
||||||
|
var exception = value.Item2;
|
||||||
|
var hasNext = value.Item3;
|
||||||
|
if (exception != null)
|
||||||
|
{
|
||||||
|
completionSource.TrySetException(exception);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Current = resultValue;
|
||||||
|
completionSource.TrySetResult(hasNext);
|
||||||
|
}
|
||||||
|
return new UniTask<bool>(this, completionSource.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
if (states[i] == MergeSourceState.Pending)
|
||||||
|
{
|
||||||
|
states[i] = MergeSourceState.Running;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var awaiter = enumerators[i].MoveNextAsync().GetAwaiter();
|
||||||
|
if (awaiter.IsCompleted)
|
||||||
|
{
|
||||||
|
GetResultAt(i, awaiter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
awaiter.SourceOnCompleted(GetResultAtAction, StateTuple.Create(this, i, awaiter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new UniTask<bool>(this, completionSource.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTask DisposeAsync()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
await enumerators[i].DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayPool<MergeSourceState>.Shared.Return(states, true);
|
||||||
|
ArrayPool<IUniTaskAsyncEnumerator<T>>.Shared.Return(enumerators, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetResultAt(object state)
|
||||||
|
{
|
||||||
|
using (var tuple = (StateTuple<_Merge, int, UniTask<bool>.Awaiter>)state)
|
||||||
|
{
|
||||||
|
tuple.Item1.GetResultAt(tuple.Item2, tuple.Item3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetResultAt(int index, UniTask<bool>.Awaiter awaiter)
|
||||||
|
{
|
||||||
|
bool hasNext;
|
||||||
|
bool completedAll;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hasNext = awaiter.GetResult();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (Interlocked.CompareExchange(ref moveNextCompleted, 1, 0) == 0)
|
||||||
|
{
|
||||||
|
completionSource.TrySetException(ex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
queuedResult.Enqueue((default, ex, default));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
states[index] = hasNext ? MergeSourceState.Pending : MergeSourceState.Completed;
|
||||||
|
completedAll = !hasNext && IsCompletedAll();
|
||||||
|
}
|
||||||
|
if (hasNext || completedAll)
|
||||||
|
{
|
||||||
|
if (Interlocked.CompareExchange(ref moveNextCompleted, 1, 0) == 0)
|
||||||
|
{
|
||||||
|
Current = enumerators[index].Current;
|
||||||
|
completionSource.TrySetResult(!completedAll);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
queuedResult.Enqueue((enumerators[index].Current, null, !completedAll));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasQueuedResult()
|
||||||
|
{
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
return queuedResult.Count > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCompletedAll()
|
||||||
|
{
|
||||||
|
lock (states)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if (states[i] != MergeSourceState.Completed)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ca56812f160c45d0bacb4339819edf1a
|
||||||
|
timeCreated: 1694133666
|
||||||
@@ -285,7 +285,11 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return dest.ToArray();
|
return dest.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
#if UNITY_2020_1_OR_NEWER
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||||||
|
#else
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||||
|
#endif
|
||||||
static void Init()
|
static void Init()
|
||||||
{
|
{
|
||||||
// capture default(unity) sync-context.
|
// capture default(unity) sync-context.
|
||||||
@@ -524,6 +528,14 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
sb.AppendFormat("------{0}------", header.type.Name);
|
sb.AppendFormat("------{0}------", header.type.Name);
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
|
if (header.subSystemList is null)
|
||||||
|
{
|
||||||
|
sb.AppendFormat("{0} has no subsystems!", header.ToString());
|
||||||
|
sb.AppendLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var subSystem in header.subSystemList)
|
foreach (var subSystem in header.subSystemList)
|
||||||
{
|
{
|
||||||
sb.AppendFormat("{0}", subSystem.type.Name);
|
sb.AppendFormat("{0}", subSystem.type.Name);
|
||||||
@@ -545,6 +557,11 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
foreach (var header in playerLoop.subSystemList)
|
foreach (var header in playerLoop.subSystemList)
|
||||||
{
|
{
|
||||||
|
if (header.subSystemList is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var subSystem in header.subSystemList)
|
foreach (var subSystem in header.subSystemList)
|
||||||
{
|
{
|
||||||
if (subSystem.type == typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization))
|
if (subSystem.type == typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace Cysharp.Threading.Tasks
|
namespace Cysharp.Threading.Tasks
|
||||||
{
|
{
|
||||||
// internaly used but public, allow to user create custom operator with pooling.
|
// internally used but public, allow to user create custom operator with pooling.
|
||||||
|
|
||||||
public static class TaskPool
|
public static class TaskPool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
timer.Stop();
|
timer?.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -109,7 +109,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// stop timer.
|
// stop timer.
|
||||||
timer.Dispose();
|
timer?.Dispose();
|
||||||
|
|
||||||
// cancel and dispose.
|
// cancel and dispose.
|
||||||
timeoutSource.Cancel();
|
timeoutSource.Cancel();
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
ITriggerHandler<T> head; // head.prev is last
|
ITriggerHandler<T> head; // head.prev is last
|
||||||
ITriggerHandler<T> iteratingHead;
|
ITriggerHandler<T> iteratingHead;
|
||||||
|
|
||||||
bool preserveRemoveSelf;
|
|
||||||
ITriggerHandler<T> iteratingNode;
|
ITriggerHandler<T> iteratingNode;
|
||||||
|
|
||||||
void LogError(Exception ex)
|
void LogError(Exception ex)
|
||||||
@@ -55,18 +53,9 @@ namespace Cysharp.Threading.Tasks
|
|||||||
Remove(h);
|
Remove(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preserveRemoveSelf)
|
// If `h` itself is removed by OnNext, h.Next is null.
|
||||||
{
|
// Therefore, instead of looking at h.Next, the `iteratingNode` reference itself is replaced.
|
||||||
preserveRemoveSelf = false;
|
h = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
|
||||||
h = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h = h.Next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
@@ -97,9 +86,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
@@ -132,9 +120,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
@@ -167,9 +154,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
@@ -241,71 +227,65 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
||||||
|
|
||||||
if (iteratingNode != null && iteratingNode == handler)
|
var prev = handler.Prev;
|
||||||
|
var next = handler.Next;
|
||||||
|
|
||||||
|
if (next != null)
|
||||||
{
|
{
|
||||||
// if remove self, reserve remove self after invoke completed.
|
next.Prev = prev;
|
||||||
preserveRemoveSelf = true;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (handler == head)
|
||||||
{
|
{
|
||||||
var prev = handler.Prev;
|
head = next;
|
||||||
var next = handler.Next;
|
|
||||||
|
|
||||||
if (next != null)
|
|
||||||
{
|
|
||||||
next.Prev = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler == head)
|
|
||||||
{
|
|
||||||
head = next;
|
|
||||||
}
|
|
||||||
else if (handler == iteratingHead)
|
|
||||||
{
|
|
||||||
iteratingHead = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// when handler is head, prev indicate last so don't use it.
|
|
||||||
if (prev != null)
|
|
||||||
{
|
|
||||||
prev.Next = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (head != null)
|
|
||||||
{
|
|
||||||
if (head.Prev == handler)
|
|
||||||
{
|
|
||||||
if (prev != head)
|
|
||||||
{
|
|
||||||
head.Prev = prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
head.Prev = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iteratingHead != null)
|
|
||||||
{
|
|
||||||
if (iteratingHead.Prev == handler)
|
|
||||||
{
|
|
||||||
if (prev != iteratingHead.Prev)
|
|
||||||
{
|
|
||||||
iteratingHead.Prev = prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iteratingHead.Prev = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.Prev = null;
|
|
||||||
handler.Next = null;
|
|
||||||
}
|
}
|
||||||
|
// when handler is head, prev indicate last so don't use it.
|
||||||
|
else if (prev != null)
|
||||||
|
{
|
||||||
|
prev.Next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler == iteratingNode)
|
||||||
|
{
|
||||||
|
iteratingNode = next;
|
||||||
|
}
|
||||||
|
if (handler == iteratingHead)
|
||||||
|
{
|
||||||
|
iteratingHead = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head != null)
|
||||||
|
{
|
||||||
|
if (head.Prev == handler)
|
||||||
|
{
|
||||||
|
if (prev != head)
|
||||||
|
{
|
||||||
|
head.Prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.Prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iteratingHead != null)
|
||||||
|
{
|
||||||
|
if (iteratingHead.Prev == handler)
|
||||||
|
{
|
||||||
|
if (prev != iteratingHead.Prev)
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Prev = null;
|
||||||
|
handler.Next = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,11 @@ namespace Cysharp.Threading.Tasks.Triggers
|
|||||||
if (cancellationTokenSource == null)
|
if (cancellationTokenSource == null)
|
||||||
{
|
{
|
||||||
cancellationTokenSource = new CancellationTokenSource();
|
cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
if (!awakeCalled)
|
||||||
|
{
|
||||||
|
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!awakeCalled)
|
|
||||||
{
|
|
||||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, new AwakeMonitor(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cancellationTokenSource.Token;
|
return cancellationTokenSource.Token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +81,7 @@ namespace Cysharp.Threading.Tasks.Triggers
|
|||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
if (trigger.called) return false;
|
if (trigger.called || trigger.awakeCalled) return false;
|
||||||
if (trigger == null)
|
if (trigger == null)
|
||||||
{
|
{
|
||||||
trigger.OnDestroy();
|
trigger.OnDestroy();
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
public static class UniTaskCancellationExtensions
|
public static class UniTaskCancellationExtensions
|
||||||
{
|
{
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
|
||||||
|
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
|
||||||
|
public static CancellationToken GetCancellationTokenOnDestroy(this MonoBehaviour monoBehaviour)
|
||||||
|
{
|
||||||
|
return monoBehaviour.destroyCancellationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
|
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
|
||||||
public static CancellationToken GetCancellationTokenOnDestroy(this GameObject gameObject)
|
public static CancellationToken GetCancellationTokenOnDestroy(this GameObject gameObject)
|
||||||
{
|
{
|
||||||
@@ -17,6 +27,13 @@ namespace Cysharp.Threading.Tasks
|
|||||||
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
|
/// <summary>This CancellationToken is canceled when the MonoBehaviour will be destroyed.</summary>
|
||||||
public static CancellationToken GetCancellationTokenOnDestroy(this Component component)
|
public static CancellationToken GetCancellationTokenOnDestroy(this Component component)
|
||||||
{
|
{
|
||||||
|
#if UNITY_2022_2_OR_NEWER
|
||||||
|
if (component is MonoBehaviour mb)
|
||||||
|
{
|
||||||
|
return mb.destroyCancellationToken;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return component.GetAsyncDestroyTrigger().CancellationToken;
|
return component.GetAsyncDestroyTrigger().CancellationToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
|
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
public static async UniTask WaitForEndOfFrame(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await Awaitable.EndOfFrameAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
#else
|
||||||
[Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")]
|
[Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")]
|
||||||
public static YieldAwaitable WaitForEndOfFrame()
|
public static YieldAwaitable WaitForEndOfFrame()
|
||||||
{
|
{
|
||||||
@@ -86,6 +92,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
|
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default)
|
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
@@ -94,22 +101,34 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Same as UniTask.Yield(PlayerLoopTiming.FixedUpdate).
|
/// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static YieldAwaitable WaitForFixedUpdate()
|
public static YieldAwaitable WaitForFixedUpdate()
|
||||||
{
|
{
|
||||||
return UniTask.Yield(PlayerLoopTiming.FixedUpdate);
|
// use LastFixedUpdate instead of FixedUpdate
|
||||||
|
// https://github.com/Cysharp/UniTask/issues/377
|
||||||
|
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Same as UniTask.Yield(PlayerLoopTiming.FixedUpdate, cancellationToken).
|
/// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken)
|
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return UniTask.Yield(PlayerLoopTiming.FixedUpdate, cancellationToken);
|
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
if (delayFrameCount < 0)
|
if (delayFrameCount < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
||||||
{
|
{
|
||||||
continuation(continuationState);
|
continuation(continuationState);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -165,8 +165,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
||||||
{
|
{
|
||||||
continuation(continuationState);
|
continuation(continuationState);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -184,8 +184,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null)
|
||||||
{
|
{
|
||||||
continuation(continuationState);
|
continuation(continuationState);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -328,6 +328,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||||
|
short version;
|
||||||
|
|
||||||
AutoResetUniTaskCompletionSource()
|
AutoResetUniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
@@ -340,6 +341,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
result = new AutoResetUniTaskCompletionSource();
|
result = new AutoResetUniTaskCompletionSource();
|
||||||
}
|
}
|
||||||
|
result.version = result.core.Version;
|
||||||
TaskTracker.TrackActiveTask(result, 2);
|
TaskTracker.TrackActiveTask(result, 2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -383,19 +385,19 @@ namespace Cysharp.Threading.Tasks
|
|||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetResult()
|
public bool TrySetResult()
|
||||||
{
|
{
|
||||||
return core.TrySetResult(AsyncUnit.Default);
|
return version == core.Version && core.TrySetResult(AsyncUnit.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetCanceled(CancellationToken cancellationToken = default)
|
public bool TrySetCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return core.TrySetCanceled(cancellationToken);
|
return version == core.Version && core.TrySetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetException(Exception exception)
|
public bool TrySetException(Exception exception)
|
||||||
{
|
{
|
||||||
return core.TrySetException(exception);
|
return version == core.Version && core.TrySetException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
@@ -409,7 +411,6 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
TryReturn();
|
TryReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
@@ -451,6 +452,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
UniTaskCompletionSourceCore<T> core;
|
UniTaskCompletionSourceCore<T> core;
|
||||||
|
short version;
|
||||||
|
|
||||||
AutoResetUniTaskCompletionSource()
|
AutoResetUniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
@@ -463,6 +465,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
result = new AutoResetUniTaskCompletionSource<T>();
|
result = new AutoResetUniTaskCompletionSource<T>();
|
||||||
}
|
}
|
||||||
|
result.version = result.core.Version;
|
||||||
TaskTracker.TrackActiveTask(result, 2);
|
TaskTracker.TrackActiveTask(result, 2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -506,19 +509,19 @@ namespace Cysharp.Threading.Tasks
|
|||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetResult(T result)
|
public bool TrySetResult(T result)
|
||||||
{
|
{
|
||||||
return core.TrySetResult(result);
|
return version == core.Version && core.TrySetResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetCanceled(CancellationToken cancellationToken = default)
|
public bool TrySetCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return core.TrySetCanceled(cancellationToken);
|
return version == core.Version && core.TrySetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public bool TrySetException(Exception exception)
|
public bool TrySetException(Exception exception)
|
||||||
{
|
{
|
||||||
return core.TrySetException(exception);
|
return version == core.Version && core.TrySetException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
@@ -937,5 +940,5 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
p.TrySetCanceled();
|
p.TrySetCanceled();
|
||||||
break;
|
break;
|
||||||
case TaskStatus.Faulted:
|
case TaskStatus.Faulted:
|
||||||
p.TrySetException(x.Exception);
|
p.TrySetException(x.Exception.InnerException ?? x.Exception);
|
||||||
break;
|
break;
|
||||||
case TaskStatus.RanToCompletion:
|
case TaskStatus.RanToCompletion:
|
||||||
p.TrySetResult(x.Result);
|
p.TrySetResult(x.Result);
|
||||||
@@ -58,7 +58,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
p.TrySetCanceled();
|
p.TrySetCanceled();
|
||||||
break;
|
break;
|
||||||
case TaskStatus.Faulted:
|
case TaskStatus.Faulted:
|
||||||
p.TrySetException(x.Exception);
|
p.TrySetException(x.Exception.InnerException ?? x.Exception);
|
||||||
break;
|
break;
|
||||||
case TaskStatus.RanToCompletion:
|
case TaskStatus.RanToCompletion:
|
||||||
p.TrySetResult();
|
p.TrySetResult();
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
var self = (ToUniTaskObserver<T>)state;
|
var self = (ToUniTaskObserver<T>)state;
|
||||||
self.disposable.Dispose();
|
self.disposable.Dispose();
|
||||||
self.promise.TrySetCanceled();
|
self.promise.TrySetCanceled(self.cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnNext(T value)
|
public void OnNext(T value)
|
||||||
@@ -203,7 +203,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
var self = (FirstValueToUniTaskObserver<T>)state;
|
var self = (FirstValueToUniTaskObserver<T>)state;
|
||||||
self.disposable.Dispose();
|
self.disposable.Dispose();
|
||||||
self.promise.TrySetCanceled();
|
self.promise.TrySetCanceled(self.cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnNext(T value)
|
public void OnNext(T value)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken)
|
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return AwaitForAllAssets(asyncOperation, cancellationToken: cancellationToken);
|
return AwaitForAllAssets(asyncOperation, null, PlayerLoopTiming.Update, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
|||||||
@@ -15,11 +15,15 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
#region AsyncOperation
|
#region AsyncOperation
|
||||||
|
|
||||||
|
#if !UNITY_2023_1_OR_NEWER
|
||||||
|
// from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine.
|
||||||
|
|
||||||
public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation)
|
public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation)
|
||||||
{
|
{
|
||||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||||
return new AsyncOperationAwaiter(asyncOperation);
|
return new AsyncOperationAwaiter(asyncOperation);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken)
|
public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@@ -896,7 +900,11 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
if (asyncOperation.isDone)
|
if (asyncOperation.isDone)
|
||||||
{
|
{
|
||||||
if (asyncOperation.webRequest.IsError())
|
if (asyncOperation.webRequest == null)
|
||||||
|
{
|
||||||
|
core.TrySetException(new ObjectDisposedException("The webRequest has been destroyed."));
|
||||||
|
}
|
||||||
|
else if (asyncOperation.webRequest.IsError())
|
||||||
{
|
{
|
||||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
if (cancellationToken2.CanBeCanceled)
|
if (cancellationToken2.CanBeCanceled)
|
||||||
{
|
{
|
||||||
registration2 = cancellationToken1.RegisterWithoutCaptureExecutionContext(cancel2, this);
|
registration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(cancel2, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,13 +688,27 @@ namespace Cysharp.Threading.Tasks
|
|||||||
static void OnCanceled1(object state)
|
static void OnCanceled1(object state)
|
||||||
{
|
{
|
||||||
var self = (UnityEventHandlerAsyncEnumerator)state;
|
var self = (UnityEventHandlerAsyncEnumerator)state;
|
||||||
self.DisposeAsync().Forget();
|
try
|
||||||
|
{
|
||||||
|
self.completionSource.TrySetCanceled(self.cancellationToken1);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
self.DisposeAsync().Forget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnCanceled2(object state)
|
static void OnCanceled2(object state)
|
||||||
{
|
{
|
||||||
var self = (UnityEventHandlerAsyncEnumerator)state;
|
var self = (UnityEventHandlerAsyncEnumerator)state;
|
||||||
self.DisposeAsync().Forget();
|
try
|
||||||
|
{
|
||||||
|
self.completionSource.TrySetCanceled(self.cancellationToken2);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
self.DisposeAsync().Forget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
@@ -706,6 +720,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
registration1.Dispose();
|
registration1.Dispose();
|
||||||
registration2.Dispose();
|
registration2.Dispose();
|
||||||
unityEvent.RemoveListener(unityAction);
|
unityEvent.RemoveListener(unityAction);
|
||||||
|
|
||||||
|
completionSource.TrySetCanceled();
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
@@ -777,7 +793,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
if (cancellationToken2.CanBeCanceled)
|
if (cancellationToken2.CanBeCanceled)
|
||||||
{
|
{
|
||||||
registration2 = cancellationToken1.RegisterWithoutCaptureExecutionContext(cancel2, this);
|
registration2 = cancellationToken2.RegisterWithoutCaptureExecutionContext(cancel2, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,13 +809,27 @@ namespace Cysharp.Threading.Tasks
|
|||||||
static void OnCanceled1(object state)
|
static void OnCanceled1(object state)
|
||||||
{
|
{
|
||||||
var self = (UnityEventHandlerAsyncEnumerator)state;
|
var self = (UnityEventHandlerAsyncEnumerator)state;
|
||||||
self.DisposeAsync().Forget();
|
try
|
||||||
|
{
|
||||||
|
self.completionSource.TrySetCanceled(self.cancellationToken1);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
self.DisposeAsync().Forget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnCanceled2(object state)
|
static void OnCanceled2(object state)
|
||||||
{
|
{
|
||||||
var self = (UnityEventHandlerAsyncEnumerator)state;
|
var self = (UnityEventHandlerAsyncEnumerator)state;
|
||||||
self.DisposeAsync().Forget();
|
try
|
||||||
|
{
|
||||||
|
self.completionSource.TrySetCanceled(self.cancellationToken2);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
self.DisposeAsync().Forget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
@@ -815,6 +845,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
disp.Dispose();
|
disp.Dispose();
|
||||||
}
|
}
|
||||||
unityEvent.RemoveListener(unityAction);
|
unityEvent.RemoveListener(unityAction);
|
||||||
|
|
||||||
|
completionSource.TrySetCanceled();
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
|
|||||||
@@ -12,17 +12,17 @@ namespace Cysharp.Threading.Tasks
|
|||||||
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT
|
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT
|
||||||
// <string> -> Text
|
// <string> -> Text
|
||||||
|
|
||||||
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, Text text, bool rebindOnError = true)
|
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, bool rebindOnError = true)
|
||||||
{
|
{
|
||||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
||||||
{
|
{
|
||||||
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<string> source, Text text, CancellationToken cancellationToken, bool rebindOnError)
|
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<string> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError)
|
||||||
{
|
{
|
||||||
var repeat = false;
|
var repeat = false;
|
||||||
BIND_AGAIN:
|
BIND_AGAIN:
|
||||||
@@ -68,22 +68,22 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
// <T> -> Text
|
// <T> -> Text
|
||||||
|
|
||||||
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, Text text, bool rebindOnError = true)
|
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, bool rebindOnError = true)
|
||||||
{
|
{
|
||||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError = true)
|
||||||
{
|
{
|
||||||
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BindTo<T>(this AsyncReactiveProperty<T> source, Text text, bool rebindOnError = true)
|
public static void BindTo<T>(this AsyncReactiveProperty<T> source, UnityEngine.UI.Text text, bool rebindOnError = true)
|
||||||
{
|
{
|
||||||
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async UniTaskVoid BindToCore<T>(IUniTaskAsyncEnumerable<T> source, Text text, CancellationToken cancellationToken, bool rebindOnError)
|
static async UniTaskVoid BindToCore<T>(IUniTaskAsyncEnumerable<T> source, UnityEngine.UI.Text text, CancellationToken cancellationToken, bool rebindOnError)
|
||||||
{
|
{
|
||||||
var repeat = false;
|
var repeat = false;
|
||||||
BIND_AGAIN:
|
BIND_AGAIN:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -49,7 +49,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
{
|
{
|
||||||
if (msg == null)
|
if (msg == null)
|
||||||
{
|
{
|
||||||
if (Text != null)
|
if(!string.IsNullOrWhiteSpace(Text))
|
||||||
{
|
{
|
||||||
msg = Error + Environment.NewLine + Text;
|
msg = Error + Environment.NewLine + Text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "com.cysharp.unitask",
|
"name": "com.cysharp.unitask",
|
||||||
"displayName": "UniTask",
|
"displayName": "UniTask",
|
||||||
"author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" },
|
"author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" },
|
||||||
"version": "2.3.0",
|
"version": "2.4.1",
|
||||||
"unity": "2018.4",
|
"unity": "2018.4",
|
||||||
"description": "Provides an efficient async/await integration to Unity.",
|
"description": "Provides an efficient async/await integration to Unity.",
|
||||||
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
||||||
|
|||||||
@@ -310,33 +310,33 @@ namespace Cysharp.Threading.TasksTests
|
|||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnityTest]
|
//[UnityTest]
|
||||||
public IEnumerator ExceptionUnobserved1() => UniTask.ToCoroutine(async () =>
|
//public IEnumerator ExceptionUnobserved1() => UniTask.ToCoroutine(async () =>
|
||||||
{
|
//{
|
||||||
bool calledEx = false;
|
// bool calledEx = false;
|
||||||
Action<Exception> action = exx =>
|
// Action<Exception> action = exx =>
|
||||||
{
|
// {
|
||||||
calledEx = true;
|
// calledEx = true;
|
||||||
exx.Message.Should().Be("MyException");
|
// exx.Message.Should().Be("MyException");
|
||||||
};
|
// };
|
||||||
|
|
||||||
UniTaskScheduler.UnobservedTaskException += action;
|
// UniTaskScheduler.UnobservedTaskException += action;
|
||||||
|
|
||||||
var ex = InException1();
|
// var ex = InException1();
|
||||||
ex = default(UniTask);
|
// ex = default(UniTask);
|
||||||
|
|
||||||
await UniTask.DelayFrame(3);
|
// await UniTask.DelayFrame(3);
|
||||||
|
|
||||||
GC.Collect();
|
// GC.Collect();
|
||||||
GC.WaitForPendingFinalizers();
|
// GC.WaitForPendingFinalizers();
|
||||||
GC.Collect();
|
// GC.Collect();
|
||||||
|
|
||||||
await UniTask.DelayFrame(1);
|
// await UniTask.DelayFrame(1);
|
||||||
|
|
||||||
calledEx.Should().BeTrue();
|
// calledEx.Should().BeTrue();
|
||||||
|
|
||||||
UniTaskScheduler.UnobservedTaskException -= action;
|
// UniTaskScheduler.UnobservedTaskException -= action;
|
||||||
});
|
//});
|
||||||
|
|
||||||
[UnityTest]
|
[UnityTest]
|
||||||
public IEnumerator ExceptionUnobserved2() => UniTask.ToCoroutine(async () =>
|
public IEnumerator ExceptionUnobserved2() => UniTask.ToCoroutine(async () =>
|
||||||
|
|||||||
Reference in New Issue
Block a user