Compare commits

..

1 Commits

Author SHA1 Message Date
neuecc
936b224b2b WIP reuse and cancellation 2024-10-25 11:51:55 +09:00
31 changed files with 600 additions and 668 deletions

View File

@@ -1,13 +0,0 @@
{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.78.3",
"commands": [
"docfx"
],
"rollForward": false
}
}
}

View File

@@ -1,41 +0,0 @@
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
# Visual Studio Spell checker configs (https://learn.microsoft.com/en-us/visualstudio/ide/text-spell-checker?view=vs-2022#how-to-customize-the-spell-checker)
spelling_exclusion_path = ./exclusion.dic
[*.cs]
indent_size = 4
charset = utf-8-bom
end_of_line = unset
# Solution files
[*.{sln,slnx}]
end_of_line = unset
# MSBuild project files
[*.{csproj,props,targets}]
end_of_line = unset
# Xml config files
[*.{ruleset,config,nuspec,resx,runsettings,DotSettings}]
end_of_line = unset
[*{_AssemblyInfo.cs,.notsupported.cs}]
generated_code = true
# C# code style settings
[*.{cs}]
dotnet_diagnostic.IDE0044.severity = none # IDE0044: Make field readonly
# https://stackoverflow.com/questions/79195382/how-to-disable-fading-unused-methods-in-visual-studio-2022-17-12-0
dotnet_diagnostic.IDE0051.severity = none # IDE0051: Remove unused private member
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure

View File

@@ -5,14 +5,3 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "weekly" # Check for updates to GitHub Actions every week interval: "weekly" # Check for updates to GitHub Actions every week
groups:
dependencies:
patterns:
- "*"
cooldown:
default-days: 14 # Wait 14 days before creating another PR for the same dependency. This will prevent vulnerability on the package impact.
ignore:
# I just want update action when major/minor version is updated. patch updates are too noisy.
- dependency-name: "*"
update-types:
- version-update:semver-patch

View File

@@ -10,16 +10,13 @@ on:
jobs: jobs:
build-dotnet: build-dotnet:
permissions: runs-on: ubuntu-latest
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- uses: Cysharp/Actions/.github/actions/checkout@main - uses: actions/checkout@v4
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main - uses: Cysharp/Actions/.github/actions/setup-dotnet@main
- run: dotnet build -c Release - run: dotnet build -c Debug
- run: dotnet test -c Release - run: dotnet test -c Debug
- run: dotnet pack -c Release --no-build -p:IncludeSymbols=true -o $GITHUB_WORKSPACE/artifacts
build-unity: build-unity:
if: ${{ ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:')) && github.triggering_actor != 'dependabot[bot]' }} if: ${{ ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:')) && github.triggering_actor != 'dependabot[bot]' }}
@@ -28,23 +25,21 @@ jobs:
max-parallel: 2 max-parallel: 2
matrix: matrix:
unity: ["2022.3.39f1", "6000.0.12f1"] # Test with LTS unity: ["2022.3.39f1", "6000.0.12f1"] # Test with LTS
permissions: runs-on: ubuntu-latest
contents: read timeout-minutes: 20
runs-on: ubuntu-24.04
timeout-minutes: 30 # Unity build takes more than 20min.
steps: steps:
- name: Load secrets - name: Load secrets
id: op-load-secret id: op-load-secret
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0 uses: 1password/load-secrets-action@v2
with: with:
export-env: false export-env: false
env: env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }} OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username" UNITY_EMAIL: "op://GitHubActionsPublic/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential" UNITY_PASSWORD: "op://GitHubActionsPublic/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial" UNITY_SERIAL: "op://GitHubActionsPublic/UNITY_LICENSE/serial"
- uses: Cysharp/Actions/.github/actions/checkout@main - uses: actions/checkout@v4
# 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
@@ -61,6 +56,10 @@ jobs:
targetPlatform: StandaloneLinux64 targetPlatform: StandaloneLinux64
buildMethod: PackageExporter.Export buildMethod: PackageExporter.Export
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Execute UnitTest # Execute UnitTest
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend IL2CPP /BuildTarget StandaloneLinux64 # /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend IL2CPP /BuildTarget StandaloneLinux64
- name: Build UnitTest (IL2CPP) - name: Build UnitTest (IL2CPP)
@@ -80,10 +79,6 @@ jobs:
- name: Execute UnitTest - name: Execute UnitTest
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_IL2CPP/test run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_IL2CPP/test
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Store artifacts. # Store artifacts.
- uses: Cysharp/Actions/.github/actions/upload-artifact@main - uses: Cysharp/Actions/.github/actions/upload-artifact@main
if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021 if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021

