Auto status change to "Under Review"
@@ -0,0 +1,17 | |||||
|
1 | using System; | |||
|
2 | using System.Threading; | |||
|
3 | using Xunit; | |||
|
4 | ||||
|
5 | namespace Implab.Test | |||
|
6 | { | |||
|
7 | public class UnitTest1 | |||
|
8 | { | |||
|
9 | [Fact] | |||
|
10 | public void Test1() | |||
|
11 | { | |||
|
12 | using(var cts = new CancellationTokenSource(1000)) { | |||
|
13 | PromiseHelper.Sleep(10000, cts.Token).Join(); | |||
|
14 | } | |||
|
15 | } | |||
|
16 | } | |||
|
17 | } |
@@ -1,88 +1,16 | |||||
1 | <?xml version="1.0" encoding="utf-8"?> |
|
1 | <Project Sdk="Microsoft.NET.Sdk"> | |
2 | <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
2 | ||
3 | <PropertyGroup> |
|
3 | <PropertyGroup> | |
4 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
4 | <TargetFramework>netcoreapp2.0</TargetFramework> | |
5 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
5 | ||
6 | <ProductVersion>8.0.30703</ProductVersion> |
|
6 | <IsPackable>false</IsPackable> | |
7 | <SchemaVersion>2.0</SchemaVersion> |
|
|||
8 | <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid> |
|
|||
9 | <OutputType>Library</OutputType> |
|
|||
10 | <AppDesignerFolder>Properties</AppDesignerFolder> |
|
|||
11 | <RootNamespace>Implab.Test</RootNamespace> |
|
|||
12 | <AssemblyName>Implab.Test</AssemblyName> |
|
|||
13 | <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
|
|||
14 | <FileAlignment>512</FileAlignment> |
|
|||
15 | <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
|
|||
16 | <TargetFrameworkProfile /> |
|
|||
17 | </PropertyGroup> |
|
|||
18 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
|||
19 | <DebugSymbols>true</DebugSymbols> |
|
|||
20 | <DebugType>full</DebugType> |
|
|||
21 | <Optimize>false</Optimize> |
|
|||
22 | <OutputPath>bin\Debug\</OutputPath> |
|
|||
23 | <DefineConstants>DEBUG;TRACE</DefineConstants> |
|
|||
24 | <ErrorReport>prompt</ErrorReport> |
|
|||
25 | <WarningLevel>4</WarningLevel> |
|
|||
26 | <Prefer32Bit>false</Prefer32Bit> |
|
|||
27 | </PropertyGroup> |
|
|||
28 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|
|||
29 | <DebugType>pdbonly</DebugType> |
|
|||
30 | <Optimize>true</Optimize> |
|
|||
31 | <OutputPath>bin\Release\</OutputPath> |
|
|||
32 | <DefineConstants>TRACE</DefineConstants> |
|
|||
33 | <ErrorReport>prompt</ErrorReport> |
|
|||
34 | <WarningLevel>4</WarningLevel> |
|
|||
35 | <Prefer32Bit>false</Prefer32Bit> |
|
|||
36 | </PropertyGroup> |
|
|||
37 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' "> |
|
|||
38 | <DebugSymbols>true</DebugSymbols> |
|
|||
39 | <DebugType>full</DebugType> |
|
|||
40 | <Optimize>false</Optimize> |
|
|||
41 | <OutputPath>bin\Debug\</OutputPath> |
|
|||
42 | <DefineConstants>DEBUG;TRACE</DefineConstants> |
|
|||
43 | <ErrorReport>prompt</ErrorReport> |
|
|||
44 | <WarningLevel>4</WarningLevel> |
|
|||
45 | <Prefer32Bit>false</Prefer32Bit> |
|
|||
46 | </PropertyGroup> |
|
|||
47 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' "> |
|
|||
48 | <DebugType>pdbonly</DebugType> |
|
|||
49 | <Optimize>true</Optimize> |
|
|||
50 | <OutputPath>bin\Release\</OutputPath> |
|
|||
51 | <DefineConstants>TRACE</DefineConstants> |
|
|||
52 | <ErrorReport>prompt</ErrorReport> |
|
|||
53 | <WarningLevel>4</WarningLevel> |
|
|||
54 | <Prefer32Bit>false</Prefer32Bit> |
|
|||
55 | </PropertyGroup> |
|
7 | </PropertyGroup> | |
56 | <ItemGroup> |
|
8 | <ItemGroup> | |
57 | <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> |
|
9 | <ProjectReference Include="../Implab/Implab.csproj"/> | |
58 | <Reference Include="System" /> |
|
10 | <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" /> | |
59 |
<Reference Include=" |
|
11 | <PackageReference Include="xunit" Version="2.3.1" /> | |
60 | <RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
12 | <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |
61 | </Reference> |
|
13 | <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |
62 | </ItemGroup> |
|
|||
63 | <ItemGroup> |
|
|||
64 | <Compile Include="AsyncTests.cs" /> |
|
|||
65 | <Compile Include="CancelationTests.cs" /> |
|
|||
66 | <Compile Include="Mock\MockPollingComponent.cs" /> |
|
|||
67 | <Compile Include="Mock\MockRunnableComponent.cs" /> |
|
|||
68 | <Compile Include="PollingComponentTests.cs" /> |
|
|||
69 | <Compile Include="PromiseHelper.cs" /> |
|
|||
70 | <Compile Include="Properties\AssemblyInfo.cs" /> |
|
|||
71 | <Compile Include="RunnableComponentTests.cs" /> |
|
|||
72 | </ItemGroup> |
|
14 | </ItemGroup> | |
73 | <ItemGroup> |
|
15 | ||
74 | <ProjectReference Include="..\Implab\Implab.csproj"> |
|
16 | </Project> | |
75 | <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project> |
|
|||
76 | <Name>Implab</Name> |
|
|||
77 | </ProjectReference> |
|
|||
78 | </ItemGroup> |
|
|||
79 | <ItemGroup /> |
|
|||
80 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
|
|||
81 | <!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|
|||
82 | Other similar extension points exist, see Microsoft.Common.targets. |
|
|||
83 | <Target Name="BeforeBuild"> |
|
|||
84 | </Target> |
|
|||
85 | <Target Name="AfterBuild"> |
|
|||
86 | </Target> |
|
|||
87 | --> |
|
|||
88 | </Project> No newline at end of file |
|
@@ -1,21 +1,39 | |||||
1 |
using Implab |
|
1 | using Implab; | |
|
2 | using System; | |||
2 | using System.Threading; |
|
3 | using System.Threading; | |
3 |
|
4 | |||
4 | namespace Implab.Test { |
|
5 | namespace Implab.Test { | |
5 | static class PromiseHelper { |
|
6 | static class PromiseHelper { | |
6 | public static IPromise<T> Sleep<T>(int timeout, T retVal) { |
|
7 | public static IPromise<T> Sleep<T>(int timeout, T retVal, CancellationToken ct = default(CancellationToken)) { | |
7 | return AsyncPool.Invoke((ct) => { |
|
8 | ||
8 | ct.CancellationRequested(ct.CancelOperation); |
|
9 | Timer timer = null; | |
9 | Thread.Sleep(timeout); |
|
10 | ||
10 | return retVal; |
|
11 | return Promise.Create<T>((d) => { | |
|
12 | timer = new Timer(x => { | |||
|
13 | d.Resolve(retVal); | |||
|
14 | }, null, timeout, Timeout.Infinite); | |||
|
15 | ||||
|
16 | if(ct.CanBeCanceled) | |||
|
17 | ct.Register(d.Cancel); | |||
|
18 | ||||
|
19 | }).Finally(() => { | |||
|
20 | Safe.Dispose(timer); | |||
11 | }); |
|
21 | }); | |
12 | } |
|
22 | } | |
13 |
|
23 | |||
14 | public static IPromise Sleep(int timeout) { |
|
24 | public static IPromise Sleep(int timeout, CancellationToken ct = default(CancellationToken)) { | |
15 | return AsyncPool.Invoke((ct) => { |
|
25 | Timer timer = null; | |
16 | ct.CancellationRequested(ct.CancelOperation); |
|
26 | ||
17 | Thread.Sleep(timeout); |
|
27 | return Promise.Create((d) => { | |
18 |
|
|
28 | timer = new Timer(x => { | |
|
29 | d.Resolve(); | |||
|
30 | }, null, timeout, Timeout.Infinite); | |||
|
31 | ||||
|
32 | if(ct.CanBeCanceled) | |||
|
33 | ct.Register(d.Cancel); | |||
|
34 | ||||
|
35 | }).Finally(() => { | |||
|
36 | Safe.Dispose(timer); | |||
19 | }); |
|
37 | }); | |
20 | } |
|
38 | } | |
21 | } |
|
39 | } |
@@ -8,51 +8,46 namespace Implab { | |||||
8 | public class Deferred : IResolvable { |
|
8 | public class Deferred : IResolvable { | |
9 |
|
9 | |||
10 | readonly Promise m_promise; |
|
10 | readonly Promise m_promise; | |
11 | readonly IDispatcher m_dispatcher; |
|
11 | internal Deferred() { | |
12 |
|
12 | m_promise = new Promise(); | ||
13 | internal Deferred(IDispatcher dispatcher) : this(new Promise(), dispatcher) { |
|
|||
14 | } |
|
13 | } | |
15 |
|
14 | |||
16 | internal Deferred(Promise promise, IDispatcher dispatcher) { |
|
15 | internal Deferred(Promise promise, IDispatcher dispatcher) { | |
17 | Debug.Assert(promise != null); |
|
16 | Debug.Assert(promise != null); | |
18 | m_promise = promise; |
|
17 | m_promise = promise; | |
19 | m_dispatcher = dispatcher; |
|
|||
20 | } |
|
18 | } | |
21 |
|
19 | |||
22 | public IPromise Promise { |
|
20 | public IPromise Promise { | |
23 | get { return m_promise; } |
|
21 | get { return m_promise; } | |
24 | } |
|
22 | } | |
25 |
|
23 | |||
26 |
public void |
|
24 | public void Cancel() { | |
|
25 | Reject(new OperationCanceledException()); | |||
|
26 | } | |||
|
27 | ||||
|
28 | public virtual void Reject(Exception error) { | |||
27 | if (error is PromiseTransientException) |
|
29 | if (error is PromiseTransientException) | |
28 | error = ((PromiseTransientException)error).InnerException; |
|
30 | error = ((PromiseTransientException)error).InnerException; | |
29 |
|
31 | |||
30 | m_promise.RejectPromise(error); |
|
32 | m_promise.RejectPromise(error); | |
31 | } |
|
33 | } | |
32 |
|
34 | |||
33 | public void Resolve() { |
|
35 | public virtual void Resolve() { | |
34 | m_promise.ResolvePromise(); |
|
36 | m_promise.ResolvePromise(); | |
35 | } |
|
37 | } | |
36 |
|
38 | |||
37 | public void Resolve(IPromise thenable) { |
|
39 | public virtual void Resolve(IPromise thenable) { | |
38 | if (thenable == null) |
|
40 | if (thenable == null) | |
39 | Reject(new Exception("The promise or task are expected")); |
|
41 | Reject(new Exception("The promise or task are expected")); | |
40 | if (thenable == m_promise) |
|
42 | if (thenable == m_promise) | |
41 | Reject(new Exception("The promise cannot be resolved with oneself")); |
|
43 | Reject(new Exception("The promise cannot be resolved with oneself")); | |
42 |
|
44 | |||
43 | else if (m_dispatcher != null) |
|
|||
44 | // dispatch (see ecma-262/6.0: 25.4.1.3.2 Promise Resolve Functions) |
|
|||
45 | m_dispatcher.Enqueue(Chain, thenable); |
|
|||
46 | else |
|
|||
47 | Chain(thenable); |
|
|||
48 | } |
|
|||
49 |
|
||||
50 | void Chain(IPromise thenable) { |
|
|||
51 | try { |
|
45 | try { | |
52 | thenable.Then(this); |
|
46 | thenable.Then(this); | |
53 | } catch (Exception err) { |
|
47 | } catch (Exception err) { | |
54 | Reject(err); |
|
48 | Reject(err); | |
55 | } |
|
49 | } | |
56 | } |
|
50 | } | |
|
51 | ||||
57 | } |
|
52 | } | |
58 | } No newline at end of file |
|
53 | } |
@@ -4,46 +4,41 using System.Diagnostics; | |||||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 | public class Deferred<T> : IResolvable<T> { |
|
5 | public class Deferred<T> : IResolvable<T> { | |
6 | readonly Promise<T> m_promise; |
|
6 | readonly Promise<T> m_promise; | |
7 | readonly IDispatcher m_dispatcher; |
|
|||
8 |
|
7 | |||
9 | internal Deferred(IDispatcher dispatcher) : this(new Promise<T>(), dispatcher) { |
|
8 | internal Deferred() { | |
|
9 | m_promise = new Promise<T>(); | |||
10 | } |
|
10 | } | |
11 |
|
11 | |||
12 |
|
|
12 | protected Deferred(Promise<T> promise) { | |
13 | Debug.Assert(promise != null); |
|
13 | Debug.Assert(promise != null); | |
14 | m_promise = promise; |
|
14 | m_promise = promise; | |
15 | m_dispatcher = dispatcher; |
|
|||
16 | } |
|
15 | } | |
17 |
|
16 | |||
18 | public IPromise<T> Promise { |
|
17 | public IPromise<T> Promise { | |
19 | get { return m_promise; } |
|
18 | get { return m_promise; } | |
20 | } |
|
19 | } | |
21 |
|
20 | |||
22 |
public void |
|
21 | public void Cancel() { | |
|
22 | Reject(new OperationCanceledException()); | |||
|
23 | } | |||
|
24 | ||||
|
25 | public virtual void Reject(Exception error) { | |||
23 | if (error is PromiseTransientException) |
|
26 | if (error is PromiseTransientException) | |
24 | error = ((PromiseTransientException)error).InnerException; |
|
27 | error = ((PromiseTransientException)error).InnerException; | |
25 |
|
28 | |||
26 | m_promise.RejectPromise(error); |
|
29 | m_promise.RejectPromise(error); | |
27 | } |
|
30 | } | |
28 |
|
31 | |||
29 | public void Resolve(T value) { |
|
32 | public virtual void Resolve(T value) { | |
30 | m_promise.ResolvePromise(value); |
|
33 | m_promise.ResolvePromise(value); | |
31 | } |
|
34 | } | |
32 |
|
35 | |||
33 | public void Resolve(IPromise<T> thenable) { |
|
36 | public virtual void Resolve(IPromise<T> thenable) { | |
34 | if (thenable == null) |
|
37 | if (thenable == null) | |
35 | Reject(new Exception("The promise or task are expected")); |
|
38 | Reject(new Exception("The promise or task are expected")); | |
36 | if (thenable == m_promise) |
|
39 | if (thenable == m_promise) | |
37 | Reject(new Exception("The promise cannot be resolved with oneself")); |
|
40 | Reject(new Exception("The promise cannot be resolved with oneself")); | |
38 |
|
41 | |||
39 | else if (m_dispatcher != null) |
|
|||
40 | // dispatch (see ecma-262/6.0: 25.4.1.3.2 Promise Resolve Functions) |
|
|||
41 | m_dispatcher.Enqueue(Chain, thenable); |
|
|||
42 | else |
|
|||
43 | Chain(thenable); |
|
|||
44 | } |
|
|||
45 |
|
||||
46 | void Chain(IPromise<T> thenable) { |
|
|||
47 | try { |
|
42 | try { | |
48 | thenable.Then(this); |
|
43 | thenable.Then(this); | |
49 | } catch (Exception err) { |
|
44 | } catch (Exception err) { |
@@ -3,16 +3,19 using System.Reflection; | |||||
3 | using System.Runtime.ExceptionServices; |
|
3 | using System.Runtime.ExceptionServices; | |
4 |
|
4 | |||
5 | namespace Implab { |
|
5 | namespace Implab { | |
6 |
|
|
6 | static class ExceptionHelpers { | |
7 |
public static |
|
7 | public static Exception Rethrow(this Exception that) { | |
8 | ExceptionDispatchInfo.Capture(that).Throw(); |
|
8 | ExceptionDispatchInfo.Capture(that).Throw(); | |
|
9 | return new TargetInvocationException(that); | |||
9 | } |
|
10 | } | |
10 |
|
11 | |||
11 |
public static |
|
12 | public static Exception Wrap(this Exception that) { | |
12 |
if (that |
|
13 | if (that == null) | |
13 | throw new OperationCanceledException("Operation cancelled", that); |
|
14 | return new Exception(); | |
|
15 | else if (that is OperationCanceledException) | |||
|
16 | return new OperationCanceledException("The operation has been cancelled", that); | |||
14 | else |
|
17 | else | |
15 |
|
|
18 | return new TargetInvocationException(that); | |
16 | } |
|
19 | } | |
17 | } |
|
20 | } | |
18 | } No newline at end of file |
|
21 | } |
@@ -169,8 +169,7 namespace Implab { | |||||
169 | public static IPromise<T> Create<T>(PromiseExecutor<T> executor) { |
|
169 | public static IPromise<T> Create<T>(PromiseExecutor<T> executor) { | |
170 | Safe.ArgumentNotNull(executor, nameof(executor)); |
|
170 | Safe.ArgumentNotNull(executor, nameof(executor)); | |
171 |
|
171 | |||
172 |
var |
|
172 | var d = new Deferred<T>(); | |
173 | var d = new Deferred<T>(p, DefaultDispatcher); |
|
|||
174 |
|
173 | |||
175 | try { |
|
174 | try { | |
176 | executor(d); |
|
175 | executor(d); | |
@@ -182,7 +181,7 namespace Implab { | |||||
182 | } |
|
181 | } | |
183 |
|
182 | |||
184 | public static IPromise All(IEnumerable<IPromise> promises) { |
|
183 | public static IPromise All(IEnumerable<IPromise> promises) { | |
185 |
var d = new Deferred( |
|
184 | var d = new Deferred(); | |
186 | var all = new PromiseAll(d); |
|
185 | var all = new PromiseAll(d); | |
187 | foreach (var promise in promises) { |
|
186 | foreach (var promise in promises) { | |
188 | all.AddPromise(promise); |
|
187 | all.AddPromise(promise); | |
@@ -193,8 +192,8 namespace Implab { | |||||
193 | return all.ResultPromise; |
|
192 | return all.ResultPromise; | |
194 | } |
|
193 | } | |
195 |
|
194 | |||
196 | public static IPromise<T[]> All<T>(IEnumerable<IPromise<T>> promises, Func<T, IPromise> cleanup, Action cancel) { |
|
195 | public static IPromise<T[]> All<T>(IEnumerable<IPromise<T>> promises, Func<T, IPromise> cleanup = null, Action cancel = null) { | |
197 |
var d = new Deferred<T[]>( |
|
196 | var d = new Deferred<T[]>(); | |
198 | var all = new PromiseAll<T>(d, cleanup, cancel); |
|
197 | var all = new PromiseAll<T>(d, cleanup, cancel); | |
199 | foreach (var promise in promises) { |
|
198 | foreach (var promise in promises) { | |
200 | all.AddPromise(promise); |
|
199 | all.AddPromise(promise); |
@@ -2,56 +2,91 using System; | |||||
2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
3 |
|
3 | |||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 |
class PromiseActionReaction : |
|
5 | class PromiseActionReaction : IResolvable { | |
6 |
|
6 | |||
7 | readonly Deferred m_next; |
|
7 | readonly Deferred m_next; | |
8 |
|
8 | |||
|
9 | readonly IDispatcher m_dispatcher; | |||
|
10 | ||||
|
11 | readonly Action<Deferred> m_fulfilled; | |||
|
12 | ||||
|
13 | readonly Action<Exception, Deferred> m_rejected; | |||
|
14 | ||||
9 | public IPromise Promise { |
|
15 | public IPromise Promise { | |
10 | get { return m_next.Promise; } |
|
16 | get { return m_next.Promise; } | |
11 | } |
|
17 | } | |
12 |
|
18 | |||
13 |
public PromiseActionReaction(Action fulfilled, Action<Exception> rejected, IDispatcher dispatcher) |
|
19 | public PromiseActionReaction(Action<Deferred> fulfilled, Action<Exception, Deferred> rejected, Deferred next, IDispatcher dispatcher) { | |
14 |
m_next = ne |
|
20 | m_next = next; | |
15 |
|
|
21 | m_fulfilled = fulfilled; | |
16 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
22 | m_rejected = rejected; | |
17 |
|
23 | m_dispatcher = dispatcher; | ||
18 | if (rejected != null) |
|
|||
19 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
|||
20 | } |
|
24 | } | |
21 |
|
25 | |||
22 | public PromiseActionReaction(Func<IPromise> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
26 | public void Resolve() { | |
23 | m_next = new Deferred(dispatcher); |
|
27 | if (m_fulfilled != null) { | |
24 |
if ( |
|
28 | if (m_dispatcher != null) | |
25 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
29 | m_dispatcher.Enqueue(ResolveImpl); | |
|
30 | else | |||
|
31 | ResolveImpl(); | |||
|
32 | } else { | |||
|
33 | m_next.Resolve(); | |||
|
34 | } | |||
|
35 | } | |||
26 |
|
36 | |||
27 | if (rejected != null) |
|
37 | void ResolveImpl() { | |
28 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
38 | m_fulfilled(m_next); | |
|
39 | } | |||
|
40 | ||||
|
41 | public void Reject(Exception error) { | |||
|
42 | if (m_fulfilled != null) { | |||
|
43 | if (m_dispatcher != null) | |||
|
44 | m_dispatcher.Enqueue(RejectImpl, error); | |||
|
45 | else | |||
|
46 | RejectImpl(error); | |||
|
47 | } else { | |||
|
48 | m_next.Reject(error); | |||
|
49 | } | |||
29 | } |
|
50 | } | |
30 |
|
51 | |||
31 | public PromiseActionReaction(Action fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
52 | void RejectImpl(Exception error) { | |
32 | m_next = new Deferred(dispatcher); |
|
53 | m_rejected(error, m_next); | |
33 | if (fulfilled != null) |
|
54 | } | |
34 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
|||
35 |
|
55 | |||
36 | if (rejected != null) |
|
56 | public static PromiseActionReaction Create(Action fulfilled, Action<Exception> rejected, IDispatcher dispatcher) { | |
37 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
57 | return new PromiseActionReaction( | |
|
58 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
59 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
60 | new Deferred(), | |||
|
61 | dispatcher | |||
|
62 | ); | |||
38 | } |
|
63 | } | |
39 |
|
64 | |||
40 |
public PromiseActionReaction(Func<IPromise> fulfilled, Action<Exception> rejected, IDispatcher dispatcher) |
|
65 | public static PromiseActionReaction Create(Func<IPromise> fulfilled, Action<Exception> rejected, IDispatcher dispatcher) { | |
41 | m_next = new Deferred(dispatcher); |
|
66 | return new PromiseActionReaction( | |
42 | if (fulfilled != null) |
|
67 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |
43 |
|
|
68 | rejected != null ? PromiseHandler.Create(rejected) : null, | |
44 |
|
69 | new Deferred(), | ||
45 | if (rejected != null) |
|
70 | dispatcher | |
46 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
71 | ); | |
47 | } |
|
72 | } | |
48 |
|
73 | |||
49 | protected override void DefaultReject(Exception reason) { |
|
74 | public static PromiseActionReaction Create(Action fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) { | |
50 | m_next.Reject(reason); |
|
75 | return new PromiseActionReaction( | |
|
76 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
77 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
78 | new Deferred(), | |||
|
79 | dispatcher | |||
|
80 | ); | |||
51 | } |
|
81 | } | |
52 |
|
82 | |||
53 | protected override void DefaultResolve() { |
|
83 | public static PromiseActionReaction Create(Func<IPromise> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) { | |
54 | m_next.Resolve(); |
|
84 | return new PromiseActionReaction( | |
|
85 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
86 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
87 | new Deferred(), | |||
|
88 | dispatcher | |||
|
89 | ); | |||
55 | } |
|
90 | } | |
56 | } |
|
91 | } | |
57 | } No newline at end of file |
|
92 | } |
@@ -2,55 +2,90 using System; | |||||
2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
3 |
|
3 | |||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 |
class PromiseActionReaction<T> : |
|
5 | class PromiseActionReaction<T> : IResolvable<T> { | |
6 | readonly Deferred m_next; |
|
6 | readonly Deferred m_next; | |
7 |
|
7 | |||
|
8 | readonly IDispatcher m_dispatcher; | |||
|
9 | ||||
|
10 | readonly Action<T, Deferred> m_fulfilled; | |||
|
11 | ||||
|
12 | readonly Action<Exception, Deferred> m_rejected; | |||
|
13 | ||||
8 | public IPromise Promise { |
|
14 | public IPromise Promise { | |
9 | get { return m_next.Promise; } |
|
15 | get { return m_next.Promise; } | |
10 | } |
|
16 | } | |
11 |
|
17 | |||
12 |
public PromiseActionReaction(Action<T> fulfilled, Action<Exception> rejected, IDispatcher dispatcher) |
|
18 | public PromiseActionReaction(Action<T, Deferred> fulfilled, Action<Exception, Deferred> rejected, Deferred next, IDispatcher dispatcher) { | |
13 |
m_next = ne |
|
19 | m_next = next; | |
14 |
|
|
20 | m_fulfilled = fulfilled; | |
15 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
21 | m_rejected = rejected; | |
16 |
|
22 | m_dispatcher = dispatcher; | ||
17 | if (rejected != null) |
|
|||
18 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
|||
19 | } |
|
23 | } | |
20 |
|
24 | |||
21 | public PromiseActionReaction(Func<T, IPromise> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
25 | public void Resolve(T result) { | |
22 | m_next = new Deferred(dispatcher); |
|
26 | if (m_fulfilled != null) { | |
23 |
if ( |
|
27 | if (m_dispatcher != null) | |
24 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
28 | m_dispatcher.Enqueue(ResolveImpl, result); | |
|
29 | else | |||
|
30 | ResolveImpl(result); | |||
|
31 | } else { | |||
|
32 | m_next.Resolve(); | |||
|
33 | } | |||
|
34 | } | |||
25 |
|
35 | |||
26 | if (rejected != null) |
|
36 | void ResolveImpl (T result) { | |
27 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
37 | m_fulfilled(result, m_next); | |
|
38 | } | |||
|
39 | ||||
|
40 | public void Reject(Exception error) { | |||
|
41 | if (m_fulfilled != null) { | |||
|
42 | if (m_dispatcher != null) | |||
|
43 | m_dispatcher.Enqueue(RejectImpl, error); | |||
|
44 | else | |||
|
45 | RejectImpl(error); | |||
|
46 | } else { | |||
|
47 | m_next.Reject(error); | |||
|
48 | } | |||
28 | } |
|
49 | } | |
29 |
|
50 | |||
30 | public PromiseActionReaction(Action<T> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
51 | void RejectImpl(Exception error) { | |
31 | m_next = new Deferred(dispatcher); |
|
52 | m_rejected(error, m_next); | |
32 | if (fulfilled != null) |
|
53 | } | |
33 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
|||
34 |
|
54 | |||
35 | if (rejected != null) |
|
55 | public static PromiseActionReaction<T> Create(Action<T> fulfilled, Action<Exception> rejected, IDispatcher dispatcher) { | |
36 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
56 | return new PromiseActionReaction<T>( | |
|
57 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
58 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
59 | new Deferred(), | |||
|
60 | dispatcher | |||
|
61 | ); | |||
37 | } |
|
62 | } | |
38 |
|
63 | |||
39 |
public PromiseActionReaction(Func<T, |
|
64 | public static PromiseActionReaction<T> Create(Func<T,IPromise> fulfilled, Action<Exception> rejected, IDispatcher dispatcher) { | |
40 | m_next = new Deferred(dispatcher); |
|
65 | return new PromiseActionReaction<T>( | |
41 | if (fulfilled != null) |
|
66 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |
42 |
|
|
67 | rejected != null ? PromiseHandler.Create(rejected) : null, | |
43 |
|
68 | new Deferred(), | ||
44 | if (rejected != null) |
|
69 | dispatcher | |
45 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
70 | ); | |
46 | } |
|
71 | } | |
47 |
|
72 | |||
48 | protected override void DefaultReject(Exception reason) { |
|
73 | public static PromiseActionReaction<T> Create(Action<T> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) { | |
49 | m_next.Reject(reason); |
|
74 | return new PromiseActionReaction<T>( | |
|
75 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
76 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
77 | new Deferred(), | |||
|
78 | dispatcher | |||
|
79 | ); | |||
50 | } |
|
80 | } | |
51 |
|
81 | |||
52 | protected override void DefaultResolve(T result) { |
|
82 | public static PromiseActionReaction<T> Create(Func<T,IPromise> fulfilled, Func<Exception, IPromise> rejected, IDispatcher dispatcher) { | |
53 | m_next.Resolve(); |
|
83 | return new PromiseActionReaction<T>( | |
|
84 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
85 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
86 | new Deferred(), | |||
|
87 | dispatcher | |||
|
88 | ); | |||
54 | } |
|
89 | } | |
55 | } |
|
90 | } | |
56 | } No newline at end of file |
|
91 | } |
@@ -8,97 +8,145 namespace Implab { | |||||
8 | public static class PromiseExtensions { |
|
8 | public static class PromiseExtensions { | |
9 |
|
9 | |||
10 | public static IPromise Then(this IPromise that, Action fulfilled, Action<Exception> rejected) { |
|
10 | public static IPromise Then(this IPromise that, Action fulfilled, Action<Exception> rejected) { | |
11 |
var reaction = |
|
11 | var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
12 | that.Then(reaction); | |||
|
13 | return reaction.Promise; | |||
|
14 | } | |||
|
15 | ||||
|
16 | public static IPromise Then(this IPromise that, Action fulfilled) { | |||
|
17 | var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher); | |||
12 | that.Then(reaction); |
|
18 | that.Then(reaction); | |
13 | return reaction.Promise; |
|
19 | return reaction.Promise; | |
14 | } |
|
20 | } | |
15 |
|
21 | |||
16 | public static IPromise Then(this IPromise that, Action fulfilled, Func<Exception, IPromise> rejected) { |
|
22 | public static IPromise Then(this IPromise that, Action fulfilled, Func<Exception, IPromise> rejected) { | |
17 |
var reaction = |
|
23 | var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
18 | that.Then(reaction); |
|
24 | that.Then(reaction); | |
19 | return reaction.Promise; |
|
25 | return reaction.Promise; | |
20 | } |
|
26 | } | |
21 |
|
27 | |||
22 | public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Action<Exception> rejected) { |
|
28 | public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Action<Exception> rejected) { | |
23 |
var reaction = |
|
29 | var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
30 | that.Then(reaction); | |||
|
31 | return reaction.Promise; | |||
|
32 | } | |||
|
33 | ||||
|
34 | public static IPromise Then(this IPromise that, Func<IPromise> fulfilled) { | |||
|
35 | var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher); | |||
24 | that.Then(reaction); |
|
36 | that.Then(reaction); | |
25 | return reaction.Promise; |
|
37 | return reaction.Promise; | |
26 | } |
|
38 | } | |
27 |
|
39 | |||
28 | public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Func<Exception, IPromise> rejected) { |
|
40 | public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Func<Exception, IPromise> rejected) { | |
29 |
var reaction = |
|
41 | var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
30 | that.Then(reaction); |
|
42 | that.Then(reaction); | |
31 | return reaction.Promise; |
|
43 | return reaction.Promise; | |
32 | } |
|
44 | } | |
33 |
|
45 | |||
34 | public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Action<Exception> rejected) { |
|
46 | public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Action<Exception> rejected) { | |
35 |
var reaction = |
|
47 | var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
48 | that.Then(reaction); | |||
|
49 | return reaction.Promise; | |||
|
50 | } | |||
|
51 | ||||
|
52 | public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled) { | |||
|
53 | var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher); | |||
36 | that.Then(reaction); |
|
54 | that.Then(reaction); | |
37 | return reaction.Promise; |
|
55 | return reaction.Promise; | |
38 | } |
|
56 | } | |
39 |
|
57 | |||
40 | public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Func<Exception, IPromise> rejected) { |
|
58 | public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Func<Exception, IPromise> rejected) { | |
41 |
var reaction = |
|
59 | var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
42 | that.Then(reaction); |
|
60 | that.Then(reaction); | |
43 | return reaction.Promise; |
|
61 | return reaction.Promise; | |
44 | } |
|
62 | } | |
45 |
|
63 | |||
46 | public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Action<Exception> rejected) { |
|
64 | public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Action<Exception> rejected) { | |
47 |
var reaction = |
|
65 | var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
66 | that.Then(reaction); | |||
|
67 | return reaction.Promise; | |||
|
68 | } | |||
|
69 | ||||
|
70 | public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled) { | |||
|
71 | var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher); | |||
48 | that.Then(reaction); |
|
72 | that.Then(reaction); | |
49 | return reaction.Promise; |
|
73 | return reaction.Promise; | |
50 | } |
|
74 | } | |
51 |
|
75 | |||
52 | public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Func<Exception, IPromise> rejected) { |
|
76 | public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Func<Exception, IPromise> rejected) { | |
53 |
var reaction = |
|
77 | var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
54 | that.Then(reaction); |
|
78 | that.Then(reaction); | |
55 | return reaction.Promise; |
|
79 | return reaction.Promise; | |
56 | } |
|
80 | } | |
57 |
|
81 | |||
58 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, Tout> rejected) { |
|
82 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, Tout> rejected) { | |
59 |
var reaction = |
|
83 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
84 | that.Then(reaction); | |||
|
85 | return reaction.Promise; | |||
|
86 | } | |||
|
87 | ||||
|
88 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled) { | |||
|
89 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher); | |||
60 | that.Then(reaction); |
|
90 | that.Then(reaction); | |
61 | return reaction.Promise; |
|
91 | return reaction.Promise; | |
62 | } |
|
92 | } | |
63 |
|
93 | |||
64 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) { |
|
94 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) { | |
65 |
var reaction = |
|
95 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
66 | that.Then(reaction); |
|
96 | that.Then(reaction); | |
67 | return reaction.Promise; |
|
97 | return reaction.Promise; | |
68 | } |
|
98 | } | |
69 |
|
99 | |||
70 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) { |
|
100 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) { | |
71 |
var reaction = |
|
101 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
102 | that.Then(reaction); | |||
|
103 | return reaction.Promise; | |||
|
104 | } | |||
|
105 | ||||
|
106 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled) { | |||
|
107 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher); | |||
72 | that.Then(reaction); |
|
108 | that.Then(reaction); | |
73 | return reaction.Promise; |
|
109 | return reaction.Promise; | |
74 | } |
|
110 | } | |
75 |
|
111 | |||
76 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) { |
|
112 | public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) { | |
77 |
var reaction = |
|
113 | var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
78 | that.Then(reaction); |
|
114 | that.Then(reaction); | |
79 | return reaction.Promise; |
|
115 | return reaction.Promise; | |
80 | } |
|
116 | } | |
81 |
|
117 | |||
82 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, Tout> rejected) { |
|
118 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, Tout> rejected) { | |
83 |
var reaction = |
|
119 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
120 | that.Then(reaction); | |||
|
121 | return reaction.Promise; | |||
|
122 | } | |||
|
123 | ||||
|
124 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled) { | |||
|
125 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher); | |||
84 | that.Then(reaction); |
|
126 | that.Then(reaction); | |
85 | return reaction.Promise; |
|
127 | return reaction.Promise; | |
86 | } |
|
128 | } | |
87 |
|
129 | |||
88 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) { |
|
130 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) { | |
89 |
var reaction = |
|
131 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
90 | that.Then(reaction); |
|
132 | that.Then(reaction); | |
91 | return reaction.Promise; |
|
133 | return reaction.Promise; | |
92 | } |
|
134 | } | |
93 |
|
135 | |||
94 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) { |
|
136 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) { | |
95 |
var reaction = |
|
137 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
|
138 | that.Then(reaction); | |||
|
139 | return reaction.Promise; | |||
|
140 | } | |||
|
141 | ||||
|
142 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled) { | |||
|
143 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher); | |||
96 | that.Then(reaction); |
|
144 | that.Then(reaction); | |
97 | return reaction.Promise; |
|
145 | return reaction.Promise; | |
98 | } |
|
146 | } | |
99 |
|
147 | |||
100 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) { |
|
148 | public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) { | |
101 |
var reaction = |
|
149 | var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher); | |
102 | that.Then(reaction); |
|
150 | that.Then(reaction); | |
103 | return reaction.Promise; |
|
151 | return reaction.Promise; | |
104 | } |
|
152 | } | |
@@ -126,6 +174,44 namespace Implab { | |||||
126 | public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, IPromise<Tout>> rejected) { |
|
174 | public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, IPromise<Tout>> rejected) { | |
127 | return Then(that, (Func<Tin, Tout>)null, rejected); |
|
175 | return Then(that, (Func<Tin, Tout>)null, rejected); | |
128 | } |
|
176 | } | |
|
177 | ||||
|
178 | public static IPromise Finally(this IPromise that, Action final) { | |||
|
179 | return Then(that, final, e => { | |||
|
180 | final(); | |||
|
181 | throw e.Rethrow(); | |||
|
182 | }); | |||
|
183 | } | |||
|
184 | ||||
|
185 | public static IPromise Finally(this IPromise that, Func<IPromise> final) { | |||
|
186 | return Then(that, final, e => { | |||
|
187 | final(); | |||
|
188 | throw e.Rethrow(); | |||
|
189 | }); | |||
|
190 | } | |||
|
191 | ||||
|
192 | public static IPromise<T> Finally<T>(this IPromise<T> that, Action final) { | |||
|
193 | return Then<T, T>(that, x => { | |||
|
194 | final(); | |||
|
195 | return x; | |||
|
196 | }, new Func<Exception, T>(e => { | |||
|
197 | final(); | |||
|
198 | throw e.Rethrow(); | |||
|
199 | })); | |||
|
200 | } | |||
|
201 | ||||
|
202 | public static IPromise<T> Finally<T>(this IPromise<T> that, Func<IPromise> final) { | |||
|
203 | return Then<T, T>(that, x => { | |||
|
204 | return final() | |||
|
205 | .Then(() => x); | |||
|
206 | }, new Func<Exception, IPromise<T>>(e => { | |||
|
207 | return final() | |||
|
208 | .Then(new Func<T>(() => { | |||
|
209 | throw e.Rethrow(); | |||
|
210 | })); | |||
|
211 | })); | |||
|
212 | } | |||
|
213 | ||||
|
214 | ||||
129 | } |
|
215 | } | |
130 | } |
|
216 | } | |
131 |
|
217 |
@@ -2,55 +2,90 using System; | |||||
2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
3 |
|
3 | |||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 |
class PromiseFuncReaction<TRet> : |
|
5 | class PromiseFuncReaction<TRet> : IResolvable { | |
6 | readonly Deferred<TRet> m_next; |
|
6 | readonly Deferred<TRet> m_next; | |
7 |
|
7 | |||
|
8 | readonly IDispatcher m_dispatcher; | |||
|
9 | ||||
|
10 | readonly Action<Deferred<TRet>> m_fulfilled; | |||
|
11 | ||||
|
12 | readonly Action<Exception, Deferred<TRet>> m_rejected; | |||
|
13 | ||||
8 | public IPromise<TRet> Promise { |
|
14 | public IPromise<TRet> Promise { | |
9 | get { return m_next.Promise; } |
|
15 | get { return m_next.Promise; } | |
10 | } |
|
16 | } | |
11 |
|
17 | |||
12 |
public PromiseFuncReaction( |
|
18 | public PromiseFuncReaction(Action<Deferred<TRet>> fulfilled, Action<Exception, Deferred<TRet>> rejected, Deferred<TRet> next, IDispatcher dispatcher) { | |
13 |
m_next = ne |
|
19 | m_next = next; | |
14 |
|
|
20 | m_fulfilled = fulfilled; | |
15 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
21 | m_rejected = rejected; | |
16 |
|
22 | m_dispatcher = dispatcher; | ||
17 | if (rejected != null) |
|
|||
18 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
|||
19 | } |
|
23 | } | |
20 |
|
24 | |||
21 | public PromiseFuncReaction(Func<IPromise<TRet>> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
25 | public void Resolve() { | |
22 | m_next = new Deferred<TRet>(dispatcher); |
|
26 | if (m_fulfilled != null) { | |
23 |
if ( |
|
27 | if (m_dispatcher != null) | |
24 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
28 | m_dispatcher.Enqueue(ResolveImpl); | |
|
29 | else | |||
|
30 | ResolveImpl(); | |||
|
31 | } else { | |||
|
32 | m_next.Resolve(default(TRet)); | |||
|
33 | } | |||
|
34 | } | |||
25 |
|
35 | |||
26 | if (rejected != null) |
|
36 | void ResolveImpl () { | |
27 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
37 | m_fulfilled(m_next); | |
|
38 | } | |||
|
39 | ||||
|
40 | public void Reject(Exception error) { | |||
|
41 | if (m_fulfilled != null) { | |||
|
42 | if (m_dispatcher != null) | |||
|
43 | m_dispatcher.Enqueue(RejectImpl, error); | |||
|
44 | else | |||
|
45 | RejectImpl(error); | |||
|
46 | } else { | |||
|
47 | m_next.Reject(error); | |||
|
48 | } | |||
28 | } |
|
49 | } | |
29 |
|
50 | |||
30 | public PromiseFuncReaction(Func<TRet> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
51 | void RejectImpl(Exception error) { | |
31 | m_next = new Deferred<TRet>(dispatcher); |
|
52 | m_rejected(error, m_next); | |
32 | if (fulfilled != null) |
|
53 | } | |
33 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
|||
34 |
|
54 | |||
35 | if (rejected != null) |
|
55 | public static PromiseFuncReaction<TRet> Create(Func<TRet> fulfilled, Func<Exception, TRet> rejected, IDispatcher dispatcher) { | |
36 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
56 | return new PromiseFuncReaction<TRet>( | |
|
57 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
58 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
59 | new Deferred<TRet>(), | |||
|
60 | dispatcher | |||
|
61 | ); | |||
37 | } |
|
62 | } | |
38 |
|
63 | |||
39 |
public PromiseFuncReaction(Func<IPromise<TRet>> fulfilled, Func<Exception, TRet> rejected, IDispatcher dispatcher) |
|
64 | public static PromiseFuncReaction<TRet> Create(Func<IPromise<TRet>> fulfilled, Func<Exception, TRet> rejected, IDispatcher dispatcher) { | |
40 | m_next = new Deferred<TRet>(dispatcher); |
|
65 | return new PromiseFuncReaction<TRet>( | |
41 | if (fulfilled != null) |
|
66 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |
42 |
|
|
67 | rejected != null ? PromiseHandler.Create(rejected) : null, | |
43 |
|
68 | new Deferred<TRet>(), | ||
44 | if (rejected != null) |
|
69 | dispatcher | |
45 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
70 | ); | |
46 | } |
|
71 | } | |
47 |
|
72 | |||
48 | protected override void DefaultReject(Exception reason) { |
|
73 | public static PromiseFuncReaction<TRet> Create(Func<TRet> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) { | |
49 | m_next.Reject(reason); |
|
74 | return new PromiseFuncReaction<TRet>( | |
|
75 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
76 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
77 | new Deferred<TRet>(), | |||
|
78 | dispatcher | |||
|
79 | ); | |||
50 | } |
|
80 | } | |
51 |
|
81 | |||
52 | protected override void DefaultResolve() { |
|
82 | public static PromiseFuncReaction<TRet> Create(Func<IPromise<TRet>> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) { | |
53 | throw new NotImplementedException(); |
|
83 | return new PromiseFuncReaction<TRet>( | |
|
84 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
85 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
86 | new Deferred<TRet>(), | |||
|
87 | dispatcher | |||
|
88 | ); | |||
54 | } |
|
89 | } | |
55 | } |
|
90 | } | |
56 | } No newline at end of file |
|
91 | } |
@@ -2,55 +2,96 using System; | |||||
2 | using System.Diagnostics; |
|
2 | using System.Diagnostics; | |
3 |
|
3 | |||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 |
class PromiseFuncReaction<TIn, TRet> : |
|
5 | class PromiseFuncReaction<TIn, TRet> : IResolvable<TIn> { | |
6 | readonly Deferred<TRet> m_next; |
|
6 | readonly Deferred<TRet> m_next; | |
7 |
|
7 | |||
8 | public IPromise<TRet> Promise { |
|
8 | readonly IDispatcher m_dispatcher; | |
|
9 | ||||
|
10 | readonly Action<TIn, Deferred<TRet>> m_fulfilled; | |||
|
11 | ||||
|
12 | readonly Action<Exception, Deferred<TRet>> m_rejected; | |||
|
13 | ||||
|
14 | public IPromise<TRet> Promise { | |||
9 | get { return m_next.Promise; } |
|
15 | get { return m_next.Promise; } | |
10 | } |
|
16 | } | |
11 |
|
17 | |||
12 |
public PromiseFuncReaction( |
|
18 | public PromiseFuncReaction(Action<TIn, Deferred<TRet>> fulfilled, Action<Exception, Deferred<TRet>> rejected, Deferred<TRet> next, IDispatcher dispatcher) { | |
13 |
m_next = ne |
|
19 | m_next = next; | |
14 |
|
|
20 | m_fulfilled = fulfilled; | |
15 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
21 | m_rejected = rejected; | |
16 |
|
22 | m_dispatcher = dispatcher; | ||
17 | if (rejected != null) |
|
|||
18 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
|||
19 | } |
|
23 | } | |
20 |
|
24 | |||
21 | public PromiseFuncReaction(Func<TIn, IPromise<TRet>> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
25 | public void Resolve(TIn result) { | |
22 | m_next = new Deferred<TRet>(dispatcher); |
|
26 | if (m_fulfilled != null) { | |
23 |
if ( |
|
27 | if (m_dispatcher != null) | |
24 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
28 | m_dispatcher.Enqueue(ResolveImpl, result); | |
|
29 | else | |||
|
30 | ResolveImpl(result); | |||
|
31 | } else { | |||
|
32 | try { | |||
|
33 | m_next.Resolve((TRet)(object)result); | |||
|
34 | } catch(Exception error) { | |||
|
35 | // handle cast exceptions | |||
|
36 | m_next.Reject(error); | |||
|
37 | } | |||
|
38 | } | |||
|
39 | } | |||
25 |
|
40 | |||
26 | if (rejected != null) |
|
41 | void ResolveImpl (TIn result) { | |
27 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
42 | m_fulfilled(result, m_next); | |
|
43 | } | |||
|
44 | ||||
|
45 | public void Reject(Exception error) { | |||
|
46 | if (m_fulfilled != null) { | |||
|
47 | if (m_dispatcher != null) | |||
|
48 | m_dispatcher.Enqueue(RejectImpl, error); | |||
|
49 | else | |||
|
50 | RejectImpl(error); | |||
|
51 | } else { | |||
|
52 | m_next.Reject(error); | |||
|
53 | } | |||
28 | } |
|
54 | } | |
29 |
|
55 | |||
30 | public PromiseFuncReaction(Func<TIn, TRet> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) : base(dispatcher) { |
|
56 | void RejectImpl(Exception error) { | |
31 | m_next = new Deferred<TRet>(dispatcher); |
|
57 | m_rejected(error, m_next); | |
32 | if (fulfilled != null) |
|
58 | } | |
33 | FulfilHandler = PromiseHandler.Create(fulfilled, m_next); |
|
59 | ||
34 |
|
60 | |||
35 | if (rejected != null) |
|
61 | public static PromiseFuncReaction<TIn,TRet> Create(Func<TIn,TRet> fulfilled, Func<Exception, TRet> rejected, IDispatcher dispatcher) { | |
36 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
62 | return new PromiseFuncReaction<TIn,TRet>( | |
|
63 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
64 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
65 | new Deferred<TRet>(), | |||
|
66 | dispatcher | |||
|
67 | ); | |||
37 | } |
|
68 | } | |
38 |
|
69 | |||
39 |
public PromiseFuncReaction(Func<TIn, |
|
70 | public static PromiseFuncReaction<TIn,TRet> Create(Func<TIn,IPromise<TRet>> fulfilled, Func<Exception, TRet> rejected, IDispatcher dispatcher) { | |
40 | m_next = new Deferred<TRet>(dispatcher); |
|
71 | return new PromiseFuncReaction<TIn,TRet>( | |
41 | if (fulfilled != null) |
|
72 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |
42 |
|
|
73 | rejected != null ? PromiseHandler.Create(rejected) : null, | |
43 |
|
74 | new Deferred<TRet>(), | ||
44 | if (rejected != null) |
|
75 | dispatcher | |
45 | RejectHandler = PromiseHandler.Create(rejected, m_next); |
|
76 | ); | |
46 | } |
|
77 | } | |
47 |
|
78 | |||
48 | protected override void DefaultReject(Exception reason) { |
|
79 | public static PromiseFuncReaction<TIn,TRet> Create(Func<TIn,TRet> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) { | |
49 | m_next.Reject(reason); |
|
80 | return new PromiseFuncReaction<TIn,TRet>( | |
|
81 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
82 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
83 | new Deferred<TRet>(), | |||
|
84 | dispatcher | |||
|
85 | ); | |||
50 | } |
|
86 | } | |
51 |
|
87 | |||
52 | protected override void DefaultResolve(TIn result) { |
|
88 | public static PromiseFuncReaction<TIn,TRet> Create(Func<TIn,IPromise<TRet>> fulfilled, Func<Exception, IPromise<TRet>> rejected, IDispatcher dispatcher) { | |
53 | m_next.Resolve((TRet)(object)result); |
|
89 | return new PromiseFuncReaction<TIn,TRet>( | |
|
90 | fulfilled != null ? PromiseHandler.Create(fulfilled) : null, | |||
|
91 | rejected != null ? PromiseHandler.Create(rejected) : null, | |||
|
92 | new Deferred<TRet>(), | |||
|
93 | dispatcher | |||
|
94 | ); | |||
54 | } |
|
95 | } | |
55 | } |
|
96 | } | |
56 | } No newline at end of file |
|
97 | } |
@@ -3,10 +3,10 using System.Diagnostics; | |||||
3 |
|
3 | |||
4 | namespace Implab { |
|
4 | namespace Implab { | |
5 | class PromiseHandler { |
|
5 | class PromiseHandler { | |
6 |
public static Action<T> Create<T>(Action<T> handler |
|
6 | public static Action<T, Deferred> Create<T>(Action<T> handler) { | |
7 | Debug.Assert(handler != null); |
|
7 | Debug.Assert(handler != null); | |
8 |
|
8 | |||
9 | return (v) => { |
|
9 | return (v, next) => { | |
10 | try { |
|
10 | try { | |
11 | handler(v); |
|
11 | handler(v); | |
12 | next.Resolve(); |
|
12 | next.Resolve(); | |
@@ -16,10 +16,10 namespace Implab { | |||||
16 | }; |
|
16 | }; | |
17 | } |
|
17 | } | |
18 |
|
18 | |||
19 |
public static Action<T> Create<T>(Func<T, IPromise> handler |
|
19 | public static Action<T, Deferred> Create<T>(Func<T, IPromise> handler) { | |
20 | Debug.Assert(handler != null); |
|
20 | Debug.Assert(handler != null); | |
21 |
|
21 | |||
22 | return (v) => { |
|
22 | return (v, next) => { | |
23 | try { |
|
23 | try { | |
24 | next.Resolve(handler(v)); |
|
24 | next.Resolve(handler(v)); | |
25 | } catch (Exception err) { |
|
25 | } catch (Exception err) { | |
@@ -28,10 +28,10 namespace Implab { | |||||
28 | }; |
|
28 | }; | |
29 | } |
|
29 | } | |
30 |
|
30 | |||
31 |
public static Action<T> Create<T, T2>(Func<T, T2> handler |
|
31 | public static Action<T, Deferred<T2>> Create<T, T2>(Func<T, T2> handler) { | |
32 | Debug.Assert(handler != null); |
|
32 | Debug.Assert(handler != null); | |
33 |
|
33 | |||
34 | return (v) => { |
|
34 | return (v, next) => { | |
35 | try { |
|
35 | try { | |
36 | next.Resolve(handler(v)); |
|
36 | next.Resolve(handler(v)); | |
37 | } catch (Exception err) { |
|
37 | } catch (Exception err) { | |
@@ -40,9 +40,9 namespace Implab { | |||||
40 | }; |
|
40 | }; | |
41 | } |
|
41 | } | |
42 |
|
42 | |||
43 |
public static Action<T> Create<T, T2>(Func<T, IPromise<T2>> handler |
|
43 | public static Action<T, Deferred<T2>> Create<T, T2>(Func<T, IPromise<T2>> handler) { | |
44 | Debug.Assert(handler != null); |
|
44 | Debug.Assert(handler != null); | |
45 | return (v) => { |
|
45 | return (v, next) => { | |
46 | try { |
|
46 | try { | |
47 | next.Resolve(handler(v)); |
|
47 | next.Resolve(handler(v)); | |
48 | } catch (Exception err) { |
|
48 | } catch (Exception err) { | |
@@ -51,10 +51,10 namespace Implab { | |||||
51 | }; |
|
51 | }; | |
52 | } |
|
52 | } | |
53 |
|
53 | |||
54 |
public static Action Create(Action handler |
|
54 | public static Action<Deferred> Create(Action handler) { | |
55 | Debug.Assert(handler != null); |
|
55 | Debug.Assert(handler != null); | |
56 |
|
56 | |||
57 | return () => { |
|
57 | return (next) => { | |
58 | try { |
|
58 | try { | |
59 | handler(); |
|
59 | handler(); | |
60 | next.Resolve(); |
|
60 | next.Resolve(); | |
@@ -64,10 +64,10 namespace Implab { | |||||
64 | }; |
|
64 | }; | |
65 | } |
|
65 | } | |
66 |
|
66 | |||
67 |
public static Action Create(Func<IPromise> handler |
|
67 | public static Action<Deferred> Create(Func<IPromise> handler) { | |
68 | Debug.Assert(handler != null); |
|
68 | Debug.Assert(handler != null); | |
69 |
|
69 | |||
70 | return () => { |
|
70 | return (next) => { | |
71 | try { |
|
71 | try { | |
72 | next.Resolve(handler()); |
|
72 | next.Resolve(handler()); | |
73 | } catch (Exception err) { |
|
73 | } catch (Exception err) { | |
@@ -76,10 +76,10 namespace Implab { | |||||
76 | }; |
|
76 | }; | |
77 | } |
|
77 | } | |
78 |
|
78 | |||
79 |
public static Action Create<T2>(Func<T2> handler |
|
79 | public static Action<Deferred<T2>> Create<T2>(Func<T2> handler) { | |
80 | Debug.Assert(handler != null); |
|
80 | Debug.Assert(handler != null); | |
81 |
|
81 | |||
82 | return () => { |
|
82 | return (next) => { | |
83 | try { |
|
83 | try { | |
84 | next.Resolve(handler()); |
|
84 | next.Resolve(handler()); | |
85 | } catch (Exception err) { |
|
85 | } catch (Exception err) { | |
@@ -88,9 +88,9 namespace Implab { | |||||
88 | }; |
|
88 | }; | |
89 | } |
|
89 | } | |
90 |
|
90 | |||
91 |
public static Action Create<T2>(Func<IPromise<T2>> handler |
|
91 | public static Action<Deferred<T2>> Create<T2>(Func<IPromise<T2>> handler) { | |
92 | Debug.Assert(handler != null); |
|
92 | Debug.Assert(handler != null); | |
93 | return () => { |
|
93 | return (next) => { | |
94 | try { |
|
94 | try { | |
95 | next.Resolve(handler()); |
|
95 | next.Resolve(handler()); | |
96 | } catch (Exception err) { |
|
96 | } catch (Exception err) { |
@@ -24,11 +24,11 namespace Implab | |||||
24 | } |
|
24 | } | |
25 |
|
25 | |||
26 | public void Join() { |
|
26 | public void Join() { | |
27 |
m_reason. |
|
27 | throw m_reason.Wrap(); | |
28 | } |
|
28 | } | |
29 |
|
29 | |||
30 | public void Join(int timeout) { |
|
30 | public void Join(int timeout) { | |
31 |
m_reason. |
|
31 | throw m_reason.Wrap(); | |
32 | } |
|
32 | } | |
33 |
|
33 | |||
34 | public void Then(IResolvable next) { |
|
34 | public void Then(IResolvable next) { |
@@ -24,21 +24,19 namespace Implab | |||||
24 | } |
|
24 | } | |
25 |
|
25 | |||
26 | void IPromise.Join() { |
|
26 | void IPromise.Join() { | |
27 |
m_reason. |
|
27 | throw m_reason.Wrap(); | |
28 | } |
|
28 | } | |
29 |
|
29 | |||
30 | void IPromise.Join(int timeout) { |
|
30 | void IPromise.Join(int timeout) { | |
31 |
m_reason. |
|
31 | throw m_reason.Wrap(); | |
32 | } |
|
32 | } | |
33 |
|
33 | |||
34 | public T Join() { |
|
34 | public T Join() { | |
35 |
m_reason. |
|
35 | throw m_reason.Wrap(); | |
36 | throw new Exception(); // unreachable code |
|
|||
37 | } |
|
36 | } | |
38 |
|
37 | |||
39 | public T Join(int timeout) { |
|
38 | public T Join(int timeout) { | |
40 |
m_reason. |
|
39 | throw m_reason.Wrap(); | |
41 | throw new Exception(); // unreachable code |
|
|||
42 | } |
|
40 | } | |
43 |
|
41 | |||
44 | public void Then(IResolvable next) { |
|
42 | public void Then(IResolvable next) { |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
This diff has been collapsed as it changes many lines, (878 lines changed) Show them Hide them |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now