@@ -0,0 +1,30 | |||
|
1 | using System.Windows.Forms; | |
|
2 | using System; | |
|
3 | ||
|
4 | ||
|
5 | namespace Implab.Fx { | |
|
6 | public class ControlBoundPromise<T> : Promise<T> { | |
|
7 | readonly Control m_target; | |
|
8 | ||
|
9 | public ControlBoundPromise(Control target) { | |
|
10 | Safe.ArgumentNotNull(target, "target"); | |
|
11 | ||
|
12 | m_target = target; | |
|
13 | } | |
|
14 | ||
|
15 | public ControlBoundPromise(Control target, IPromise parent, bool cancellable) | |
|
16 | : base(parent, cancellable) { | |
|
17 | Safe.ArgumentNotNull(target, "target"); | |
|
18 | ||
|
19 | m_target = target; | |
|
20 | } | |
|
21 | ||
|
22 | protected override void InvokeHandler(HandlerDescriptor handler) { | |
|
23 | if (m_target.InvokeRequired) | |
|
24 | m_target.BeginInvoke(new Action<HandlerDescriptor>(base.InvokeHandler), handler); | |
|
25 | else | |
|
26 | base.InvokeHandler(handler); | |
|
27 | } | |
|
28 | } | |
|
29 | } | |
|
30 |
@@ -0,0 +1,38 | |||
|
1 | using System.Threading; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | public static class PromiseExtensions { | |
|
5 | public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) { | |
|
6 | var context = SynchronizationContext.Current; | |
|
7 | if (context == null) | |
|
8 | return that; | |
|
9 | ||
|
10 | var p = new SyncContextPromise<T>(context, that, true); | |
|
11 | ||
|
12 | that.Then( | |
|
13 | x => p.Resolve(x), | |
|
14 | e => { | |
|
15 | p.Reject(e); | |
|
16 | return default(T); | |
|
17 | } | |
|
18 | ); | |
|
19 | return p; | |
|
20 | } | |
|
21 | ||
|
22 | public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) { | |
|
23 | Safe.ArgumentNotNull(context, "context"); | |
|
24 | ||
|
25 | var p = new SyncContextPromise<T>(context, that, true); | |
|
26 | ||
|
27 | that.Then( | |
|
28 | x => p.Resolve(x), | |
|
29 | e => { | |
|
30 | p.Reject(e); | |
|
31 | return default(T); | |
|
32 | } | |
|
33 | ); | |
|
34 | return p; | |
|
35 | } | |
|
36 | } | |
|
37 | } | |
|
38 |
@@ -0,0 +1,22 | |||
|
1 | using System.Threading; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | public class SyncContextPromise<T> : Promise<T> { | |
|
5 | readonly SynchronizationContext m_context; | |
|
6 | ||
|
7 | public SyncContextPromise(SynchronizationContext context) { | |
|
8 | Safe.ArgumentNotNull(context, "context"); | |
|
9 | m_context = context; | |
|
10 | } | |
|
11 | ||
|
12 | public SyncContextPromise(SynchronizationContext context, IPromise parent, bool cancellable) | |
|
13 | : base(parent, cancellable) { | |
|
14 | Safe.ArgumentNotNull(context, "context"); | |
|
15 | m_context = context; | |
|
16 | } | |
|
17 | protected override void InvokeHandler(HandlerDescriptor handler) { | |
|
18 | m_context.Post(x => base.InvokeHandler(handler),null); | |
|
19 | } | |
|
20 | } | |
|
21 | } | |
|
22 |
@@ -0,0 +1,33 | |||
|
1 | using System; | |
|
2 | ||
|
3 | namespace Implab { | |
|
4 | ||
|
5 | [Serializable] | |
|
6 | public class TransientPromiseException : Exception { | |
|
7 | /// <summary> | |
|
8 | /// Initializes a new instance of the <see cref="PromiseFailedException"/> class. | |
|
9 | /// </summary> | |
|
10 | /// <param name="inner">The exception that is the cause of the current exception.</param> | |
|
11 | public TransientPromiseException(Exception inner) : base("The preceding promise has failed", inner) { | |
|
12 | } | |
|
13 | ||
|
14 | /// <summary> | |
|
15 | /// Initializes a new instance of the <see cref="PromiseFailedException"/> class | |
|
16 | /// </summary> | |
|
17 | /// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param> | |
|
18 | /// <param name="inner">The exception that is the cause of the current exception. </param> | |
|
19 | public TransientPromiseException(string message, Exception inner) | |
|
20 | : base(message, inner) { | |
|
21 | } | |
|
22 | ||
|
23 | /// <summary> | |
|
24 | /// Initializes a new instance of the <see cref="PromiseFailedException"/> class | |
|
25 | /// </summary> | |
|
26 | /// <param name="context">The contextual information about the source or destination.</param> | |
|
27 | /// <param name="info">The object that holds the serialized object data.</param> | |
|
28 | protected TransientPromiseException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) | |
|
29 | : base(info, context) { | |
|
30 | } | |
|
31 | } | |
|
32 | } | |
|
33 |
@@ -3,8 +3,7 | |||
|
3 | 3 | <PropertyGroup> |
|
4 | 4 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
5 | 5 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
6 | <ProductVersion> | |
|
7 | </ProductVersion> | |
|
6 | <ProductVersion>8.0.30703</ProductVersion> | |
|
8 | 7 | <SchemaVersion>2.0</SchemaVersion> |
|
9 | 8 | <ProjectGuid>{2F31E405-E267-4195-A05D-574093C21209}</ProjectGuid> |
|
10 | 9 | <OutputType>Library</OutputType> |
@@ -45,11 +44,6 | |||
|
45 | 44 | <Reference Include="WindowsBase" /> |
|
46 | 45 | </ItemGroup> |
|
47 | 46 | <ItemGroup> |
|
48 | <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | |
|
49 | <Visible>False</Visible> | |
|
50 | </CodeAnalysisDependentAssemblyPaths> | |
|
51 | </ItemGroup> | |
|
52 | <ItemGroup> | |
|
53 | 47 | <Compile Include="Properties\AssemblyInfo.cs" /> |
|
54 | 48 | <Compile Include="OverlayTest.cs" /> |
|
55 | 49 | <Compile Include="Sample\MainForm.cs"> |
@@ -68,9 +62,13 | |||
|
68 | 62 | <ItemGroup> |
|
69 | 63 | <EmbeddedResource Include="Sample\MainForm.resx"> |
|
70 | 64 | <DependentUpon>MainForm.cs</DependentUpon> |
|
65 | <LogicalName> | |
|
66 | </LogicalName> | |
|
71 | 67 | </EmbeddedResource> |
|
72 | 68 | <EmbeddedResource Include="Sample\OverlayForm.resx"> |
|
73 | 69 | <DependentUpon>OverlayForm.cs</DependentUpon> |
|
70 | <LogicalName> | |
|
71 | </LogicalName> | |
|
74 | 72 | </EmbeddedResource> |
|
75 | 73 | </ItemGroup> |
|
76 | 74 | <ItemGroup> |
@@ -46,10 +46,11 | |||
|
46 | 46 | <Compile Include="AnimationHelpers.cs" /> |
|
47 | 47 | <Compile Include="PromiseHelpers.cs" /> |
|
48 | 48 | <Compile Include="Properties\AssemblyInfo.cs" /> |
|
49 | <Compile Include="ControlBoundPromise.cs" /> | |
|
49 | 50 | </ItemGroup> |
|
50 | 51 | <ItemGroup> |
|
51 | 52 | <ProjectReference Include="..\Implab\Implab.csproj"> |
|
52 |
<Project>{ |
|
|
53 | <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project> | |
|
53 | 54 | <Name>Implab</Name> |
|
54 | 55 | </ProjectReference> |
|
55 | 56 | </ItemGroup> |
@@ -1,7 +1,4 | |||
|
1 | 1 | using System; |
|
2 | using System.Collections.Generic; | |
|
3 | using System.Linq; | |
|
4 | using System.Text; | |
|
5 | 2 | using System.Windows.Forms; |
|
6 | 3 | using System.Threading; |
|
7 | 4 | |
@@ -32,22 +29,14 namespace Implab.Fx | |||
|
32 | 29 | if (ctl == null) |
|
33 | 30 | throw new ArgumentNullException("ctl"); |
|
34 | 31 | |
|
35 | var directed = new Promise<T>(); | |
|
32 | var directed = new ControlBoundPromise<T>(ctl,that,true); | |
|
36 | 33 | |
|
37 | 34 | that.Then( |
|
38 |
|
|
|
39 | { | |
|
40 | if (ctl.InvokeRequired) | |
|
41 | ctl.Invoke(new Action<T>(directed.Resolve), res); | |
|
42 | else | |
|
43 | directed.Resolve(res); | |
|
44 | }, | |
|
35 | directed.Resolve, | |
|
45 | 36 | err => |
|
46 | 37 | { |
|
47 | if (ctl.InvokeRequired) | |
|
48 | ctl.Invoke(new Action<Exception>(directed.Reject), err); | |
|
49 | else | |
|
50 | directed.Reject(err); | |
|
38 | directed.Reject(err); | |
|
39 | return default(T); | |
|
51 | 40 | } |
|
52 | 41 | ); |
|
53 | 42 | |
@@ -86,7 +75,10 namespace Implab.Fx | |||
|
86 | 75 | |
|
87 | 76 | that.Then( |
|
88 | 77 | res => sync.Post(state => d.Resolve(res), null), |
|
89 | err => sync.Post(state => d.Reject(err), null) | |
|
78 | err => { | |
|
79 | sync.Post(state => d.Reject(err), null); | |
|
80 | return default(T); | |
|
81 | } | |
|
90 | 82 | ); |
|
91 | 83 | |
|
92 | 84 | return d; |
@@ -3,8 +3,7 | |||
|
3 | 3 | <PropertyGroup> |
|
4 | 4 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
5 | 5 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
6 | <ProductVersion> | |
|
7 | </ProductVersion> | |
|
6 | <ProductVersion>8.0.30703</ProductVersion> | |
|
8 | 7 | <SchemaVersion>2.0</SchemaVersion> |
|
9 | 8 | <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid> |
|
10 | 9 | <OutputType>Library</OutputType> |
@@ -40,11 +39,6 | |||
|
40 | 39 | </Reference> |
|
41 | 40 | </ItemGroup> |
|
42 | 41 | <ItemGroup> |
|
43 | <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> | |
|
44 | <Visible>False</Visible> | |
|
45 | </CodeAnalysisDependentAssemblyPaths> | |
|
46 | </ItemGroup> | |
|
47 | <ItemGroup> | |
|
48 | 42 | <Compile Include="AsyncTests.cs" /> |
|
49 | 43 | <Compile Include="PromiseHelper.cs" /> |
|
50 | 44 | <Compile Include="Properties\AssemblyInfo.cs" /> |
@@ -17,22 +17,11 EndProject | |||
|
17 | 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}" |
|
18 | 18 | EndProject |
|
19 | 19 | Global |
|
20 | GlobalSection(TestCaseManagementSettings) = postSolution | |
|
21 | CategoryFile = Implab.vsmdi | |
|
22 | EndGlobalSection | |
|
23 | 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|
24 | 21 | Debug|Any CPU = Debug|Any CPU |
|
25 | 22 | Release|Any CPU = Release|Any CPU |
|
26 | 23 | EndGlobalSection |
|
27 | 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|
28 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
|
29 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU | |
|
30 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
|
31 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU | |
|
32 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
|
33 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU | |
|
34 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
|
35 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU | |
|
36 | 25 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
37 | 26 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
38 | 27 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
@@ -41,11 +30,223 Global | |||
|
41 | 30 | {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
42 | 31 | {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
43 | 32 | {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU |
|
33 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
|
34 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU | |
|
35 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
|
36 | {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU | |
|
37 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
|
38 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU | |
|
39 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
|
40 | {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU | |
|
41 | EndGlobalSection | |
|
42 | GlobalSection(NestedProjects) = preSolution | |
|
43 | EndGlobalSection | |
|
44 | GlobalSection(MonoDevelopProperties) = preSolution | |
|
45 | StartupItem = Implab\Implab.csproj | |
|
46 | Policies = $0 | |
|
47 | $0.CSharpFormattingPolicy = $1 | |
|
48 | $1.IndentSwitchBody = True | |
|
49 | $1.NamespaceBraceStyle = EndOfLine | |
|
50 | $1.ClassBraceStyle = EndOfLine | |
|
51 | $1.InterfaceBraceStyle = EndOfLine | |
|
52 | $1.StructBraceStyle = EndOfLine | |
|
53 | $1.EnumBraceStyle = EndOfLine | |
|
54 | $1.MethodBraceStyle = EndOfLine | |
|
55 | $1.ConstructorBraceStyle = EndOfLine | |
|
56 | $1.DestructorBraceStyle = EndOfLine | |
|
57 | $1.BeforeMethodDeclarationParentheses = False | |
|
58 | $1.BeforeMethodCallParentheses = False | |
|
59 | $1.BeforeConstructorDeclarationParentheses = False | |
|
60 | $1.NewLineBeforeConstructorInitializerColon = NewLine | |
|
61 | $1.NewLineAfterConstructorInitializerColon = SameLine | |
|
62 | $1.BeforeIndexerDeclarationBracket = False | |
|
63 | $1.BeforeDelegateDeclarationParentheses = False | |
|
64 | $1.NewParentheses = False | |
|
65 | $1.SpacesBeforeBrackets = False | |
|
66 | $1.inheritsSet = Mono | |
|
67 | $1.inheritsScope = text/x-csharp | |
|
68 | $1.scope = text/x-csharp | |
|
69 | $0.TextStylePolicy = $2 | |
|
70 | $2.FileWidth = 120 | |
|
71 | $2.EolMarker = Unix | |
|
72 | $2.inheritsSet = VisualStudio | |
|
73 | $2.inheritsScope = text/plain | |
|
74 | $2.scope = text/x-csharp | |
|
75 | $0.DotNetNamingPolicy = $3 | |
|
76 | $3.DirectoryNamespaceAssociation = PrefixedHierarchical | |
|
77 | $3.ResourceNamePolicy = MSBuild | |
|
78 | $0.TextStylePolicy = $4 | |
|
79 | $4.FileWidth = 120 | |
|
80 | $4.TabsToSpaces = False | |
|
81 | $4.inheritsSet = VisualStudio | |
|
82 | $4.inheritsScope = text/plain | |
|
83 | $4.scope = application/xml | |
|
84 | $0.XmlFormattingPolicy = $5 | |
|
85 | $5.inheritsSet = Mono | |
|
86 | $5.inheritsScope = application/xml | |
|
87 | $5.scope = application/xml | |
|
88 | $0.TextStylePolicy = $6 | |
|
89 | $6.FileWidth = 120 | |
|
90 | $6.TabsToSpaces = False | |
|
91 | $6.inheritsSet = VisualStudio | |
|
92 | $6.inheritsScope = text/plain | |
|
93 | $6.scope = text/plain | |
|
94 | $0.NameConventionPolicy = $7 | |
|
95 | $7.Rules = $8 | |
|
96 | $8.NamingRule = $9 | |
|
97 | $9.Name = Namespaces | |
|
98 | $9.AffectedEntity = Namespace | |
|
99 | $9.VisibilityMask = VisibilityMask | |
|
100 | $9.NamingStyle = PascalCase | |
|
101 | $9.IncludeInstanceMembers = True | |
|
102 | $9.IncludeStaticEntities = True | |
|
103 | $8.NamingRule = $10 | |
|
104 | $10.Name = Types | |
|
105 | $10.AffectedEntity = Class, Struct, Enum, Delegate | |
|
106 | $10.VisibilityMask = VisibilityMask | |
|
107 | $10.NamingStyle = PascalCase | |
|
108 | $10.IncludeInstanceMembers = True | |
|
109 | $10.IncludeStaticEntities = True | |
|
110 | $8.NamingRule = $11 | |
|
111 | $11.Name = Interfaces | |
|
112 | $11.RequiredPrefixes = $12 | |
|
113 | $12.String = I | |
|
114 | $11.AffectedEntity = Interface | |
|
115 | $11.VisibilityMask = VisibilityMask | |
|
116 | $11.NamingStyle = PascalCase | |
|
117 | $11.IncludeInstanceMembers = True | |
|
118 | $11.IncludeStaticEntities = True | |
|
119 | $8.NamingRule = $13 | |
|
120 | $13.Name = Attributes | |
|
121 | $13.RequiredSuffixes = $14 | |
|
122 | $14.String = Attribute | |
|
123 | $13.AffectedEntity = CustomAttributes | |
|
124 | $13.VisibilityMask = VisibilityMask | |
|
125 | $13.NamingStyle = PascalCase | |
|
126 | $13.IncludeInstanceMembers = True | |
|
127 | $13.IncludeStaticEntities = True | |
|
128 | $8.NamingRule = $15 | |
|
129 | $15.Name = Event Arguments | |
|
130 | $15.RequiredSuffixes = $16 | |
|
131 | $16.String = EventArgs | |
|
132 | $15.AffectedEntity = CustomEventArgs | |
|
133 | $15.VisibilityMask = VisibilityMask | |
|
134 | $15.NamingStyle = PascalCase | |
|
135 | $15.IncludeInstanceMembers = True | |
|
136 | $15.IncludeStaticEntities = True | |
|
137 | $8.NamingRule = $17 | |
|
138 | $17.Name = Exceptions | |
|
139 | $17.RequiredSuffixes = $18 | |
|
140 | $18.String = Exception | |
|
141 | $17.AffectedEntity = CustomExceptions | |
|
142 | $17.VisibilityMask = VisibilityMask | |
|
143 | $17.NamingStyle = PascalCase | |
|
144 | $17.IncludeInstanceMembers = True | |
|
145 | $17.IncludeStaticEntities = True | |
|
146 | $8.NamingRule = $19 | |
|
147 | $19.Name = Methods | |
|
148 | $19.AffectedEntity = Methods | |
|
149 | $19.VisibilityMask = VisibilityMask | |
|
150 | $19.NamingStyle = PascalCase | |
|
151 | $19.IncludeInstanceMembers = True | |
|
152 | $19.IncludeStaticEntities = True | |
|
153 | $8.NamingRule = $20 | |
|
154 | $20.Name = Static Readonly Fields | |
|
155 | $20.AffectedEntity = ReadonlyField | |
|
156 | $20.VisibilityMask = Internal, Protected, Public | |
|
157 | $20.NamingStyle = CamelCase | |
|
158 | $20.IncludeInstanceMembers = False | |
|
159 | $20.IncludeStaticEntities = True | |
|
160 | $8.NamingRule = $21 | |
|
161 | $21.Name = Fields (Non Private) | |
|
162 | $21.AffectedEntity = Field | |
|
163 | $21.VisibilityMask = Internal, Public | |
|
164 | $21.NamingStyle = CamelCase | |
|
165 | $21.IncludeInstanceMembers = True | |
|
166 | $21.IncludeStaticEntities = True | |
|
167 | $8.NamingRule = $22 | |
|
168 | $22.Name = ReadOnly Fields (Non Private) | |
|
169 | $22.AffectedEntity = ReadonlyField | |
|
170 | $22.VisibilityMask = Internal, Public | |
|
171 | $22.NamingStyle = CamelCase | |
|
172 | $22.IncludeInstanceMembers = True | |
|
173 | $22.IncludeStaticEntities = False | |
|
174 | $8.NamingRule = $23 | |
|
175 | $23.Name = Fields (Private) | |
|
176 | $23.RequiredPrefixes = $24 | |
|
177 | $24.String = m_ | |
|
178 | $23.AffectedEntity = Field, ReadonlyField | |
|
179 | $23.VisibilityMask = Private, Protected | |
|
180 | $23.NamingStyle = CamelCase | |
|
181 | $23.IncludeInstanceMembers = True | |
|
182 | $23.IncludeStaticEntities = False | |
|
183 | $8.NamingRule = $25 | |
|
184 | $25.Name = Static Fields (Private) | |
|
185 | $25.RequiredPrefixes = $26 | |
|
186 | $26.String = _ | |
|
187 | $25.AffectedEntity = Field | |
|
188 | $25.VisibilityMask = Private | |
|
189 | $25.NamingStyle = CamelCase | |
|
190 | $25.IncludeInstanceMembers = False | |
|
191 | $25.IncludeStaticEntities = True | |
|
192 | $8.NamingRule = $27 | |
|
193 | $27.Name = ReadOnly Fields (Private) | |
|
194 | $27.RequiredPrefixes = $28 | |
|
195 | $28.String = m_ | |
|
196 | $27.AffectedEntity = ReadonlyField | |
|
197 | $27.VisibilityMask = Private, Protected | |
|
198 | $27.NamingStyle = CamelCase | |
|
199 | $27.IncludeInstanceMembers = True | |
|
200 | $27.IncludeStaticEntities = False | |
|
201 | $8.NamingRule = $29 | |
|
202 | $29.Name = Constant Fields | |
|
203 | $29.AffectedEntity = ConstantField | |
|
204 | $29.VisibilityMask = VisibilityMask | |
|
205 | $29.NamingStyle = AllUpper | |
|
206 | $29.IncludeInstanceMembers = True | |
|
207 | $29.IncludeStaticEntities = True | |
|
208 | $8.NamingRule = $30 | |
|
209 | $30.Name = Properties | |
|
210 | $30.AffectedEntity = Property | |
|
211 | $30.VisibilityMask = VisibilityMask | |
|
212 | $30.NamingStyle = PascalCase | |
|
213 | $30.IncludeInstanceMembers = True | |
|
214 | $30.IncludeStaticEntities = True | |
|
215 | $8.NamingRule = $31 | |
|
216 | $31.Name = Events | |
|
217 | $31.AffectedEntity = Event | |
|
218 | $31.VisibilityMask = VisibilityMask | |
|
219 | $31.NamingStyle = PascalCase | |
|
220 | $31.IncludeInstanceMembers = True | |
|
221 | $31.IncludeStaticEntities = True | |
|
222 | $8.NamingRule = $32 | |
|
223 | $32.Name = Enum Members | |
|
224 | $32.AffectedEntity = EnumMember | |
|
225 | $32.VisibilityMask = VisibilityMask | |
|
226 | $32.NamingStyle = PascalCase | |
|
227 | $32.IncludeInstanceMembers = True | |
|
228 | $32.IncludeStaticEntities = True | |
|
229 | $8.NamingRule = $33 | |
|
230 | $33.Name = Parameters | |
|
231 | $33.AffectedEntity = Parameter, LocalVariable | |
|
232 | $33.VisibilityMask = VisibilityMask | |
|
233 | $33.NamingStyle = CamelCase | |
|
234 | $33.IncludeInstanceMembers = True | |
|
235 | $33.IncludeStaticEntities = True | |
|
236 | $8.NamingRule = $34 | |
|
237 | $34.Name = Type Parameters | |
|
238 | $34.RequiredPrefixes = $35 | |
|
239 | $35.String = T | |
|
240 | $34.AffectedEntity = TypeParameter | |
|
241 | $34.VisibilityMask = VisibilityMask | |
|
242 | $34.NamingStyle = PascalCase | |
|
243 | $34.IncludeInstanceMembers = True | |
|
244 | $34.IncludeStaticEntities = True | |
|
245 | EndGlobalSection | |
|
246 | GlobalSection(TestCaseManagementSettings) = postSolution | |
|
247 | CategoryFile = Implab.vsmdi | |
|
44 | 248 | EndGlobalSection |
|
45 | 249 | GlobalSection(SolutionProperties) = preSolution |
|
46 | 250 | HideSolutionNode = FALSE |
|
47 | 251 | EndGlobalSection |
|
48 | GlobalSection(MonoDevelopProperties) = preSolution | |
|
49 | StartupItem = Implab\Implab.csproj | |
|
50 | EndGlobalSection | |
|
51 | 252 | EndGlobal |
@@ -11,16 +11,14 namespace Implab | |||
|
11 | 11 | new T Join(); |
|
12 | 12 | new T Join(int timeout); |
|
13 | 13 | |
|
14 | IPromise<T> Then(ResultHandler<T> success, ErrorHandler error); | |
|
15 | 14 | IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error); |
|
16 | 15 | IPromise<T> Then(ResultHandler<T> success); |
|
17 | new IPromise<T> Error(ErrorHandler error); | |
|
18 | 16 | IPromise<T> Error(ErrorHandler<T> error); |
|
19 | 17 | |
|
20 | IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler error); | |
|
18 | IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler<T> error); | |
|
21 | 19 | IPromise<T2> Map<T2>(ResultMapper<T, T2> mapper); |
|
22 | 20 | |
|
23 | IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler error); | |
|
21 | IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler<T> error); | |
|
24 | 22 | IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained); |
|
25 | 23 | |
|
26 | 24 | new IPromise<T> Cancelled(Action handler); |
@@ -7,6 +7,8 | |||
|
7 | 7 | <OutputType>Library</OutputType> |
|
8 | 8 | <RootNamespace>Implab</RootNamespace> |
|
9 | 9 | <AssemblyName>Implab</AssemblyName> |
|
10 | <ProductVersion>8.0.30703</ProductVersion> | |
|
11 | <SchemaVersion>2.0</SchemaVersion> | |
|
10 | 12 | </PropertyGroup> |
|
11 | 13 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
12 | 14 | <DebugSymbols>true</DebugSymbols> |
@@ -99,7 +101,79 | |||
|
99 | 101 | <Compile Include="Parallels\AsyncPool.cs" /> |
|
100 | 102 | <Compile Include="Safe.cs" /> |
|
101 | 103 | <Compile Include="ValueEventArgs.cs" /> |
|
104 | <Compile Include="PromiseExtensions.cs" /> | |
|
105 | <Compile Include="TransientPromiseException.cs" /> | |
|
106 | <Compile Include="SyncContextPromise.cs" /> | |
|
102 | 107 | </ItemGroup> |
|
103 | 108 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
|
104 | 109 | <ItemGroup /> |
|
110 | <ProjectExtensions> | |
|
111 | <MonoDevelop> | |
|
112 | <Properties> | |
|
113 | <Policies> | |
|
114 | <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" /> | |
|
115 | <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" /> | |
|
116 | <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" /> | |
|
117 | <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" /> | |
|
118 | <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" /> | |
|
119 | <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" /> | |
|
120 | <NameConventionPolicy> | |
|
121 | <Rules> | |
|
122 | <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
123 | <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
124 | <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> | |
|
125 | <RequiredPrefixes> | |
|
126 | <String>I</String> | |
|
127 | </RequiredPrefixes> | |
|
128 | </NamingRule> | |
|
129 | <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> | |
|
130 | <RequiredSuffixes> | |
|
131 | <String>Attribute</String> | |
|
132 | </RequiredSuffixes> | |
|
133 | </NamingRule> | |
|
134 | <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> | |
|
135 | <RequiredSuffixes> | |
|
136 | <String>EventArgs</String> | |
|
137 | </RequiredSuffixes> | |
|
138 | </NamingRule> | |
|
139 | <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> | |
|
140 | <RequiredSuffixes> | |
|
141 | <String>Exception</String> | |
|
142 | </RequiredSuffixes> | |
|
143 | </NamingRule> | |
|
144 | <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
145 | <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" /> | |
|
146 | <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
147 | <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" /> | |
|
148 | <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False"> | |
|
149 | <RequiredPrefixes> | |
|
150 | <String>m_</String> | |
|
151 | </RequiredPrefixes> | |
|
152 | </NamingRule> | |
|
153 | <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True"> | |
|
154 | <RequiredPrefixes> | |
|
155 | <String>_</String> | |
|
156 | </RequiredPrefixes> | |
|
157 | </NamingRule> | |
|
158 | <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False"> | |
|
159 | <RequiredPrefixes> | |
|
160 | <String>m_</String> | |
|
161 | </RequiredPrefixes> | |
|
162 | </NamingRule> | |
|
163 | <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
164 | <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
165 | <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
166 | <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
167 | <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> | |
|
168 | <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> | |
|
169 | <RequiredPrefixes> | |
|
170 | <String>T</String> | |
|
171 | </RequiredPrefixes> | |
|
172 | </NamingRule> | |
|
173 | </Rules> | |
|
174 | </NameConventionPolicy> | |
|
175 | </Policies> | |
|
176 | </Properties> | |
|
177 | </MonoDevelop> | |
|
178 | </ProjectExtensions> | |
|
105 | 179 | </Project> No newline at end of file |
@@ -7,7 +7,7 using System.Threading.Tasks; | |||
|
7 | 7 | |
|
8 | 8 | namespace Implab.JSON { |
|
9 | 9 | internal class JSONGrammar : Grammar<JSONGrammar> { |
|
10 | public enum TokenType : int{ | |
|
10 | public enum TokenType : int { | |
|
11 | 11 | None, |
|
12 | 12 | BeginObject, |
|
13 | 13 | EndObject, |
@@ -53,7 +53,6 namespace Implab.JSON { | |||
|
53 | 53 | var backSlash = SymbolToken('\\'); |
|
54 | 54 | var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r'); |
|
55 | 55 | var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4)); |
|
56 | var escape = backSlash.Cat(specialEscapeChars.Or(unicodeEspace)); | |
|
57 | 56 | var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure(); |
|
58 | 57 | var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace); |
|
59 | 58 | var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace); |
@@ -65,9 +64,6 namespace Implab.JSON { | |||
|
65 | 64 | var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional()); |
|
66 | 65 | var literal = letters.Closure(); |
|
67 | 66 | var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x)); |
|
68 | var character = unescaped.Or(escape); | |
|
69 | var str = quote.Cat(character.EClosure()).Cat(quote); | |
|
70 | ||
|
71 | 67 | |
|
72 | 68 | var jsonExpression = |
|
73 | 69 | number.Tag(TokenType.Number) |
@@ -86,13 +82,7 namespace Implab.JSON { | |||
|
86 | 82 | .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar)) |
|
87 | 83 | .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode)) |
|
88 | 84 | .Or(unescaped.Closure().Tag(TokenType.UnescapedChar)); |
|
89 | ||
|
90 | var jsonNumberExpression = | |
|
91 | minus.Tag(TokenType.Minus) | |
|
92 | .Or(SymbolToken('+').Tag(TokenType.Plus)) | |
|
93 | .Or(digit.Closure().Tag(TokenType.Integer)) | |
|
94 | .Or(dot.Tag(TokenType.Dot)) | |
|
95 | .Or(expSign.Tag(TokenType.Exp)); | |
|
85 | ||
|
96 | 86 | |
|
97 | 87 | m_jsonDFA = BuildDFA(jsonExpression); |
|
98 | 88 | m_stringDFA = BuildDFA(jsonStringExpression); |
@@ -15,7 +15,8 namespace Implab.JSON { | |||
|
15 | 15 | Context m_context; |
|
16 | 16 | |
|
17 | 17 | TextWriter m_writer; |
|
18 | bool m_indent; | |
|
18 | readonly bool m_indent = true; | |
|
19 | readonly int m_indentSize = 4; | |
|
19 | 20 | |
|
20 | 21 | static readonly char [] _escapeBKS, |
|
21 | 22 | _escapeFWD, |
@@ -43,13 +44,33 namespace Implab.JSON { | |||
|
43 | 44 | m_writer = writer; |
|
44 | 45 | } |
|
45 | 46 | |
|
47 | public JSONWriter(TextWriter writer, bool indent) { | |
|
48 | Safe.ArgumentNotNull(writer, "writer"); | |
|
49 | ||
|
50 | m_writer = writer; | |
|
51 | m_indent = indent; | |
|
52 | } | |
|
53 | ||
|
54 | void WriteIndent() { | |
|
55 | if (m_indent) { | |
|
56 | var indent = new char[m_contextStack.Count * m_indentSize + 1]; | |
|
57 | indent[0] = '\n'; | |
|
58 | for (int i = 1; i < indent.Length; i++) | |
|
59 | indent[i] = ' '; | |
|
60 | m_writer.Write(new String(indent)); | |
|
61 | } else { | |
|
62 | m_writer.Write(' '); | |
|
63 | } | |
|
64 | } | |
|
65 | ||
|
46 | 66 | void WriteMemberName(string name) { |
|
47 | 67 | Safe.ArgumentNotEmpty(name, "name"); |
|
48 | 68 | if (m_context.element != JSONElementContext.Object) |
|
49 | 69 | OperationNotApplicable("WriteMember"); |
|
50 | 70 | if (m_context.needComma) |
|
51 |
m_writer.Write(", |
|
|
52 | // TODO indent | |
|
71 | m_writer.Write(","); | |
|
72 | ||
|
73 | WriteIndent(); | |
|
53 | 74 | m_context.needComma = true; |
|
54 | 75 | Write(name); |
|
55 | 76 | m_writer.Write(" : "); |
@@ -70,13 +91,12 namespace Implab.JSON { | |||
|
70 | 91 | Write(value); |
|
71 | 92 | } |
|
72 | 93 | |
|
73 | ||
|
74 | ||
|
75 | 94 | public void WriteValue(string value) { |
|
76 | 95 | if (m_context.element != JSONElementContext.Array) |
|
77 | 96 | OperationNotApplicable("WriteValue"); |
|
78 | 97 | if (m_context.needComma) |
|
79 |
m_writer.Write(", |
|
|
98 | m_writer.Write(","); | |
|
99 | WriteIndent(); | |
|
80 | 100 | m_context.needComma = true; |
|
81 | 101 | |
|
82 | 102 | Write(value); |
@@ -86,9 +106,10 namespace Implab.JSON { | |||
|
86 | 106 | if (m_context.element != JSONElementContext.Array) |
|
87 | 107 | OperationNotApplicable("WriteValue"); |
|
88 | 108 | if (m_context.needComma) |
|
89 |
m_writer.Write(", |
|
|
109 | m_writer.Write(","); | |
|
90 | 110 | m_context.needComma = true; |
|
91 | 111 | |
|
112 | WriteIndent(); | |
|
92 | 113 | Write(value); |
|
93 | 114 | } |
|
94 | 115 | |
@@ -96,9 +117,10 namespace Implab.JSON { | |||
|
96 | 117 | if (m_context.element != JSONElementContext.Array) |
|
97 | 118 | OperationNotApplicable("WriteValue"); |
|
98 | 119 | if (m_context.needComma) |
|
99 |
m_writer.Write(", |
|
|
120 | m_writer.Write(","); | |
|
100 | 121 | m_context.needComma = true; |
|
101 | 122 | |
|
123 | WriteIndent(); | |
|
102 | 124 | Write(value); |
|
103 | 125 | } |
|
104 | 126 | |
@@ -106,13 +128,16 namespace Implab.JSON { | |||
|
106 | 128 | if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array) |
|
107 | 129 | OperationNotApplicable("BeginObject"); |
|
108 | 130 | if (m_context.needComma) |
|
109 |
m_writer.Write(", |
|
|
131 | m_writer.Write(","); | |
|
132 | ||
|
133 | WriteIndent(); | |
|
134 | ||
|
110 | 135 | m_context.needComma = true; |
|
111 | 136 | |
|
112 | 137 | m_contextStack.Push(m_context); |
|
113 | 138 | |
|
114 | 139 | m_context = new Context { element = JSONElementContext.Object, needComma = false }; |
|
115 |
m_writer.Write("{ |
|
|
140 | m_writer.Write("{"); | |
|
116 | 141 | } |
|
117 | 142 | |
|
118 | 143 | public void BeginObject(string name) { |
@@ -121,28 +146,31 namespace Implab.JSON { | |||
|
121 | 146 | m_contextStack.Push(m_context); |
|
122 | 147 | |
|
123 | 148 | m_context = new Context { element = JSONElementContext.Object, needComma = false }; |
|
124 |
m_writer.Write("{ |
|
|
149 | m_writer.Write("{"); | |
|
125 | 150 | } |
|
126 | 151 | |
|
127 | 152 | public void EndObject() { |
|
128 | 153 | if (m_context.element != JSONElementContext.Object) |
|
129 | 154 | OperationNotApplicable("EndArray"); |
|
130 | ||
|
131 | m_writer.Write(" }"); | |
|
155 | ||
|
132 | 156 | m_context = m_contextStack.Pop(); |
|
157 | WriteIndent(); | |
|
158 | m_writer.Write("}"); | |
|
133 | 159 | } |
|
134 | 160 | |
|
135 | 161 | public void BeginArray() { |
|
136 | 162 | if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array) |
|
137 | 163 | throw new InvalidOperationException(); |
|
138 | if (m_context.needComma) | |
|
139 |
m_writer.Write(", |
|
|
164 | if (m_context.needComma) { | |
|
165 | m_writer.Write(","); | |
|
166 | ||
|
167 | } | |
|
140 | 168 | m_context.needComma = true; |
|
141 | 169 | |
|
170 | WriteIndent(); | |
|
142 | 171 | m_contextStack.Push(m_context); |
|
143 | ||
|
144 | 172 | m_context = new Context { element = JSONElementContext.Array, needComma = false }; |
|
145 |
m_writer.Write("[ |
|
|
173 | m_writer.Write("["); | |
|
146 | 174 | } |
|
147 | 175 | |
|
148 | 176 | public void BeginArray(string name) { |
@@ -151,15 +179,16 namespace Implab.JSON { | |||
|
151 | 179 | m_contextStack.Push(m_context); |
|
152 | 180 | |
|
153 | 181 | m_context = new Context { element = JSONElementContext.Array, needComma = false }; |
|
154 |
m_writer.Write("[ |
|
|
182 | m_writer.Write("["); | |
|
155 | 183 | } |
|
156 | 184 | |
|
157 | 185 | public void EndArray() { |
|
158 | 186 | if (m_context.element != JSONElementContext.Array) |
|
159 | 187 | OperationNotApplicable("EndArray"); |
|
160 | 188 | |
|
161 | m_writer.Write(" ]"); | |
|
162 | 189 | m_context = m_contextStack.Pop(); |
|
190 | WriteIndent(); | |
|
191 | m_writer.Write("]"); | |
|
163 | 192 | } |
|
164 | 193 | |
|
165 | 194 | void Write(bool value) { |
@@ -174,7 +174,10 namespace Implab.Parallels { | |||
|
174 | 174 | if (left == 0) |
|
175 | 175 | promise.Resolve(res); |
|
176 | 176 | }, |
|
177 |
e => |
|
|
177 | e => { | |
|
178 | promise.Reject(e); | |
|
179 | throw new TransientPromiseException(e); | |
|
180 | } | |
|
178 | 181 | ); |
|
179 | 182 | |
|
180 | 183 | } catch (Exception e) { |
@@ -10,8 +10,8 namespace Implab { | |||
|
10 | 10 | public delegate void ErrorHandler(Exception e); |
|
11 | 11 | public delegate T ErrorHandler<out T>(Exception e); |
|
12 | 12 | public delegate void ResultHandler<in T>(T result); |
|
13 |
public delegate TNew ResultMapper<in TSrc, |
|
|
14 |
public delegate IPromise<TNew> ChainedOperation<in TSrc, |
|
|
13 | public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result); | |
|
14 | public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result); | |
|
15 | 15 | |
|
16 | 16 | /// <summary> |
|
17 | 17 | /// ΠΠ»Π°ΡΡ Π΄Π»Ρ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ². Π’Π°ΠΊ Π½Π°Π·ΡΠ²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅". |
@@ -51,32 +51,51 namespace Implab { | |||
|
51 | 51 | |
|
52 | 52 | protected struct HandlerDescriptor { |
|
53 | 53 | public ResultHandler<T> resultHandler; |
|
54 | public ErrorHandler errorHandler; | |
|
54 | public ErrorHandler<T> errorHandler; | |
|
55 | 55 | public Action cancellHandler; |
|
56 | public Promise<T> medium; | |
|
56 | 57 | |
|
57 | 58 | public void Resolve(T result) { |
|
58 | if (resultHandler != null) | |
|
59 | if (resultHandler != null) { | |
|
59 | 60 | try { |
|
60 | 61 | resultHandler(result); |
|
61 | 62 | } catch (Exception e) { |
|
62 | 63 | Reject(e); |
|
64 | return; | |
|
63 | 65 | } |
|
66 | } | |
|
67 | if (medium != null) | |
|
68 | medium.Resolve(result); | |
|
64 | 69 | } |
|
65 | 70 | |
|
66 | 71 | public void Reject(Exception err) { |
|
67 | if (errorHandler != null) | |
|
72 | if (errorHandler != null) { | |
|
68 | 73 | try { |
|
69 | errorHandler(err); | |
|
70 |
|
|
|
74 | var res = errorHandler(err); | |
|
75 | if (medium != null) | |
|
76 | medium.Resolve(res); | |
|
77 | } catch (TransientPromiseException err2) { | |
|
78 | if (medium != null) | |
|
79 | medium.Reject(err2.InnerException); | |
|
80 | } catch (Exception err2) { | |
|
81 | if (medium != null) | |
|
82 | medium.Reject(err2); | |
|
71 | 83 | } |
|
84 | } else if (medium != null) | |
|
85 | medium.Reject(err); | |
|
72 | 86 | } |
|
73 | 87 | |
|
74 | 88 | public void Cancel() { |
|
75 | if (cancellHandler != null) | |
|
89 | if (cancellHandler != null) { | |
|
76 | 90 | try { |
|
77 | 91 | cancellHandler(); |
|
78 | } catch { | |
|
92 | } catch (Exception err) { | |
|
93 | Reject(err); | |
|
94 | return; | |
|
79 | 95 | } |
|
96 | } | |
|
97 | if (medium != null) | |
|
98 | medium.Cancel(); | |
|
80 | 99 | } |
|
81 | 100 | } |
|
82 | 101 | |
@@ -102,14 +121,10 namespace Implab { | |||
|
102 | 121 | public Promise(IPromise parent, bool cancellable) { |
|
103 | 122 | m_cancellable = cancellable; |
|
104 | 123 | if (parent != null) |
|
105 |
|
|
|
106 |
|
|
|
107 |
|
|
|
108 |
|
|
|
109 | if (parent.IsExclusive) | |
|
110 | parent.Cancel(); | |
|
111 | } | |
|
112 | ); | |
|
124 | Cancelled(() => { | |
|
125 | if (parent.IsExclusive) | |
|
126 | parent.Cancel(); | |
|
127 | }); | |
|
113 | 128 | } |
|
114 | 129 | |
|
115 | 130 | bool BeginTransit() { |
@@ -197,13 +212,12 namespace Implab { | |||
|
197 | 212 | /// </summary> |
|
198 | 213 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> |
|
199 | 214 | public bool Cancel() { |
|
200 | if (BeginTransit()) { | |
|
215 | if (m_cancellable && BeginTransit()) { | |
|
201 | 216 | CompleteTransit(CANCELLED_STATE); |
|
202 | 217 | OnStateChanged(); |
|
203 | 218 | return true; |
|
204 | } else { | |
|
205 | return false; | |
|
206 | 219 | } |
|
220 | return false; | |
|
207 | 221 | } |
|
208 | 222 | |
|
209 | 223 | // ΡΠ΄Π΅Π»Π°Π½ΠΎ Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ³ΠΎ ΡΠΈΠΏΠ° void |
@@ -216,55 +230,6 namespace Implab { | |||
|
216 | 230 | /// </summary> |
|
217 | 231 | /// <param name="success">The handler of the successfully completed operation. |
|
218 | 232 | /// This handler will recieve an operation result as a parameter.</param> |
|
219 | /// <param name="error">Handles an exception that may occur during the operation.</param> | |
|
220 | /// <returns>The new promise chained to this one.</returns> | |
|
221 | public IPromise<T> Then(ResultHandler<T> success, ErrorHandler error) { | |
|
222 | if (success == null && error == null) | |
|
223 | return this; | |
|
224 | ||
|
225 | var medium = new Promise<T>(this, true); | |
|
226 | ||
|
227 | ResultHandler<T> resultHandler; | |
|
228 | if (success != null) | |
|
229 | resultHandler = x => { | |
|
230 | success(x); | |
|
231 | medium.Resolve(x); | |
|
232 | }; | |
|
233 | else | |
|
234 | resultHandler = medium.Resolve; | |
|
235 | ||
|
236 | ErrorHandler errorHandler; | |
|
237 | if (error != null) | |
|
238 | errorHandler = x => { | |
|
239 | // Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° ΡΠΎ, ΡΡΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΊΠΈ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ, | |
|
240 | // Ρ.Π΅. Π²ΠΎΠ·Π½ΠΈΠΊΡΠΈΠ΅ Π² Π½Π΅ΠΌ ΠΎΡΠΈΠ±ΠΊΠΈ Π±ΡΠ΄ΡΡ ΠΏΠΎΠ΄Π°Π²Π»Π΅Π½Ρ, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ | |
|
241 | // Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°ΡΡ, ΡΡΠΎ ΠΎΡΠΈΠ±ΠΊΠ° Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π° Π΄Π°Π»ΡΡΠ΅ ΠΏΠΎ ΡΠ΅ΠΏΠΎΡΠΊΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠΉ | |
|
242 | try { | |
|
243 | error(x); | |
|
244 | } catch { } | |
|
245 | medium.Reject(x); | |
|
246 | }; | |
|
247 | else | |
|
248 | errorHandler = medium.Reject; | |
|
249 | ||
|
250 | AddHandler(resultHandler, errorHandler, medium.InternalCancel); | |
|
251 | ||
|
252 | return medium; | |
|
253 | } | |
|
254 | ||
|
255 | public IPromise Then(Action success, ErrorHandler error) { | |
|
256 | return Then(x => success(), error); | |
|
257 | } | |
|
258 | ||
|
259 | public IPromise Then(Action success) { | |
|
260 | return Then(x => success()); | |
|
261 | } | |
|
262 | ||
|
263 | /// <summary> | |
|
264 | /// Adds new handlers to this promise. | |
|
265 | /// </summary> | |
|
266 | /// <param name="success">The handler of the successfully completed operation. | |
|
267 | /// This handler will recieve an operation result as a parameter.</param> | |
|
268 | 233 | /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param> |
|
269 | 234 | /// <returns>The new promise chained to this one.</returns> |
|
270 | 235 | public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) { |
@@ -273,33 +238,25 namespace Implab { | |||
|
273 | 238 | |
|
274 | 239 | var medium = new Promise<T>(this, true); |
|
275 | 240 | |
|
276 | ResultHandler<T> resultHandler; | |
|
277 | ErrorHandler errorHandler; | |
|
278 | ||
|
279 | if (success != null) | |
|
280 | resultHandler = x => { | |
|
281 | success(x); | |
|
282 | medium.Resolve(x); | |
|
283 | }; | |
|
284 | else | |
|
285 | resultHandler = medium.Resolve; | |
|
286 | ||
|
287 | if (error != null) | |
|
288 | errorHandler = x => { | |
|
289 | try { | |
|
290 | medium.Resolve(error(x)); | |
|
291 | } catch (Exception e) { | |
|
292 | medium.Reject(e); | |
|
293 | } | |
|
294 | }; | |
|
295 | else | |
|
296 | errorHandler = medium.Reject; | |
|
297 | ||
|
298 | AddHandler(resultHandler, errorHandler, medium.InternalCancel); | |
|
241 | AddHandler(success, error, null, medium); | |
|
299 | 242 | |
|
300 | 243 | return medium; |
|
301 | 244 | } |
|
302 | 245 | |
|
246 | public IPromise Then(Action success, ErrorHandler error) { | |
|
247 | return Then( | |
|
248 | x => success(), | |
|
249 | e => { | |
|
250 | error(e); | |
|
251 | return default(T); | |
|
252 | } | |
|
253 | ); | |
|
254 | } | |
|
255 | ||
|
256 | public IPromise Then(Action success) { | |
|
257 | return Then(x => success()); | |
|
258 | } | |
|
259 | ||
|
303 | 260 | |
|
304 | 261 | public IPromise<T> Then(ResultHandler<T> success) { |
|
305 | 262 | if (success == null) |
@@ -307,23 +264,28 namespace Implab { | |||
|
307 | 264 | |
|
308 | 265 | var medium = new Promise<T>(this, true); |
|
309 | 266 | |
|
310 | ResultHandler<T> resultHandler; | |
|
311 | ||
|
312 | if (success != null) | |
|
313 | resultHandler = x => { | |
|
314 | success(x); | |
|
315 | medium.Resolve(x); | |
|
316 | }; | |
|
317 | else | |
|
318 | resultHandler = medium.Resolve; | |
|
319 | ||
|
320 | AddHandler(resultHandler, medium.Reject, medium.InternalCancel); | |
|
267 | AddHandler(success, null, null, medium); | |
|
321 | 268 | |
|
322 | 269 | return medium; |
|
323 | 270 | } |
|
324 | 271 | |
|
325 |
public IPromise |
|
|
326 | return Then((ResultHandler<T>)null, error); | |
|
272 | public IPromise Error(ErrorHandler error) { | |
|
273 | if (error == null) | |
|
274 | return this; | |
|
275 | ||
|
276 | var medium = new Promise<T>(this, true); | |
|
277 | ||
|
278 | AddHandler( | |
|
279 | null, | |
|
280 | e => { | |
|
281 | error(e); | |
|
282 | return default(T); | |
|
283 | }, | |
|
284 | null, | |
|
285 | medium | |
|
286 | ); | |
|
287 | ||
|
288 | return medium; | |
|
327 | 289 | } |
|
328 | 290 | |
|
329 | 291 | /// <summary> |
@@ -340,17 +302,7 namespace Implab { | |||
|
340 | 302 | |
|
341 | 303 | var medium = new Promise<T>(this, true); |
|
342 | 304 | |
|
343 | AddHandler( | |
|
344 | x => medium.Resolve(x), | |
|
345 | e => { | |
|
346 | try { | |
|
347 | medium.Resolve(handler(e)); | |
|
348 | } catch (Exception e2) { | |
|
349 | medium.Reject(e2); | |
|
350 | } | |
|
351 | }, | |
|
352 | medium.InternalCancel | |
|
353 | ); | |
|
305 | AddHandler(null, handler, null, medium); | |
|
354 | 306 | |
|
355 | 307 | return medium; |
|
356 | 308 | } |
@@ -359,27 +311,16 namespace Implab { | |||
|
359 | 311 | if (handler == null) |
|
360 | 312 | return this; |
|
361 | 313 | |
|
362 | var medium = new Promise<T>(this,true); | |
|
314 | var medium = new Promise<T>(this, true); | |
|
363 | 315 | |
|
364 | 316 | AddHandler( |
|
365 |
x => |
|
|
366 | // to avoid handler being called multiple times we handle exception by ourselfs | |
|
367 |
|
|
|
368 |
|
|
|
369 | medium.Resolve(x); | |
|
370 | } catch (Exception e) { | |
|
371 | medium.Reject(e); | |
|
372 | } | |
|
317 | x => handler(), | |
|
318 | e => { | |
|
319 | handler(); | |
|
320 | throw new TransientPromiseException(e); | |
|
373 | 321 | }, |
|
374 | ||
|
375 |
|
|
|
376 | try { | |
|
377 | handler(); | |
|
378 | } catch { } | |
|
379 | medium.Reject(e); | |
|
380 | }, | |
|
381 | ||
|
382 | medium.InternalCancel | |
|
322 | null, | |
|
323 | medium | |
|
383 | 324 | ); |
|
384 | 325 | |
|
385 | 326 | return medium; |
@@ -393,28 +334,37 namespace Implab { | |||
|
393 | 334 | /// <param name="error">ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΠ°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΠΎΠ»ΡΡΠΈΡ |
|
394 | 335 | /// ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΡΠ΅Π΅ ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ.</param> |
|
395 | 336 | /// <returns>ΠΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡ.</returns> |
|
396 | public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler error) { | |
|
337 | public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<T> error) { | |
|
397 | 338 | if (mapper == null) |
|
398 | 339 | throw new ArgumentNullException("mapper"); |
|
399 | 340 | |
|
400 | 341 | // ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΡΠΈΡΠ΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ |
|
401 | var chained = new Promise<TNew>(this,true); | |
|
342 | var chained = new Promise<TNew>(this, true); | |
|
402 | 343 | |
|
403 | 344 | ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result)); |
|
404 |
ErrorHandler errorHandler |
|
|
405 |
|
|
|
345 | ErrorHandler<T> errorHandler; | |
|
346 | if (error != null) | |
|
347 | errorHandler = e => { | |
|
406 | 348 | try { |
|
407 | error(e); | |
|
408 |
} catch { |
|
|
409 | // Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π°Π»ΡΡΠ΅ ΠΏΠΎ ΡΠ΅ΠΏΠΎΡΠΊΠ΅ | |
|
410 | chained.Reject(e); | |
|
411 |
} |
|
|
349 | return error(e); | |
|
350 | } catch (Exception e2) { | |
|
351 | // Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π°Π»ΡΡΠ΅ ΠΏΠΎ ΡΠ΅ΠΏΠΎΡΠΊΠ΅ | |
|
352 | chained.Reject(e2); | |
|
353 | } | |
|
354 | return default(T); | |
|
355 | }; | |
|
356 | else | |
|
357 | errorHandler = e => { | |
|
358 | chained.Reject(e); | |
|
359 | return default(T); | |
|
360 | }; | |
|
412 | 361 | |
|
413 | 362 | |
|
414 | 363 | AddHandler( |
|
415 | 364 | resultHandler, |
|
416 | 365 | errorHandler, |
|
417 | chained.InternalCancel | |
|
366 | chained.InternalCancel, | |
|
367 | null | |
|
418 | 368 | ); |
|
419 | 369 | |
|
420 | 370 | return chained; |
@@ -434,7 +384,7 namespace Implab { | |||
|
434 | 384 | /// <param name="error">ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΠ°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΠΎΠ»ΡΡΠΈΡ |
|
435 | 385 | /// ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΡΠ΅Π΅ ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΠ΅ΡΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ.</param> |
|
436 | 386 | /// <returns>ΠΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π°ΡΠ½Ρ ΡΠΎΠ½Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ.</returns> |
|
437 | public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler error) { | |
|
387 | public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler<T> error) { | |
|
438 | 388 | |
|
439 | 389 | // ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π² ΡΠΎΠΌ, ΡΡΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ Π΅ΡΠ΅ Π½Π΅ Π½Π°ΡΠ°ΡΠ° Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π½ΡΠΆΠ½ΠΎ |
|
440 | 390 | // ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΠΎΡΡΠ΅Π΄Π½ΠΈΠΊΠ°, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄ΡΡ ΠΏΠΎΠ΄Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ. |
@@ -449,15 +399,18 namespace Implab { | |||
|
449 | 399 | var promise = chained(result); |
|
450 | 400 | |
|
451 | 401 | promise.Then( |
|
452 |
|
|
|
453 |
e => |
|
|
402 | medium.Resolve, | |
|
403 | err => { | |
|
404 | medium.Reject(err); | |
|
405 | throw new TransientPromiseException(err); | |
|
406 | } | |
|
454 | 407 | ); |
|
455 | 408 | |
|
456 | 409 | // notify chained operation that it's not needed anymore |
|
457 | 410 | // ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π²ΡΠ·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΡ ΡΡΠΎΠ³ΠΎ |
|
458 | 411 | // Π·Π°Π²ΠΈΡΠΈΡ IsExclusive |
|
459 | 412 | medium.Cancelled(() => { |
|
460 | if(promise.IsExclusive) | |
|
413 | if (promise.IsExclusive) | |
|
461 | 414 | promise.Cancel(); |
|
462 | 415 | }); |
|
463 | 416 | |
@@ -465,17 +418,25 namespace Implab { | |||
|
465 | 418 | promise.Cancelled(() => medium.Reject(new OperationCanceledException())); |
|
466 | 419 | }; |
|
467 | 420 | |
|
468 | ErrorHandler errorHandler = delegate(Exception e) { | |
|
469 | if (error != null) | |
|
470 |
|
|
|
421 | ErrorHandler<T> errorHandler = delegate(Exception e) { | |
|
422 | if (error != null) { | |
|
423 | try { | |
|
424 | return error(e); | |
|
425 | } catch (Exception e2) { | |
|
426 | medium.Reject(e2); | |
|
427 | return default(T); | |
|
428 | } | |
|
429 | } | |
|
471 | 430 | // Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π°Π»ΡΡΠ΅ ΠΏΠΎ ΡΠ΅ΠΏΠΎΡΠΊΠ΅ |
|
472 | 431 | medium.Reject(e); |
|
432 | return default(T); | |
|
473 | 433 | }; |
|
474 | 434 | |
|
475 | 435 | AddHandler( |
|
476 | 436 | resultHandler, |
|
477 | 437 | errorHandler, |
|
478 | medium.InternalCancel | |
|
438 | medium.InternalCancel, | |
|
439 | null | |
|
479 | 440 | ); |
|
480 | 441 | |
|
481 | 442 | return medium; |
@@ -486,7 +447,7 namespace Implab { | |||
|
486 | 447 | } |
|
487 | 448 | |
|
488 | 449 | public IPromise<T> Cancelled(Action handler) { |
|
489 | AddHandler(null, null, handler); | |
|
450 | AddHandler(null, null, handler, null); | |
|
490 | 451 | return this; |
|
491 | 452 | } |
|
492 | 453 | |
@@ -500,8 +461,12 namespace Implab { | |||
|
500 | 461 | throw new ArgumentNullException("handler"); |
|
501 | 462 | AddHandler( |
|
502 | 463 | x => handler(), |
|
503 |
e => |
|
|
504 | handler | |
|
464 | e => { | |
|
465 | handler(); | |
|
466 | throw new TransientPromiseException(e); | |
|
467 | }, | |
|
468 | handler, | |
|
469 | null | |
|
505 | 470 | ); |
|
506 | 471 | return this; |
|
507 | 472 | } |
@@ -560,14 +525,15 namespace Implab { | |||
|
560 | 525 | return Join(Timeout.Infinite); |
|
561 | 526 | } |
|
562 | 527 | |
|
563 | void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) { | |
|
528 | void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) { | |
|
564 | 529 | if (success != null || error != null) |
|
565 | 530 | Interlocked.Increment(ref m_childrenCount); |
|
566 | 531 | |
|
567 |
|
|
|
532 | var handler = new HandlerDescriptor { | |
|
568 | 533 | resultHandler = success, |
|
569 | 534 | errorHandler = error, |
|
570 | cancellHandler = cancel | |
|
535 | cancellHandler = cancel, | |
|
536 | medium = medium | |
|
571 | 537 | }; |
|
572 | 538 | |
|
573 | 539 | bool queued; |
@@ -653,7 +619,10 namespace Implab { | |||
|
653 | 619 | if (Interlocked.Decrement(ref pending) == 0) |
|
654 | 620 | promise.Resolve(result); |
|
655 | 621 | }, |
|
656 |
e => |
|
|
622 | e => { | |
|
623 | promise.Reject(e); | |
|
624 | return default(T); | |
|
625 | } | |
|
657 | 626 | ); |
|
658 | 627 | } else { |
|
659 | 628 | if (Interlocked.Decrement(ref pending) == 0) |
General Comments 0
You need to be logged in to leave comments.
Login now