View File

@@ -1,58 +0,0 @@
name: build-docs
on:
push:
branches:
- master
- feature/docs
jobs:
run-docfx:
if: ${{ ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:')) && github.triggering_actor != 'dependabot[bot]' }}
permissions:
contents: write
pages: write
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0
with:
export-env: false
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial"
- uses: Cysharp/Actions/.github/actions/checkout@main
# Execute scripts: Export Package
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
- name: Build Unity (.unitypackage)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: "2022.3.39f1"
targetPlatform: StandaloneLinux64
buildMethod: PackageExporter.Export
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
repository: Cysharp/DocfxTemplate
path: docs/_DocfxTemplate
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
- name: dotnet tool restore
run: dotnet tool restore
- name: Docfx metadata
run: dotnet docfx metadata docs/docfx.json
- name: Docfx build
run: dotnet docfx build docs/docfx.json
- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site

31
.github/workflows/build-docs.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: build-docs
on:
push:
branches:
- master
- feature/docs
jobs:
run-docfx:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: Cysharp/DocfxTemplate
path: docs/_DocfxTemplate
- uses: Kirbyrawr/docfx-action@master
name: Docfx metadata
with:
args: metadata docs/docfx.json
- uses: Kirbyrawr/docfx-action@master
name: Docfx build
with:
args: build docs/docfx.json
- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site

View File

@@ -14,9 +14,6 @@ on:
jobs: jobs:
update-packagejson: update-packagejson:
permissions:
actions: read
contents: write
uses: Cysharp/Actions/.github/workflows/update-packagejson.yaml@main uses: Cysharp/Actions/.github/workflows/update-packagejson.yaml@main
with: with:
file-path: ./src/UniTask/Assets/Plugins/UniTask/package.json file-path: ./src/UniTask/Assets/Plugins/UniTask/package.json
@@ -25,13 +22,11 @@ jobs:
build-dotnet: build-dotnet:
needs: [update-packagejson] needs: [update-packagejson]
permissions: runs-on: ubuntu-latest
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- run: echo ${{ needs.update-packagejson.outputs.sha }} - run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/checkout@main - uses: actions/checkout@v4
with: with:
ref: ${{ needs.update-packagejson.outputs.sha }} ref: ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main - uses: Cysharp/Actions/.github/actions/setup-dotnet@main
@@ -51,24 +46,22 @@ jobs:
strategy: strategy:
matrix: matrix:
unity: ["2022.3.39f1"] unity: ["2022.3.39f1"]
permissions: runs-on: ubuntu-latest
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 15 timeout-minutes: 15
steps: steps:
- name: Load secrets - name: Load secrets
id: op-load-secret id: op-load-secret
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0 uses: 1password/load-secrets-action@v2
with: with:
export-env: false export-env: false
env: env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }} OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username" UNITY_EMAIL: "op://GitHubActionsPublic/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential" UNITY_PASSWORD: "op://GitHubActionsPublic/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial" UNITY_SERIAL: "op://GitHubActionsPublic/UNITY_LICENSE/serial"
- run: echo ${{ needs.update-packagejson.outputs.sha }} - run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/checkout@main - uses: actions/checkout@v4
with: with:
ref: ${{ needs.update-packagejson.outputs.sha }} ref: ${{ needs.update-packagejson.outputs.sha }}
# Execute scripts: Export Package # Execute scripts: Export Package
@@ -99,9 +92,6 @@ jobs:
# release # release
create-release: create-release:
needs: [update-packagejson, build-dotnet, build-unity] needs: [update-packagejson, build-dotnet, build-unity]
permissions:
contents: write
id-token: write # required for NuGet Trusted Publish
uses: Cysharp/Actions/.github/workflows/create-release.yaml@main uses: Cysharp/Actions/.github/workflows/create-release.yaml@main
with: with:
commit-id: ${{ needs.update-packagejson.outputs.sha }} commit-id: ${{ needs.update-packagejson.outputs.sha }}
@@ -115,8 +105,6 @@ jobs:
cleanup: cleanup:
if: ${{ needs.update-packagejson.outputs.is-branch-created == 'true' }} if: ${{ needs.update-packagejson.outputs.is-branch-created == 'true' }}
needs: [update-packagejson, build-dotnet, build-unity] needs: [update-packagejson, build-dotnet, build-unity]
permissions:
contents: write
uses: Cysharp/Actions/.github/workflows/clean-packagejson-branch.yaml@main uses: Cysharp/Actions/.github/workflows/clean-packagejson-branch.yaml@main
with: with:
branch: ${{ needs.update-packagejson.outputs.branch-name }} branch: ${{ needs.update-packagejson.outputs.branch-name }}

