Skip to content

Commit

Permalink
Merge branch 'release/0.9.8'
Browse files Browse the repository at this point in the history
  • Loading branch information
Arvtesh committed Nov 9, 2018
2 parents 2efe4b0 + aca8ccc commit fba6f9c
Show file tree
Hide file tree
Showing 71 changed files with 3,477 additions and 2,584 deletions.
2 changes: 1 addition & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dotnet_csproj:
version: '$(GitVersion_MajorMinorPatch)'
package_version: '$(GitVersion_NuGetVersionV2)'
assembly_version: '$(GitVersion_AssemblySemVer)'
file_version: '$(GitVersion_MajorMinorPatch).$(GitVersion_CommitsSinceVersionSource)'
file_version: '$(GitVersion_AssemblySemVer)'
informational_version: '$(GitVersion_InformationalVersion)'

deploy:
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/).

-----------------------
## [0.9.8] - 2018.11.09

### Added
- `AsyncResult` is now Task-like type and can be used as `async` method result value (requires C# 7.2).
- Added new `AsyncResult.FromAction` overloads.
- Added new `SynchronizationContext` extension methods (`PostAsync`, `InvokeAsync` etc).
- Added extension methods for `Socket`, `WebRequest`, `Stream` BCL classes.

### Changed
- Moved BCL extension methods to namespace `UnityFx.Async.Extensions` (previously they were in namespace `UnityFx.Async`).

### Fixed
- Fixed `AsyncResult` completion callbacks to be called event if `OnCompleted` throws.
- Fixed exception not been set for `AsyncResult.FaultedOperation` and `AsyncResult.CanceledOperation`.
- Disabled `MovieTexture` helpers for iOS/Android (as it is not supported on mobiles).

### Removed
- Removed `AsyncResultQueue`.
- Removed `AsyncLazy`.

-----------------------
## [0.9.7] - 2018.09.27

Expand Down
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ Channel | UnityFx.Async |
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)
NuGet | [![NuGet](https://img.shields.io/nuget/v/UnityFx.Async.svg)](https://www.nuget.org/packages/UnityFx.Async)
Github | [![GitHub release](https://img.shields.io/github/release/Arvtesh/UnityFx.Async.svg?logo=github)](https://github.com/Arvtesh/UnityFx.Async/releases)
Unity Asset Store | [![Asynchronous operations for Unity](https://img.shields.io/badge/tools-v0.9.7-green.svg)](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696)
Unity Asset Store | [![Asynchronous operations for Unity](https://img.shields.io/badge/tools-v0.9.8-green.svg)](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696)

**Required Unity 5.4 or higher.**
**Requires Unity 5.4 or higher.**

**If you enjoy using the library - please, [rate and review](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696) it on the Asset Store!**

**Please ask any questions and leave feedback at the [Unity forums](https://forum.unity.com/threads/asynchronous-operations-for-unity-free.522989/).**

## Synopsis

*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.
Expand All @@ -27,15 +29,17 @@ The table below summarizes differences berween *UnityFx.Async* and other popular
| Stat | UnityFx.Async | [C-Sharp-Promise](https://github.com/Real-Serious-Games/C-Sharp-Promise) | [TPL](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl) |
| :--- | :---: | :---: | :---: |
| Thread-safe | ✔️ | - | ✔️ |
| Can capture synchronization context | ✔️ | - | ✔️ |
| .NET 3.5 compilance | ✔️ | ✔️ | -️️ |
| Supports [SynchronizationContext](https://docs.microsoft.com/en-us/dotnet/api/system.threading.synchronizationcontext) capturing | ✔️ | - | ✔️ |
| Supports continuations | ✔️ | ✔️ | ✔️ |
| Supports Unity coroutines | ️️✔️ | - | - |
| Supports `async` / `await` | ✔️ | - | ✔️ |
| Supports `promise`-like continuations | ✔️ | ✔️ | - |
| Supports [async / await](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/index) | ✔️ | - | ✔️ |
| Supports [promise](https://www.promisejs.org/)-like continuations | ✔️ | ✔️ | - |
| Supports cancellation | ✔️ | -️ | ✔️ |
| Supports progress reporting | ✔️ | ✔️ | ✔️ |
| Supports child operations | - | - | ✔️ |
| Supports [Task-like types](https://github.com/dotnet/roslyn/blob/master/docs/features/task-types.md) (requires C# 7.2) | ✔️ | - | ✔️ |
| Supports [ExecutionContext](https://docs.microsoft.com/en-us/dotnet/api/system.threading.executioncontext) flow | - | - | ✔️ |
| Minimum operation data size for 32-bit systems (in bytes) | 32+ | 36+ | 40+ |
| Minimum number of allocations per continuation | ~1 | 5+ | 2+ |

Expand All @@ -55,7 +59,7 @@ git submodule -q update --init
The binaries are available as a [NuGet package](https://www.nuget.org/packages/UnityFx.Async). See [here](http://docs.nuget.org/docs/start-here/using-the-package-manager-console) for instructions on installing a package via nuget. One can also download them directly from [Github releases](https://github.com/Arvtesh/UnityFx.Async/releases). Unity3d users can import corresponding [Unity Asset Store package](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696) using the editor.

### Unity dependencies
The library core (`UnityFx.Async.dll`) does not depend on Unity and can be used in any .NET projects (via assembly or [NuGet](https://www.nuget.org/packages/UnityFx.Async) reference). All Unity-specific stuff depends on the core and is included in [Unity Asset Store package](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696).
The library core (`UnityFx.Async.dll`) does not depend on Unity and can be used in any .NET project (via assembly or [NuGet](https://www.nuget.org/packages/UnityFx.Async) reference). All Unity-specific stuff depends on the core and is included in [Asset Store package](https://assetstore.unity.com/packages/tools/asynchronous-operations-for-unity-96696).

## Understanding the concepts
The topics below are just a quick summary of problems and the proposed solutions. For more details on the topic please see useful links at the end of this document.
Expand Down Expand Up @@ -439,7 +443,7 @@ Most common way of creating own asynchronous operation is instantiating `AsyncCo
* `AsyncResult`: an asynchronous operation without a result value.
* `AsyncResult<TResult>`: an asynchronous operation with a result value.

The sample code below demostrates creating a delay operation (in fact library provides one, this is just a simplified example):
The sample code below demostrates creating a delay operation (in fact the library provides one, this is just a simplified example):
```csharp
public class TimerDelayResult : AsyncResult
{
Expand Down Expand Up @@ -479,10 +483,9 @@ public class TimerDelayResult : AsyncResult
```

### Unity3d helpers
The library consists of 3 major parts:
As stated abovethe library include 2 main parts:
* Core tools (defined in `UnityFx.Async.dll` assembly, do not depend on Unity3d);
* Unity3d-specific tools (defined as a collection of C# scripts located in `Assets/Plugins/UnityFx.Async` if installed as an Asset Store package, require Unity3d to compile/execute).
* Unity3d samples (defined as a collection of C# scripts located in `Assets/UnityFx.Async` if installed as an Asset Store package, require Unity3d to compile/execute).
* Unity3d-specific tools (defined as a collection of C# scripts if installed as an Asset Store package, require Unity3d to compile/execute).

Everything described before (unless specified otherwise) does not require Unity and can be used in any application. The Unity-specific stuff is located in 3 classes:
* `AsyncUtility`. Defines helper methods for accessing main thread in Unity, running coroutines without actually using a `MonoBehaviour` and waiting for native Unity asynchronous operations outside of coroutines.
Expand All @@ -492,11 +495,11 @@ Everything described before (unless specified otherwise) does not require Unity
For example, one can throw a few lines of code to be executed on a main thread using:
```csharp
// Sends a delegate to the main thread and blocks calling thread until it is executed.
AsyncUtility.SendToMainThread(args => Debug.Log("On the main thread."), null);
AsyncUtility.SendToMainThread(() => Debug.Log("On the main thread."));
// Posts a delegate to the main thread and returns immediately. Returns an asynchronous operation that can be used to track the delegate execution.
AsyncUtility.PostToMainThread(args => Debug.Log("On the main thread."), null);
AsyncUtility.PostToMainThread(() => Debug.Log("On the main thread."));
// If calling thread is the main thread executes the delegate synchronously, otherwise posts it to the main thread. Returns an asynchronous operation that can be used to track the delegate execution.
AsyncUtility.InvokeOnMainThread(args => Debug.Log("On the main thread."), null);
AsyncUtility.InvokeOnMainThread(() => Debug.Log("On the main thread."));
```

## Comparison to .NET Tasks
Expand All @@ -516,15 +519,14 @@ TPL | UnityFx.Async | Notes
&#45; | [IAsyncCancellable](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.IAsyncCancellable.html) | A cancellable operation.
&#45; | [IAsyncContinuation](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.IAsyncContinuation.html) | A generic non-delegate operation continuation.
&#45; | [IAsyncUpdatable](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.IAsyncUpdatable.html), [IAsyncUpdateSource](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.IAsyncUpdateSource.html) | A consumer and provider sides for frame update notifications.
&#45; | [AsyncResultQueue&lt;T&gt;](https://arvtesh.github.io/UnityFx.Async/api/netstandard2.0/UnityFx.Async.AsyncResultQueue-1.html) | A FIFO queue of asynchronous operations executed sequentially.

Please note that the library is NOT a replacement for [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) or [TPL](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl). As a general rule it is recommended to use [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) and only switch to *UnityFx.Async* if one of the following applies:
- .NET 3.5/[Unity3d](https://unity3d.com) compatibility is required.
- Memory usage is a concern ([Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) tend to do quite a lot of allocations).
- An extendable [IAsyncResult](https://docs.microsoft.com/en-us/dotnet/api/system.iasyncresult) implementation is needed.

## Motivation
The project was initially created to help author with his [Unity3d](https://unity3d.com) projects. Unity's [AsyncOperation](https://docs.unity3d.com/ScriptReference/AsyncOperation.html) and similar can only be used in coroutines, cannot be extended and mostly do not return result or error information, .NET 3.5 does not provide much help either and even with .NET 4.6 support compatibility requirements often do not allow using [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task). When I caught myself writing the same asynchronous operation wrappers in each project I decided to share my experience to the best of human kind.
The project was initially created to help author with his [Unity3d](https://unity3d.com) projects. Unity's [AsyncOperation](https://docs.unity3d.com/ScriptReference/AsyncOperation.html) and similar can only be used in coroutines, cannot be extended and mostly do not return result or error information, .NET 3.5 does not provide much help either and even with .NET 4.6 support compatibility requirements often do not allow using [Tasks](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) (and they are quite expensive). When I caught myself writing the same asynchronous operation wrappers in each project I decided to share my experience to the best of human kind.

## Documentation
Please see the links below for extended information on the product:
Expand Down Expand Up @@ -554,7 +556,7 @@ The project uses [SemVer](https://semver.org/) versioning pattern. For the versi
Please see the [![license](https://img.shields.io/github/license/Arvtesh/UnityFx.Async.svg)](LICENSE.md) for details.

## Acknowledgments
Working on this project is a great experience. Please see below list of sources of my inspiration (in no particular order):
Working on this project is a great experience. Please see below a list of my inspiration sources (in no particular order):
* [.NET reference source](https://referencesource.microsoft.com/mscorlib/System/threading/Tasks/Task.cs.html). A great source of knowledge and good programming practices.
* [C-Sharp-Promise](https://github.com/Real-Serious-Games/C-Sharp-Promise). Another great C# promise library with excellent documentation.
* [UniRx](https://github.com/neuecc/UniRx). A deeply reworked [Rx.NET](https://github.com/Reactive-Extensions/Rx.NET) port to Unity.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
SUMMARY
The package provides lightweight Task-like asynchronous operations (promises) for Unity3d.

PUBLISHER INFORMATION
https://www.linkedin.com/in/alexander-bogarsukov-93b9682/
Lightweight Task-like asynchronous operations (promises) for Unity3d.

LICENSE
https://github.com/Arvtesh/UnityFx.Async/blob/master/LICENSE.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
using UnityFx.Async.Extensions;

namespace UnityFx.Async
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public static IAsyncOperation<Texture2D> GetTexture(string url, bool nonReadable
return result;
}

#if !UNITY_2018_2_OR_NEWER
#if !UNITY_2018_2_OR_NEWER && !UNITY_IOS && !UNITY_ANDROID

/// <summary>
/// Creates an asyncronous operation optimized for downloading a <see cref="MovieTexture"/> via HTTP GET.
Expand Down Expand Up @@ -254,7 +254,7 @@ public static T GetResult<T>(UnityWebRequest request) where T : class
{
return ((DownloadHandlerAudioClip)request.downloadHandler).audioClip as T;
}
#if !UNITY_5 && !UNITY_2018_2_OR_NEWER
#if !UNITY_5 && !UNITY_2018_2_OR_NEWER && !UNITY_IOS && !UNITY_ANDROID
else if (request.downloadHandler is DownloadHandlerMovieTexture)
{
return ((DownloadHandlerMovieTexture)request.downloadHandler).movieTexture as T;
Expand Down Expand Up @@ -298,21 +298,24 @@ public static T GetResult<T>(WWW request) where T : class
{
return request.GetAudioClip() as T;
}
#if !UNITY_2018_2_OR_NEWER
else if (typeof(T) == typeof(MovieTexture))
{
return request.GetMovieTexture() as T;
}
#endif
#else
else if (typeof(T) == typeof(AudioClip))
{
return request.audioClip as T;
}
#endif
#if !UNITY_2018_2_OR_NEWER && !UNITY_IOS && !UNITY_ANDROID
#if UNITY_5_6_OR_NEWER
else if (typeof(T) == typeof(MovieTexture))
{
return request.GetMovieTexture() as T;
}
#else
else if (typeof(T) == typeof(MovieTexture))
{
return request.movie as T;
}
#endif
#endif
else if (typeof(T) == typeof(byte[]))
{
Expand All @@ -327,5 +330,5 @@ public static T GetResult<T>(WWW request) where T : class
}

#endif
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,13 @@ public AsyncOperationAwaiter(AsyncOperation op)
/// Gets a value indicating whether the underlying operation is completed.
/// </summary>
/// <value>The operation completion flag.</value>
public bool IsCompleted => _op.isDone;
public bool IsCompleted
{
get
{
return _op.isDone;
}
}

/// <summary>
/// Returns the source result value.
Expand Down Expand Up @@ -216,7 +222,13 @@ public UnityWebRequestAwaiter(UnityWebRequest op)
/// Gets a value indicating whether the underlying operation is completed.
/// </summary>
/// <value>The operation completion flag.</value>
public bool IsCompleted => _op.isDone;
public bool IsCompleted
{
get
{
return _op.isDone;
}
}

/// <summary>
/// Returns the source result value.
Expand Down Expand Up @@ -314,7 +326,13 @@ public WwwAwaiter(WWW op)
/// Gets a value indicating whether the underlying operation is completed.
/// </summary>
/// <value>The operation completion flag.</value>
public bool IsCompleted => _op.isDone;
public bool IsCompleted
{
get
{
return _op.isDone;
}
}

/// <summary>
/// Returns the source result value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<CodeAnalysisRuleSet>../CodingConventions/Cs/CsharpRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>6</LangVersion>
<LangVersion>4</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net46'">
Expand Down
73 changes: 0 additions & 73 deletions src/UnityFx.Async.Tests/Tests/AsyncResultQueueTests.cs

This file was deleted.

Loading

0 comments on commit fba6f9c

Please sign in to comment.