Skip to content

Commit 3bd906b

Browse files
committed
Merge branch 'release/0.9.3'
2 parents fbf50d1 + 0182948 commit 3bd906b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2870
-1125
lines changed

CHANGELOG.md

+24-3
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,40 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/).
55

66
-----------------------
7-
## [0.9.3] - unreleased
7+
## [0.9.3] - 2018.06.09
8+
9+
### Added
10+
- Added push-based progress reporting support.
11+
- Added `AsyncResult.Delay(float)` overloads.
12+
- Added `AsyncCreationOptions.SuppressCancellation` option.
13+
- Added update sources for `LateUpdate`, `FixedUpdate` and end-of-frame updates.
14+
- Added `SynchronizationContext` for the main thread (if not set by Unity).
15+
- Added methods `AsyncUtility.PostToMainThread`, `AsyncUtility.SendToMainThread` as `AsyncUtility.InvokeOnMainThread`.
16+
- Added new `FromAction` overloads.
17+
18+
### Changed
19+
- Significantly reduced number of memory allocations when adding continuations.
20+
- Changed signature of the `IAsyncContinuation.Invoke` method.
21+
- Changed `AsyncResult.OnCancel` implementation to do nothing (previously it threw `NotSupportedException`).
22+
23+
### Fixed
24+
- Fixed exception when removing listeners while in `AsyncUpdateSource.OnError` / `AsyncUpdateSource.OnCompleted` / `AsyncUpdateSource.Dispose`.
25+
- Fixed `AsyncResult.MoveNext` to always return `true` while the operation is not completed.
26+
- Fixed `AsyncResult` construction code not working as intended when `AsyncCreationOptions` are specified.
27+
28+
### Removed
29+
- Removed `AsyncOperationCallback` delegate type.
830

931
-----------------------
1032
## [0.9.2] - 2018.05.25
1133

1234
### Added
13-
- Added pull-based progress support (`IAsyncOperation.Progress`).
35+
- Added pull-based progress reporting support.
1436
- Added new methods to `IAsyncUpdateSource`.
1537
- Added `AsyncUpdateSource` class as default `IAsyncUpdateSource` implementation.
1638
- `IAsyncOperation<T>` now inherits `IObservable<T>`.
1739

1840
### Changed
19-
- Renamed `(Try)AddCompletionCallback`/`RemoveCompletionCallback` methods to `(Try)AddContinuation`/`RemoveContinuation`.
2041
- Changed `IAsyncOperation.Exception` type to `Exception`.
2142
- Changed `IAsyncOperationEvents.Completed` type to `AsyncCompletedEventHandler`.
2243

README.md