View File

@@ -7,6 +7,4 @@ on:
jobs: jobs:
detect: detect:
permissions:
contents: read
uses: Cysharp/Actions/.github/workflows/prevent-github-change.yaml@main uses: Cysharp/Actions/.github/workflows/prevent-github-change.yaml@main

View File

@@ -7,8 +7,4 @@ on:
jobs: jobs:
stale: stale:
permissions:
contents: read
pull-requests: write
issues: write
uses: Cysharp/Actions/.github/workflows/stale-issue.yaml@main uses: Cysharp/Actions/.github/workflows/stale-issue.yaml@main

View File

@@ -1,15 +0,0 @@
name: TOC Generator
on:
push:
paths:
- 'README.md'
jobs:
toc:
permissions:
contents: write
uses: Cysharp/Actions/.github/workflows/toc-generator.yaml@main
with:
TOC_TITLE: "## Table of Contents"
secrets: inherit

15
.github/workflows/toc.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: TOC Generator
on:
push:
paths:
- 'README.md'
jobs:
generateTOC:
name: TOC Generator
runs-on: ubuntu-latest
steps:
- uses: technote-space/toc-generator@v4.3.1
with:
TOC_TITLE: "## Table of Contents"

14
.gitignore vendored
View File

@@ -100,19 +100,7 @@ publish
*.Publish.xml *.Publish.xml
# NuGet Packages Directory # NuGet Packages Directory
*.nupkg packages
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
# packages # upm pacakge will use Packages
# **/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
# !**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Windows Azure Build Output # Windows Azure Build Output
csx csx

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)opensource.snk</AssemblyOriginatorKeyFile>
<!-- NuGet Package Information -->
<IsPackable>false</IsPackable>
<PackageVersion>$(Version)</PackageVersion>
<Company>Cysharp</Company>
<Authors>Cysharp</Authors>
<Copyright>© Cysharp, Inc.</Copyright>
<PackageTags>task;async</PackageTags>
<PackageProjectUrl>https://github.com/Cysharp/UniTask</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>$(PackageProjectUrl)</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Icon.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)Icon.png" Pack="true" PackagePath="\" />
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)LICENSE" />
</ItemGroup>
</Project>

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -4,11 +4,7 @@
"src": [ "src": [
{ {
"files": [ "files": [
"UniTask/Library/ScriptAssemblies/UniTask*.dll" "UniTask/Assets/Plugins/UniTask/Runtime/**/*.cs"
],
"exclude": [
"UniTask/Library/ScriptAssemblies/UniTask.Tests.dll",
"UniTask/Library/ScriptAssemblies/UniTask.Tests.Editor.dll"
], ],
"src": "../src" "src": "../src"
} }
@@ -58,6 +54,7 @@
} }
], ],
"dest": "_site", "dest": "_site",
"globalMetadataFiles": [], "globalMetadataFiles": [],
"fileMetadataFiles": [], "fileMetadataFiles": [],
"template": [ "template": [
@@ -70,4 +67,4 @@
"keepFileLink": false, "keepFileLink": false,
"cleanupCacheHistory": false "cleanupCacheHistory": false
} }
} }

View File

@@ -1,29 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IsRoslynComponent>true</IsRoslynComponent> <IsRoslynComponent>true</IsRoslynComponent>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage> <TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage>
<IncludeBuildOutput>false</IncludeBuildOutput> <IncludeBuildOutput>false</IncludeBuildOutput>
<IncludeSymbols>false</IncludeSymbols> <IncludeSymbols>false</IncludeSymbols>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking> <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<DevelopmentDependency>true</DevelopmentDependency> <DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
</ItemGroup>
<Target Name="PackBuildOutputs" DependsOnTargets="SatelliteDllsProjectOutputGroup;DebugSymbolsProjectOutputGroup">
<ItemGroup> <ItemGroup>
<TfmSpecificPackageFile Include="$(TargetDir)\*.dll" PackagePath="analyzers\dotnet\cs" /> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<TfmSpecificPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput->'%(FinalOutputPath)')" PackagePath="analyzers\dotnet\cs\%(SatelliteDllsProjectOutputGroupOutput.Culture)\" /> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
</ItemGroup> </ItemGroup>
</Target>
</Project> <Target Name="PackBuildOutputs" DependsOnTargets="SatelliteDllsProjectOutputGroup;DebugSymbolsProjectOutputGroup">
<ItemGroup>
<TfmSpecificPackageFile Include="$(TargetDir)\*.dll" PackagePath="analyzers\dotnet\cs" />
<TfmSpecificPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput->'%(FinalOutputPath)')" PackagePath="analyzers\dotnet\cs\%(SatelliteDllsProjectOutputGroupOutput.Culture)\" />
</ItemGroup>
</Target>
</Project>

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

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

View File

@@ -4,6 +4,7 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<RootNamespace>NetCoreSandbox</RootNamespace> <RootNamespace>NetCoreSandbox</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -15,10 +16,12 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\UniTask.NetCore\UniTask.NetCore.csproj" /> <ProjectReference Include="..\UniTask.NetCore\UniTask.NetCore.csproj" />
<ProjectReference Include="..\UniTask.Analyzer\UniTask.Analyzer.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType> <ProjectReference Include="..\UniTask.Analyzer\UniTask.Analyzer.csproj">
</ProjectReference> <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType>
</ProjectReference>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -2,6 +2,9 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
<RootNamespace>NetCoreTests</RootNamespace> <RootNamespace>NetCoreTests</RootNamespace>
</PropertyGroup> </PropertyGroup>

View File

@@ -135,8 +135,8 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose(); cancellationTokenRegistration.Dispose();
core.Reset();
cancellationTokenRegistration = default; cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this); parent.triggerEvent.Remove(this);
parent = null; parent = null;
@@ -453,8 +453,8 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose(); cancellationTokenRegistration.Dispose();
core.Reset();
cancellationTokenRegistration = default; cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this); parent.triggerEvent.Remove(this);
parent = null; parent = null;

View File

@@ -353,8 +353,8 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset();
cancellationRegistration.Dispose(); cancellationRegistration.Dispose();
core.Reset();
RestoreOriginalCallback(); RestoreOriginalCallback();

View File

@@ -255,7 +255,7 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); TryReturn();
} }
@@ -289,6 +289,7 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
cancellationTokenRegistration.Dispose();
core.TrySetResult(null); core.TrySetResult(null);
return false; return false;
} }
@@ -296,9 +297,9 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
cancellationTokenRegistration.Dispose();
core.Reset(); core.Reset();
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
@@ -366,7 +367,7 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); TryReturn();
} }
@@ -412,9 +413,9 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
cancellationTokenRegistration.Dispose();
core.Reset(); core.Reset();
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this); return pool.TryPush(this);
} }
} }

View File