+22-10
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ Channel | UnityFx.Async |
55
AppVeyor | [![Build status](https://ci.appveyor.com/api/projects/status/hfmq9vow53al7tpd/branch/master?svg=true)](https://ci.appveyor.com/project/Arvtesh/unityfx-async/branch/master) [![AppVeyor tests](https://img.shields.io/appveyor/tests/Arvtesh/unityFx-async.svg)](https://ci.appveyor.com/project/Arvtesh/unityfx-async/build/tests)
66
NuGet | [![NuGet](https://img.shields.io/nuget/v/UnityFx.Async.svg)](https://www.nuget.org/packages/UnityFx.Async)
77
Github | [![GitHub release](https://img.shields.io/github/release/Arvtesh/UnityFx.Async.svg?logo=github)](https://github.com/Arvtesh/UnityFx.Async/releases)
8-
Unity Asset Store | [![Asynchronous operations for Unity](https://img.shields.io/badge/tools-v0.9.2-green.svg)](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696)
8+
Unity Asset Store | [![Asynchronous operations for Unity](https://img.shields.io/badge/tools-v0.9.3-green.svg)](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696)
99

1010
## Synopsis
1111

12-
*UnityFx.Async* is a set of classes and interfaces that extend [Unity3d](https://unity3d.com) asynchronous operations and can be used very much like [Task-based Asynchronous Pattern (TAP)](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming) in .NET or [Promises](https://developers.google.com/web/fundamentals/primers/promises) in Javascript. The library at its core defines a container ([AsyncResult](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.AsyncResult.html)) for state and result value of an asynchronous operation (aka `promise` or `future`). In many aspects it mimics [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) (for example, it can be used with `async`/`await` operators, supports continuations and synchronization context capturing).
12+
*UnityFx.Async* introduces effective and portable asynchronous operations that can be used very much like [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) in .NET or [Promises](https://developers.google.com/web/fundamentals/primers/promises) in JS. [AsyncResult](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.AsyncResult.html) class is an implementation of a generic asynchronous operation (aka `promise` or `future`). In many aspects it mimics [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) (for example, it can be used with `async`/`await` operators, supports continuations and synchronization context capturing) while maintaining Unity/net35 compatibility. It is a great foundation toolset for any Unity project.
1313

1414
Library is designed as a lightweight [Unity3d](https://unity3d.com)-compatible [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) alternative (not a replacement though). Main design goals are:
1515
- Minimum object size and number of allocations.
16-
- Extensibility. The library operations are designed to be inherited.
16+
- Extensibility. The library entities are designed to be easily extensible.
1717
- Thread-safe. The library classes can be safely used from different threads (unless explicitly stated otherwise).
1818
- [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)-like interface and behaviour. In many cases library classes can be used much like corresponding [TPL](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl) entities.
19-
- [Unity3d](https://unity3d.com) compatibility. This includes possibility to <c>yield</c> operations in coroutines and net35-compilance.
19+
- [Unity3d](https://unity3d.com)-specific features and compatibility. This includes possibility to <c>yield</c> operations in coroutines, `net35`-compilance, extensions of Unity asynchronous operations etc.
2020

2121
The table below summarizes differences berween *UnityFx.Async* and other popular asynchronous operation frameworks:
2222

@@ -33,7 +33,7 @@ The table below summarizes differences berween *UnityFx.Async* and other popular
3333
| Supports progress reporting | ✔️ | ✔️ | ✔️ |
3434
| Supports child operations | - | - | ✔️ |
3535
| Minimum operation data size for 32-bit systems (in bytes) | 28+ | 36+ | 40+ |
36-
| Minimum number of allocations per continuation | 1+ | 5+ | 2+ |
36+
| Minimum number of allocations per continuation | ~1 | 5+ | 2+ |
3737

3838
## Getting Started
3939
### Prerequisites
@@ -166,9 +166,9 @@ Create an operation instance like this:
166166
```csharp
167167
var op = new AsyncCompletionSource<string>();
168168
```
169-
The type of the operation should reflect its result type. In this case we have created a special kind of operation - a completion source that incapsulated both producer and consumer interfaces (consumer side is represented via `IAsyncOperation` / `IAsyncOperation<TResult>` interfaces and producer side is `IAsyncCompletionSource` / `IAsyncCompletionSource<TResult>`, `AsyncCompletionSource` implements both of the interfaces).
169+
The type of the operation should reflect its result type. In this case we create a special kind of operation - a completion source, that incapsulates both producer and consumer interfaces (consumer side is represented via `IAsyncOperation` / `IAsyncOperation<TResult>` interfaces and producer side is `IAsyncCompletionSource` / `IAsyncCompletionSource<TResult>`, `AsyncCompletionSource` implements both of the interfaces).
170170

171-
While operation is running its progress can be set as:
171+
While operation is running its progress can be set like this:
172172
```csharp
173173
op.SetProgress(progressValue);
174174
```
@@ -334,9 +334,21 @@ DownloadTextAsync("http://www.google.com")
334334
If the [token](https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken) passed to `WithCancellation()` is cancelled the target operation is cancelled as well (and that means cancelling all chained operations) as soon as possible. Cancellation might not be instant (depends on specific operation implementation). Also, please note that not all operations might support cancellation; in this case `Cancel()` will throw `NotSupportedException`.
335335

336336
### Progress reporting
337-
Library operations support progress reporting via exposing `IAsyncOperation.Progress` property:
337+
Library operations support progress reporting via exposing `IAsyncOperation.Progress` property and progress reporting events:
338338
```csharp
339339
var progress = op.Progess; // gets an operation progress as a float value in range [0, 1]
340+
341+
// subscribe to progress changed event
342+
op.ProgressChanged += (sender, args) =>
343+
{
344+
Debug.Log("Progress = " + args.ProgressPercentage);
345+
}
346+
347+
// add progress changed delegate
348+
op.AddProgressCallback(op =>
349+
{
350+
Debug.Log("Progress = " + op.Progress);
351+
});
340352
```
341353
There is `AsyncResult.GetProgress()` virtual method that is called when a progress values is requested. Finally there are producer-side methods like `AsyncCompletionSource.TrySetProgress()` that can set the progress value.
342354

@@ -355,7 +367,7 @@ Completion callbacks are basicly low-level continuations. Just like continuation
355367
```csharp
356368
var op = DownloadTextAsync("http://www.google.com");
357369
op.Completed += o => Debug.Log("1");
358-
op.AddContinuation(o => Debug.Log("2"));
370+
op.AddCompletionCallback(o => Debug.Log("2"));
359371
```
360372
That said, unlike `ContinueWith()`-like stuff completion callbacks cannot be chained and do not handle exceptions automatically. Throwing an exception from a completion callback results in unspecified behavior.
361373

@@ -369,7 +381,7 @@ class MyContinuation : IAsyncContinuation
369381
// ...
370382
371383
var op = DownloadTextAsync("http://www.google.com");
372-
op.AddContinuation(new MyContinuation());
384+
op.AddCompletionCallback(new MyContinuation());
373385
```
374386

375387
### Disposing of operations

src/Build.ps1

+3
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,17 @@ function _PublishAssetStorePackage
6868
{
6969
param([string]$targetFramework)
7070

71+
$changelogPath = (Join-Path $scriptPath "..\CHANGELOG.md")
7172
$filesToPublish = (Join-Path $scriptPath "UnityFx.Async.AssetStore\Assets\*")
7273
$binToPublish =(Join-Path $binPath (Join-Path $targetFramework "\*"))
7374
$publishPath = (Join-Path $assetStorePath (Join-Path $targetFramework "Assets"))
75+
$publishPath2 = (Join-Path $publishPath "UnityFx.Async")
7476
$publishBinPath = (Join-Path $publishPath "UnityFx.Async\Bin")
7577

7678
New-Item $publishBinPath -ItemType Directory
7779
Copy-Item -Path $filesToPublish -Destination $publishPath -Force -Recurse
7880
Copy-Item -Path $binToPublish -Destination $publishBinPath -Force -Recurse
81+
Copy-Item -Path $changelogPath -Destination $publishPath2 -Force
7982
}
8083

8184

src/UnityFx.Async.AssetStore/Assets/UnityFx.Async/README.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LICENSE
55
https://github.com/Arvtesh/UnityFx.Async/blob/master/LICENSE.md
66

77
DOCUMENTATION
8+
https://github.com/Arvtesh/UnityFx.Async
89
https://arvtesh.github.io/UnityFx.Async
910

1011
SUPPORT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) Alexander Bogarsukov.
2+
// Licensed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
4+
using System;
5+
using UnityEngine;
6+
7+
namespace UnityFx.Async
8+
{
9+
/// <summary>
10+
/// A wrapper for <see cref="AssetBundleRequest"/> with result value.
11+
/// </summary>
12+
/// <typeparam name="T">Result type.</typeparam>
13+
public sealed class AssetBundleRequestResult<T> : AsyncResult<T> where T : UnityEngine.Object
14+
{
15+
#region data
16+
17+
private readonly AssetBundleRequest _op;
18+
19+
#endregion
20+
21+
#region interface
22+
23+
/// <summary>
24+
/// Gets the underlying <see cref="AssetBundleRequest"/> instance.
25+
/// </summary>
26+
public AssetBundleRequest Request
27+
{
28+
get
29+
{
30+
return _op;
31+
}
32+
}
33+
34+
/// <summary>
35+
/// Initializes a new instance of the <see cref="AssetBundleRequestResult{T}"/> class.
36+
/// </summary>
37+
/// <param name="op">Source web request.</param>
38+
public AssetBundleRequestResult(AssetBundleRequest op)
39+
: base(AsyncOperationStatus.Running)
40+
{
41+
_op = op;
42+
43+
if (op.isDone)
44+
{
45+
TrySetResult(op.asset as T, true);
46+
}
47+
else
48+
{
49+
#if UNITY_2017_2_OR_NEWER || UNITY_2018
50+
51+
// Starting with Unity 2017.2 there is AsyncOperation.completed event
52+
op.completed += o => TrySetResult(o.asset as T);
53+
54+
#else
55+
56+
AsyncUtility.AddCompletionCallback(op, () => TrySetResult(_op.asset as T));
57+
58+
#endif
59+
}
60+
}
61+
62+
#endregion
63+
64+
#region AsyncResult
65+
66+
/// <inheritdoc/>
67+
protected override float GetProgress()
68+
{
69+
return _op.progress;
70+
}
71+
72+
#endregion
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) Alexander Bogarsukov.
2+
// Licensed under the MIT license. See the LICENSE.md file in the project root for more information.
3+
4+
using System;
5+
using UnityEngine;
6+
7+
namespace UnityFx.Async
8+
{
9+
/// <summary>
10+
/// A wrapper for <see cref="AsyncOperation"/> with result value.
11+
/// </summary>
12+
public class AsyncOperationResult : AsyncResult
13+
{
14+
#region data
15+
16+
private readonly AsyncOperation _op;
17+
18+
#endregion
19+
20+
#region interface
21+
22+
/// <summary>
23+
/// Gets the underlying <see cref="AsyncOperation"/> instance.
24+
/// </summary>
25+
public AsyncOperation Operation
26+
{
27+
get
28+
{
29+
return _op;
30+
}
31+
}
32+
33+
/// <summary>
34+
/// Initializes a new instance of the <see cref="AsyncOperationResult"/> class.
35+
/// </summary>
36+
/// <param name="op">Source web request.</param>
37+
public AsyncOperationResult(AsyncOperation op)
38+
: base(AsyncOperationStatus.Running)
39+
{
40+
_op = op;
41+
42+
if (op.isDone)
43+
{
44+
TrySetCompleted(true);
45+
}
46+
else
47+
{
48+
#if UNITY_2017_2_OR_NEWER || UNITY_2018
49+
50+
// Starting with Unity 2017.2 there is AsyncOperation.completed event
51+
op.completed += o => TrySetCompleted();
52+
53+
#else
54+
55+
AsyncUtility.AddCompletionCallback(op, () => TrySetCompleted());
56+
57+
#endif
58+
}
59+
}
60+
61+
#endregion
62+
63+
#region AsyncResult
64+
65+
/// <inheritdoc/>
66+
protected override float GetProgress()
67+
{
68+
return _op.progress;
69+
}
70+
71+
#endregion
72+
}
73+
}

0 commit comments

Comments
 (0)