@@ -42,6 +42,7 @@ namespace Cysharp.Threading.Tasks
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
#if !UNITY_2023_1_OR_NEWER
public struct AsyncOperationAwaiter : ICriticalNotifyCompletion public struct AsyncOperationAwaiter : ICriticalNotifyCompletion
{ {
AsyncOperation asyncOperation; AsyncOperation asyncOperation;
@@ -81,6 +82,7 @@ namespace Cysharp.Threading.Tasks
asyncOperation.completed += continuationAction; asyncOperation.completed += continuationAction;
} }
} }
#endif
sealed class AsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationConfiguredSource> sealed class AsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationConfiguredSource>
{ {
@@ -99,6 +101,7 @@ namespace Cysharp.Threading.Tasks
CancellationTokenRegistration cancellationTokenRegistration; CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately; bool cancelImmediately;
bool completed; bool completed;
bool allowReturn;
UniTaskCompletionSourceCore<AsyncUnit> core; UniTaskCompletionSourceCore<AsyncUnit> core;
@@ -126,7 +129,8 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately; result.cancelImmediately = cancelImmediately;
result.completed = false; result.completed = false;
result.allowReturn = false;
asyncOperation.completed += result.continuationAction; asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled) if (cancelImmediately && cancellationToken.CanBeCanceled)
@@ -154,9 +158,16 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); if (allowReturn)
{
TryReturn();
}
else
{
allowReturn = true;
}
} }
else else
{ {
@@ -183,9 +194,15 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext() public bool MoveNext()
{ {
// Already completed if (allowReturn)
if (completed || asyncOperation == null)
{ {
TryReturn();
return false;
}
if (completed)
{
allowReturn = true;
return false; return false;
} }
@@ -202,6 +219,8 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone) if (asyncOperation.isDone)
{ {
cancellationTokenRegistration.Dispose();
allowReturn = true;
core.TrySetResult(AsyncUnit.Default); core.TrySetResult(AsyncUnit.Default);
return false; return false;
} }
@@ -212,29 +231,31 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
cancellationTokenRegistration.Dispose();
core.Reset(); core.Reset();
asyncOperation.completed -= continuationAction; asyncOperation.completed -= continuationAction;
asyncOperation = default; asyncOperation = default;
progress = default; progress = default;
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
void Continuation(AsyncOperation _) void Continuation(AsyncOperation _)
{ {
if (completed)
{
return;
}
completed = true; completed = true;
cancellationTokenRegistration.Dispose();
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
} }
else else
{ {
if (progress != null)
{
progress.Report(asyncOperation.progress);
}
core.TrySetResult(AsyncUnit.Default); core.TrySetResult(AsyncUnit.Default);
} }
} }
@@ -329,6 +350,7 @@ namespace Cysharp.Threading.Tasks
CancellationTokenRegistration cancellationTokenRegistration; CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately; bool cancelImmediately;
bool completed; bool completed;
bool allowReturn;
UniTaskCompletionSourceCore<UnityEngine.Object> core; UniTaskCompletionSourceCore<UnityEngine.Object> core;
@@ -356,7 +378,8 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately; result.cancelImmediately = cancelImmediately;
result.completed = false; result.completed = false;
result.allowReturn = false;
asyncOperation.completed += result.continuationAction; asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled) if (cancelImmediately && cancellationToken.CanBeCanceled)
@@ -384,9 +407,16 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); if (allowReturn)
{
TryReturn();
}
else
{
allowReturn = true;
}
} }
else else
{ {
@@ -417,9 +447,15 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext() public bool MoveNext()
{ {
// Already completed if (allowReturn)
if (completed || asyncOperation == null)
{ {
TryReturn();
return false;
}
if (completed)
{
allowReturn = true;
return false; return false;
} }
@@ -436,6 +472,8 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone) if (asyncOperation.isDone)
{ {
cancellationTokenRegistration.Dispose();
allowReturn = true;
core.TrySetResult(asyncOperation.asset); core.TrySetResult(asyncOperation.asset);
return false; return false;
} }
@@ -446,29 +484,31 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
cancellationTokenRegistration.Dispose();
core.Reset(); core.Reset();
asyncOperation.completed -= continuationAction; asyncOperation.completed -= continuationAction;
asyncOperation = default; asyncOperation = default;
progress = default; progress = default;
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
void Continuation(AsyncOperation _) void Continuation(AsyncOperation _)
{ {
if (completed)
{
return;
}
completed = true; completed = true;
cancellationTokenRegistration.Dispose();
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
} }
else else
{ {
if (progress != null)
{
progress.Report(asyncOperation.progress);
}
core.TrySetResult(asyncOperation.asset); core.TrySetResult(asyncOperation.asset);
} }
} }
@@ -564,6 +604,7 @@ namespace Cysharp.Threading.Tasks
CancellationTokenRegistration cancellationTokenRegistration; CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately; bool cancelImmediately;
bool completed; bool completed;
bool allowReturn;
UniTaskCompletionSourceCore<UnityEngine.Object> core; UniTaskCompletionSourceCore<UnityEngine.Object> core;
@@ -591,7 +632,8 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately; result.cancelImmediately = cancelImmediately;
result.completed = false; result.completed = false;
result.allowReturn = false;
asyncOperation.completed += result.continuationAction; asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled) if (cancelImmediately && cancellationToken.CanBeCanceled)
@@ -619,9 +661,16 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); if (allowReturn)
{
TryReturn();
}
else
{
allowReturn = true;
}
} }
else else
{ {
@@ -652,9 +701,15 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext() public bool MoveNext()
{ {
// Already completed if (allowReturn)
if (completed || asyncOperation == null)
{ {
TryReturn();
return false;
}
if (completed)
{
allowReturn = true;
return false; return false;
} }
@@ -671,6 +726,8 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone) if (asyncOperation.isDone)
{ {
cancellationTokenRegistration.Dispose();
allowReturn = true;
core.TrySetResult(asyncOperation.asset); core.TrySetResult(asyncOperation.asset);
return false; return false;
} }
@@ -681,29 +738,31 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
cancellationTokenRegistration.Dispose();
core.Reset(); core.Reset();
asyncOperation.completed -= continuationAction; asyncOperation.completed -= continuationAction;
asyncOperation = default; asyncOperation = default;
progress = default; progress = default;
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
void Continuation(AsyncOperation _) void Continuation(AsyncOperation _)
{ {
if (completed)
{
return;
}
completed = true; completed = true;
cancellationTokenRegistration.Dispose();
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
} }
else else
{ {
if (progress != null)
{
progress.Report(asyncOperation.progress);
}
core.TrySetResult(asyncOperation.asset); core.TrySetResult(asyncOperation.asset);
} }
} }
@@ -800,6 +859,7 @@ namespace Cysharp.Threading.Tasks
CancellationTokenRegistration cancellationTokenRegistration; CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately; bool cancelImmediately;
bool completed; bool completed;
bool allowReturn;
UniTaskCompletionSourceCore<AssetBundle> core; UniTaskCompletionSourceCore<AssetBundle> core;
@@ -827,7 +887,8 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately; result.cancelImmediately = cancelImmediately;
result.completed = false; result.completed = false;
result.allowReturn = false;
asyncOperation.completed += result.continuationAction; asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled) if (cancelImmediately && cancellationToken.CanBeCanceled)
@@ -855,9 +916,16 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); if (allowReturn)
{
TryReturn();
}
else
{
allowReturn = true;
}
} }
else else
{ {
@@ -888,9 +956,15 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext() public bool MoveNext()
{ {
// Already completed if (allowReturn)
if (completed || asyncOperation == null)
{ {
TryReturn();
return false;
}
if (completed)
{
allowReturn = true;
return false; return false;
} }
@@ -907,6 +981,8 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone) if (asyncOperation.isDone)
{ {
cancellationTokenRegistration.Dispose();
allowReturn = true;
core.TrySetResult(asyncOperation.assetBundle); core.TrySetResult(asyncOperation.assetBundle);
return false; return false;
} }
@@ -916,30 +992,32 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
cancellationTokenRegistration.Dispose();
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset(); core.Reset();
asyncOperation.completed -= continuationAction; asyncOperation.completed -= continuationAction;
asyncOperation = default; asyncOperation = default;
progress = default; progress = default;
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
void Continuation(AsyncOperation _) void Continuation(AsyncOperation _)
{ {
if (completed)
{
return;
}
completed = true; completed = true;
cancellationTokenRegistration.Dispose();
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
} }
else else
{ {
if (progress != null)
{
progress.Report(asyncOperation.progress);
}
core.TrySetResult(asyncOperation.assetBundle); core.TrySetResult(asyncOperation.assetBundle);
} }
} }
@@ -1051,6 +1129,7 @@ namespace Cysharp.Threading.Tasks
CancellationTokenRegistration cancellationTokenRegistration; CancellationTokenRegistration cancellationTokenRegistration;
bool cancelImmediately; bool cancelImmediately;
bool completed; bool completed;
bool allowReturn;
UniTaskCompletionSourceCore<UnityWebRequest> core; UniTaskCompletionSourceCore<UnityWebRequest> core;
@@ -1078,7 +1157,8 @@ namespace Cysharp.Threading.Tasks
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately; result.cancelImmediately = cancelImmediately;
result.completed = false; result.completed = false;
result.allowReturn = false;
asyncOperation.completed += result.continuationAction; asyncOperation.completed += result.continuationAction;
if (cancelImmediately && cancellationToken.CanBeCanceled) if (cancelImmediately && cancellationToken.CanBeCanceled)
@@ -1107,9 +1187,16 @@ namespace Cysharp.Threading.Tasks
} }
finally finally
{ {
if (!(cancelImmediately && cancellationToken.IsCancellationRequested)) if (!cancellationToken.IsCancellationRequested)
{ {
TryReturn(); if (allowReturn)
{
TryReturn();
}
else
{
allowReturn = true;
}
} }
else else
{ {
@@ -1140,15 +1227,20 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext() public bool MoveNext()
{ {
// Already completed if (allowReturn)
if (completed || asyncOperation == null)
{ {
TryReturn();
return false;
}
if (completed)
{
allowReturn = true;
return false; return false;
} }
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
asyncOperation.webRequest.Abort();
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
return false; return false;
} }
@@ -1160,14 +1252,9 @@ namespace Cysharp.Threading.Tasks
if (asyncOperation.isDone) if (asyncOperation.isDone)
{ {
if (asyncOperation.webRequest.IsError()) cancellationTokenRegistration.Dispose();
{ allowReturn = true;
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); core.TrySetResult(asyncOperation.webRequest);
}
else
{
core.TrySetResult(asyncOperation.webRequest);
}
return false; return false;
} }
@@ -1176,24 +1263,22 @@ namespace Cysharp.Threading.Tasks
bool TryReturn() bool TryReturn()
{ {
cancellationTokenRegistration.Dispose();
TaskTracker.RemoveTracking(this); TaskTracker.RemoveTracking(this);
core.Reset(); core.Reset();
asyncOperation.completed -= continuationAction; asyncOperation.completed -= continuationAction;
asyncOperation = default; asyncOperation = default;
progress = default; progress = default;
cancellationToken = default; cancellationToken = default;
cancellationTokenRegistration.Dispose();
cancelImmediately = default; cancelImmediately = default;
return pool.TryPush(this); return pool.TryPush(this);
} }
void Continuation(AsyncOperation _) void Continuation(AsyncOperation _)
{ {
if (completed)
{
return;
}
completed = true; completed = true;
cancellationTokenRegistration.Dispose();
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
core.TrySetCanceled(cancellationToken); core.TrySetCanceled(cancellationToken);
@@ -1204,6 +1289,11 @@ namespace Cysharp.Threading.Tasks
} }
else else
{ {
if (progress != null)
{
progress.Report(asyncOperation.progress);
}
core.TrySetResult(asyncOperation.webRequest); core.TrySetResult(asyncOperation.webRequest);
} }
} }

View File

@@ -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.5.10", "version": "2.5.9",
"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" ],

View File

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

View File

@@ -0,0 +1 @@
MyTEST

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 49ccc900467d35543bb602a3de4d786a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -21,7 +21,6 @@ using System.Linq.Expressions;
using UnityEngine.Events; using UnityEngine.Events;
// using DG.Tweening; // using DG.Tweening;
@@ -180,7 +179,7 @@ public class SandboxMain : MonoBehaviour
//UnityAction action; //UnityAction action;
return 10; return 10;
} }
@@ -592,69 +591,78 @@ public class SandboxMain : MonoBehaviour
async UniTaskVoid Start() async UniTaskVoid Start()
{ {
await new WhenEachTest().Each(); var p = Progress.Create<float>(x =>
// UniTask.Delay(TimeSpan.FromSeconds(1)).TimeoutWithoutException
var currentLoop = PlayerLoop.GetDefaultPlayerLoop();
PlayerLoopHelper.Initialize(ref currentLoop, InjectPlayerLoopTimings.Minimum); // minimum is Update | FixedUpdate | LastPostLateUpdate
// TestAsync(cts.Token).Forget();
okButton.onClick.AddListener(UniTask.UnityAction(async () =>
{ {
await UniTask.WaitForEndOfFrame(this); Debug.Log(x);
var texture = new Texture2D(Screen.width, Screen.height); });
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); var foo = await Resources.LoadAsync("test2").ToUniTask(progress: p) as TextAsset;
texture.Apply(); Debug.Log(foo.text);
//var foo2 = await Resources.LoadAsync("test2").ToUniTask() as TextAsset;
//Debug.Log(foo2.text); // onemore?
var jpg = texture.EncodeToJPG();
File.WriteAllBytes("testscreencapture.jpg", jpg);
Debug.Log("ok?");
//var texture = ScreenCapture.CaptureScreenshotAsTexture();
//if (texture == null)
//{
// Debug.Log("fail");
//}
//else
//{
// var jpg = texture.EncodeToJPG();
// File.WriteAllBytes("testscreencapture.jpg", jpg);
// Debug.Log("ok?");
//}
}));
cancelButton.onClick.AddListener(UniTask.UnityAction(async () => //await new WhenEachTest().Each();
{
//clickCancelSource.Cancel();
//RunCheck(PlayerLoopTiming.Initialization).Forget();
//RunCheck(PlayerLoopTiming.LastInitialization).Forget();
//RunCheck(PlayerLoopTiming.EarlyUpdate).Forget();
//RunCheck(PlayerLoopTiming.LastEarlyUpdate).Forget();
//RunCheck(PlayerLoopTiming.FixedUpdate).Forget();
//RunCheck(PlayerLoopTiming.LastFixedUpdate).Forget();
//RunCheck(PlayerLoopTiming.PreUpdate).Forget();
//RunCheck(PlayerLoopTiming.LastPreUpdate).Forget();
//RunCheck(PlayerLoopTiming.Update).Forget();
//RunCheck(PlayerLoopTiming.LastUpdate).Forget();
//RunCheck(PlayerLoopTiming.PreLateUpdate).Forget();
//RunCheck(PlayerLoopTiming.LastPreLateUpdate).Forget();
//RunCheck(PlayerLoopTiming.PostLateUpdate).Forget();
//RunCheck(PlayerLoopTiming.LastPostLateUpdate).Forget();
await UniTask.Yield(); //// UniTask.Delay(TimeSpan.FromSeconds(1)).TimeoutWithoutException
}));
await UniTask.Yield();
//var currentLoop = PlayerLoop.GetDefaultPlayerLoop();
//PlayerLoopHelper.Initialize(ref currentLoop, InjectPlayerLoopTimings.Minimum); // minimum is Update | FixedUpdate | LastPostLateUpdate
//// TestAsync(cts.Token).Forget();
//okButton.onClick.AddListener(UniTask.UnityAction(async () =>
//{
// await UniTask.WaitForEndOfFrame(this);
// var texture = new Texture2D(Screen.width, Screen.height);
// texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
// texture.Apply();
// var jpg = texture.EncodeToJPG();
// File.WriteAllBytes("testscreencapture.jpg", jpg);
// Debug.Log("ok?");
// //var texture = ScreenCapture.CaptureScreenshotAsTexture();
// //if (texture == null)
// //{
// // Debug.Log("fail");
// //}
// //else
// //{
// // var jpg = texture.EncodeToJPG();
// // File.WriteAllBytes("testscreencapture.jpg", jpg);
// // Debug.Log("ok?");
// //}
//}));
//cancelButton.onClick.AddListener(UniTask.UnityAction(async () =>
//{
// //clickCancelSource.Cancel();
// //RunCheck(PlayerLoopTiming.Initialization).Forget();
// //RunCheck(PlayerLoopTiming.LastInitialization).Forget();
// //RunCheck(PlayerLoopTiming.EarlyUpdate).Forget();
// //RunCheck(PlayerLoopTiming.LastEarlyUpdate).Forget();
// //RunCheck(PlayerLoopTiming.FixedUpdate).Forget();
// //RunCheck(PlayerLoopTiming.LastFixedUpdate).Forget();
// //RunCheck(PlayerLoopTiming.PreUpdate).Forget();
// //RunCheck(PlayerLoopTiming.LastPreUpdate).Forget();
// //RunCheck(PlayerLoopTiming.Update).Forget();
// //RunCheck(PlayerLoopTiming.LastUpdate).Forget();
// //RunCheck(PlayerLoopTiming.PreLateUpdate).Forget();
// //RunCheck(PlayerLoopTiming.LastPreLateUpdate).Forget();
// //RunCheck(PlayerLoopTiming.PostLateUpdate).Forget();
// //RunCheck(PlayerLoopTiming.LastPostLateUpdate).Forget();
// await UniTask.Yield();
//}));
} }
async UniTaskVoid RunCheck(PlayerLoopTiming timing) async UniTaskVoid RunCheck(PlayerLoopTiming timing)