Mercurial > pub > ImplabNet
changeset 72:d67b95eddaf4 v2
promises refactoring
author | cin |
---|---|
date | Thu, 04 Sep 2014 18:47:12 +0400 |
parents | 1714fd8678ef |
children | 3b8393be3441 |
files | Implab.Fx.Test/Implab.Fx.Test.csproj Implab.Fx/ControlBoundPromise.cs Implab.Fx/Implab.Fx.csproj Implab.Fx/PromiseHelpers.cs Implab.Test/Implab.Test.csproj Implab.sln Implab/IPromiseT.cs Implab/Implab.csproj Implab/JSON/JSONGrammar.cs Implab/JSON/JSONWriter.cs Implab/Parallels/ArrayTraits.cs Implab/Promise.cs Implab/PromiseExtensions.cs Implab/SyncContextPromise.cs Implab/TransientPromiseException.cs |
diffstat | 15 files changed, 612 insertions(+), 240 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab.Fx.Test/Implab.Fx.Test.csproj Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab.Fx.Test/Implab.Fx.Test.csproj Thu Sep 04 18:47:12 2014 +0400 @@ -3,8 +3,7 @@ <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion> - </ProductVersion> + <ProductVersion>8.0.30703</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{2F31E405-E267-4195-A05D-574093C21209}</ProjectGuid> <OutputType>Library</OutputType> @@ -45,11 +44,6 @@ <Reference Include="WindowsBase" /> </ItemGroup> <ItemGroup> - <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> - <Visible>False</Visible> - </CodeAnalysisDependentAssemblyPaths> - </ItemGroup> - <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="OverlayTest.cs" /> <Compile Include="Sample\MainForm.cs"> @@ -68,9 +62,13 @@ <ItemGroup> <EmbeddedResource Include="Sample\MainForm.resx"> <DependentUpon>MainForm.cs</DependentUpon> + <LogicalName> + </LogicalName> </EmbeddedResource> <EmbeddedResource Include="Sample\OverlayForm.resx"> <DependentUpon>OverlayForm.cs</DependentUpon> + <LogicalName> + </LogicalName> </EmbeddedResource> </ItemGroup> <ItemGroup>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab.Fx/ControlBoundPromise.cs Thu Sep 04 18:47:12 2014 +0400 @@ -0,0 +1,30 @@ +using System.Windows.Forms; +using System; + + +namespace Implab.Fx { + public class ControlBoundPromise<T> : Promise<T> { + readonly Control m_target; + + public ControlBoundPromise(Control target) { + Safe.ArgumentNotNull(target, "target"); + + m_target = target; + } + + public ControlBoundPromise(Control target, IPromise parent, bool cancellable) + : base(parent, cancellable) { + Safe.ArgumentNotNull(target, "target"); + + m_target = target; + } + + protected override void InvokeHandler(HandlerDescriptor handler) { + if (m_target.InvokeRequired) + m_target.BeginInvoke(new Action<HandlerDescriptor>(base.InvokeHandler), handler); + else + base.InvokeHandler(handler); + } + } +} +
--- a/Implab.Fx/Implab.Fx.csproj Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab.Fx/Implab.Fx.csproj Thu Sep 04 18:47:12 2014 +0400 @@ -46,10 +46,11 @@ <Compile Include="AnimationHelpers.cs" /> <Compile Include="PromiseHelpers.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="ControlBoundPromise.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Implab\Implab.csproj"> - <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project> + <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project> <Name>Implab</Name> </ProjectReference> </ItemGroup>
--- a/Implab.Fx/PromiseHelpers.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab.Fx/PromiseHelpers.cs Thu Sep 04 18:47:12 2014 +0400 @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Windows.Forms; using System.Threading; @@ -32,22 +29,14 @@ if (ctl == null) throw new ArgumentNullException("ctl"); - var directed = new Promise<T>(); + var directed = new ControlBoundPromise<T>(ctl,that,true); that.Then( - res => - { - if (ctl.InvokeRequired) - ctl.Invoke(new Action<T>(directed.Resolve), res); - else - directed.Resolve(res); - }, + directed.Resolve, err => { - if (ctl.InvokeRequired) - ctl.Invoke(new Action<Exception>(directed.Reject), err); - else - directed.Reject(err); + directed.Reject(err); + return default(T); } ); @@ -86,7 +75,10 @@ that.Then( res => sync.Post(state => d.Resolve(res), null), - err => sync.Post(state => d.Reject(err), null) + err => { + sync.Post(state => d.Reject(err), null); + return default(T); + } ); return d;
--- a/Implab.Test/Implab.Test.csproj Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab.Test/Implab.Test.csproj Thu Sep 04 18:47:12 2014 +0400 @@ -3,8 +3,7 @@ <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion> - </ProductVersion> + <ProductVersion>8.0.30703</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid> <OutputType>Library</OutputType> @@ -40,11 +39,6 @@ </Reference> </ItemGroup> <ItemGroup> - <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> - <Visible>False</Visible> - </CodeAnalysisDependentAssemblyPaths> - </ItemGroup> - <ItemGroup> <Compile Include="AsyncTests.cs" /> <Compile Include="PromiseHelper.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
--- a/Implab.sln Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab.sln Thu Sep 04 18:47:12 2014 +0400 @@ -17,22 +17,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}" EndProject Global - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = Implab.vsmdi - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU - {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -41,11 +30,223 @@ {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU + {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU + {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Implab\Implab.csproj + Policies = $0 + $0.CSharpFormattingPolicy = $1 + $1.IndentSwitchBody = True + $1.NamespaceBraceStyle = EndOfLine + $1.ClassBraceStyle = EndOfLine + $1.InterfaceBraceStyle = EndOfLine + $1.StructBraceStyle = EndOfLine + $1.EnumBraceStyle = EndOfLine + $1.MethodBraceStyle = EndOfLine + $1.ConstructorBraceStyle = EndOfLine + $1.DestructorBraceStyle = EndOfLine + $1.BeforeMethodDeclarationParentheses = False + $1.BeforeMethodCallParentheses = False + $1.BeforeConstructorDeclarationParentheses = False + $1.NewLineBeforeConstructorInitializerColon = NewLine + $1.NewLineAfterConstructorInitializerColon = SameLine + $1.BeforeIndexerDeclarationBracket = False + $1.BeforeDelegateDeclarationParentheses = False + $1.NewParentheses = False + $1.SpacesBeforeBrackets = False + $1.inheritsSet = Mono + $1.inheritsScope = text/x-csharp + $1.scope = text/x-csharp + $0.TextStylePolicy = $2 + $2.FileWidth = 120 + $2.EolMarker = Unix + $2.inheritsSet = VisualStudio + $2.inheritsScope = text/plain + $2.scope = text/x-csharp + $0.DotNetNamingPolicy = $3 + $3.DirectoryNamespaceAssociation = PrefixedHierarchical + $3.ResourceNamePolicy = MSBuild + $0.TextStylePolicy = $4 + $4.FileWidth = 120 + $4.TabsToSpaces = False + $4.inheritsSet = VisualStudio + $4.inheritsScope = text/plain + $4.scope = application/xml + $0.XmlFormattingPolicy = $5 + $5.inheritsSet = Mono + $5.inheritsScope = application/xml + $5.scope = application/xml + $0.TextStylePolicy = $6 + $6.FileWidth = 120 + $6.TabsToSpaces = False + $6.inheritsSet = VisualStudio + $6.inheritsScope = text/plain + $6.scope = text/plain + $0.NameConventionPolicy = $7 + $7.Rules = $8 + $8.NamingRule = $9 + $9.Name = Namespaces + $9.AffectedEntity = Namespace + $9.VisibilityMask = VisibilityMask + $9.NamingStyle = PascalCase + $9.IncludeInstanceMembers = True + $9.IncludeStaticEntities = True + $8.NamingRule = $10 + $10.Name = Types + $10.AffectedEntity = Class, Struct, Enum, Delegate + $10.VisibilityMask = VisibilityMask + $10.NamingStyle = PascalCase + $10.IncludeInstanceMembers = True + $10.IncludeStaticEntities = True + $8.NamingRule = $11 + $11.Name = Interfaces + $11.RequiredPrefixes = $12 + $12.String = I + $11.AffectedEntity = Interface + $11.VisibilityMask = VisibilityMask + $11.NamingStyle = PascalCase + $11.IncludeInstanceMembers = True + $11.IncludeStaticEntities = True + $8.NamingRule = $13 + $13.Name = Attributes + $13.RequiredSuffixes = $14 + $14.String = Attribute + $13.AffectedEntity = CustomAttributes + $13.VisibilityMask = VisibilityMask + $13.NamingStyle = PascalCase + $13.IncludeInstanceMembers = True + $13.IncludeStaticEntities = True + $8.NamingRule = $15 + $15.Name = Event Arguments + $15.RequiredSuffixes = $16 + $16.String = EventArgs + $15.AffectedEntity = CustomEventArgs + $15.VisibilityMask = VisibilityMask + $15.NamingStyle = PascalCase + $15.IncludeInstanceMembers = True + $15.IncludeStaticEntities = True + $8.NamingRule = $17 + $17.Name = Exceptions + $17.RequiredSuffixes = $18 + $18.String = Exception + $17.AffectedEntity = CustomExceptions + $17.VisibilityMask = VisibilityMask + $17.NamingStyle = PascalCase + $17.IncludeInstanceMembers = True + $17.IncludeStaticEntities = True + $8.NamingRule = $19 + $19.Name = Methods + $19.AffectedEntity = Methods + $19.VisibilityMask = VisibilityMask + $19.NamingStyle = PascalCase + $19.IncludeInstanceMembers = True + $19.IncludeStaticEntities = True + $8.NamingRule = $20 + $20.Name = Static Readonly Fields + $20.AffectedEntity = ReadonlyField + $20.VisibilityMask = Internal, Protected, Public + $20.NamingStyle = CamelCase + $20.IncludeInstanceMembers = False + $20.IncludeStaticEntities = True + $8.NamingRule = $21 + $21.Name = Fields (Non Private) + $21.AffectedEntity = Field + $21.VisibilityMask = Internal, Public + $21.NamingStyle = CamelCase + $21.IncludeInstanceMembers = True + $21.IncludeStaticEntities = True + $8.NamingRule = $22 + $22.Name = ReadOnly Fields (Non Private) + $22.AffectedEntity = ReadonlyField + $22.VisibilityMask = Internal, Public + $22.NamingStyle = CamelCase + $22.IncludeInstanceMembers = True + $22.IncludeStaticEntities = False + $8.NamingRule = $23 + $23.Name = Fields (Private) + $23.RequiredPrefixes = $24 + $24.String = m_ + $23.AffectedEntity = Field, ReadonlyField + $23.VisibilityMask = Private, Protected + $23.NamingStyle = CamelCase + $23.IncludeInstanceMembers = True + $23.IncludeStaticEntities = False + $8.NamingRule = $25 + $25.Name = Static Fields (Private) + $25.RequiredPrefixes = $26 + $26.String = _ + $25.AffectedEntity = Field + $25.VisibilityMask = Private + $25.NamingStyle = CamelCase + $25.IncludeInstanceMembers = False + $25.IncludeStaticEntities = True + $8.NamingRule = $27 + $27.Name = ReadOnly Fields (Private) + $27.RequiredPrefixes = $28 + $28.String = m_ + $27.AffectedEntity = ReadonlyField + $27.VisibilityMask = Private, Protected + $27.NamingStyle = CamelCase + $27.IncludeInstanceMembers = True + $27.IncludeStaticEntities = False + $8.NamingRule = $29 + $29.Name = Constant Fields + $29.AffectedEntity = ConstantField + $29.VisibilityMask = VisibilityMask + $29.NamingStyle = AllUpper + $29.IncludeInstanceMembers = True + $29.IncludeStaticEntities = True + $8.NamingRule = $30 + $30.Name = Properties + $30.AffectedEntity = Property + $30.VisibilityMask = VisibilityMask + $30.NamingStyle = PascalCase + $30.IncludeInstanceMembers = True + $30.IncludeStaticEntities = True + $8.NamingRule = $31 + $31.Name = Events + $31.AffectedEntity = Event + $31.VisibilityMask = VisibilityMask + $31.NamingStyle = PascalCase + $31.IncludeInstanceMembers = True + $31.IncludeStaticEntities = True + $8.NamingRule = $32 + $32.Name = Enum Members + $32.AffectedEntity = EnumMember + $32.VisibilityMask = VisibilityMask + $32.NamingStyle = PascalCase + $32.IncludeInstanceMembers = True + $32.IncludeStaticEntities = True + $8.NamingRule = $33 + $33.Name = Parameters + $33.AffectedEntity = Parameter, LocalVariable + $33.VisibilityMask = VisibilityMask + $33.NamingStyle = CamelCase + $33.IncludeInstanceMembers = True + $33.IncludeStaticEntities = True + $8.NamingRule = $34 + $34.Name = Type Parameters + $34.RequiredPrefixes = $35 + $35.String = T + $34.AffectedEntity = TypeParameter + $34.VisibilityMask = VisibilityMask + $34.NamingStyle = PascalCase + $34.IncludeInstanceMembers = True + $34.IncludeStaticEntities = True + EndGlobalSection + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = Implab.vsmdi EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Implab\Implab.csproj - EndGlobalSection EndGlobal
--- a/Implab/IPromiseT.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/IPromiseT.cs Thu Sep 04 18:47:12 2014 +0400 @@ -11,16 +11,14 @@ new T Join(); new T Join(int timeout); - IPromise<T> Then(ResultHandler<T> success, ErrorHandler error); IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error); IPromise<T> Then(ResultHandler<T> success); - new IPromise<T> Error(ErrorHandler error); IPromise<T> Error(ErrorHandler<T> error); - IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler error); + IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler<T> error); IPromise<T2> Map<T2>(ResultMapper<T, T2> mapper); - IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler error); + IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler<T> error); IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained); new IPromise<T> Cancelled(Action handler);
--- a/Implab/Implab.csproj Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/Implab.csproj Thu Sep 04 18:47:12 2014 +0400 @@ -7,6 +7,8 @@ <OutputType>Library</OutputType> <RootNamespace>Implab</RootNamespace> <AssemblyName>Implab</AssemblyName> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -99,7 +101,79 @@ <Compile Include="Parallels\AsyncPool.cs" /> <Compile Include="Safe.cs" /> <Compile Include="ValueEventArgs.cs" /> + <Compile Include="PromiseExtensions.cs" /> + <Compile Include="TransientPromiseException.cs" /> + <Compile Include="SyncContextPromise.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup /> + <ProjectExtensions> + <MonoDevelop> + <Properties> + <Policies> + <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" /> + <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" /> + <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" /> + <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" /> + <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" /> + <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" /> + <NameConventionPolicy> + <Rules> + <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> + <RequiredPrefixes> + <String>I</String> + </RequiredPrefixes> + </NamingRule> + <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> + <RequiredSuffixes> + <String>Attribute</String> + </RequiredSuffixes> + </NamingRule> + <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> + <RequiredSuffixes> + <String>EventArgs</String> + </RequiredSuffixes> + </NamingRule> + <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> + <RequiredSuffixes> + <String>Exception</String> + </RequiredSuffixes> + </NamingRule> + <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" /> + <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" /> + <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False"> + <RequiredPrefixes> + <String>m_</String> + </RequiredPrefixes> + </NamingRule> + <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True"> + <RequiredPrefixes> + <String>_</String> + </RequiredPrefixes> + </NamingRule> + <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False"> + <RequiredPrefixes> + <String>m_</String> + </RequiredPrefixes> + </NamingRule> + <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" /> + <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True"> + <RequiredPrefixes> + <String>T</String> + </RequiredPrefixes> + </NamingRule> + </Rules> + </NameConventionPolicy> + </Policies> + </Properties> + </MonoDevelop> + </ProjectExtensions> </Project> \ No newline at end of file
--- a/Implab/JSON/JSONGrammar.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/JSON/JSONGrammar.cs Thu Sep 04 18:47:12 2014 +0400 @@ -7,7 +7,7 @@ namespace Implab.JSON { internal class JSONGrammar : Grammar<JSONGrammar> { - public enum TokenType : int{ + public enum TokenType : int { None, BeginObject, EndObject, @@ -53,7 +53,6 @@ var backSlash = SymbolToken('\\'); var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r'); var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4)); - var escape = backSlash.Cat(specialEscapeChars.Or(unicodeEspace)); var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure(); var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace); var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace); @@ -65,9 +64,6 @@ var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional()); var literal = letters.Closure(); var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x)); - var character = unescaped.Or(escape); - var str = quote.Cat(character.EClosure()).Cat(quote); - var jsonExpression = number.Tag(TokenType.Number) @@ -86,13 +82,7 @@ .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar)) .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode)) .Or(unescaped.Closure().Tag(TokenType.UnescapedChar)); - - var jsonNumberExpression = - minus.Tag(TokenType.Minus) - .Or(SymbolToken('+').Tag(TokenType.Plus)) - .Or(digit.Closure().Tag(TokenType.Integer)) - .Or(dot.Tag(TokenType.Dot)) - .Or(expSign.Tag(TokenType.Exp)); + m_jsonDFA = BuildDFA(jsonExpression); m_stringDFA = BuildDFA(jsonStringExpression);
--- a/Implab/JSON/JSONWriter.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/JSON/JSONWriter.cs Thu Sep 04 18:47:12 2014 +0400 @@ -15,7 +15,8 @@ Context m_context; TextWriter m_writer; - bool m_indent; + readonly bool m_indent = true; + readonly int m_indentSize = 4; static readonly char [] _escapeBKS, _escapeFWD, @@ -43,13 +44,33 @@ m_writer = writer; } + public JSONWriter(TextWriter writer, bool indent) { + Safe.ArgumentNotNull(writer, "writer"); + + m_writer = writer; + m_indent = indent; + } + + void WriteIndent() { + if (m_indent) { + var indent = new char[m_contextStack.Count * m_indentSize + 1]; + indent[0] = '\n'; + for (int i = 1; i < indent.Length; i++) + indent[i] = ' '; + m_writer.Write(new String(indent)); + } else { + m_writer.Write(' '); + } + } + void WriteMemberName(string name) { Safe.ArgumentNotEmpty(name, "name"); if (m_context.element != JSONElementContext.Object) OperationNotApplicable("WriteMember"); if (m_context.needComma) - m_writer.Write(", "); - // TODO indent + m_writer.Write(","); + + WriteIndent(); m_context.needComma = true; Write(name); m_writer.Write(" : "); @@ -70,13 +91,12 @@ Write(value); } - - public void WriteValue(string value) { if (m_context.element != JSONElementContext.Array) OperationNotApplicable("WriteValue"); if (m_context.needComma) - m_writer.Write(", "); + m_writer.Write(","); + WriteIndent(); m_context.needComma = true; Write(value); @@ -86,9 +106,10 @@ if (m_context.element != JSONElementContext.Array) OperationNotApplicable("WriteValue"); if (m_context.needComma) - m_writer.Write(", "); + m_writer.Write(","); m_context.needComma = true; + WriteIndent(); Write(value); } @@ -96,9 +117,10 @@ if (m_context.element != JSONElementContext.Array) OperationNotApplicable("WriteValue"); if (m_context.needComma) - m_writer.Write(", "); + m_writer.Write(","); m_context.needComma = true; + WriteIndent(); Write(value); } @@ -106,13 +128,16 @@ if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array) OperationNotApplicable("BeginObject"); if (m_context.needComma) - m_writer.Write(", "); + m_writer.Write(","); + + WriteIndent(); + m_context.needComma = true; m_contextStack.Push(m_context); m_context = new Context { element = JSONElementContext.Object, needComma = false }; - m_writer.Write("{ "); + m_writer.Write("{"); } public void BeginObject(string name) { @@ -121,28 +146,31 @@ m_contextStack.Push(m_context); m_context = new Context { element = JSONElementContext.Object, needComma = false }; - m_writer.Write("{ "); + m_writer.Write("{"); } public void EndObject() { if (m_context.element != JSONElementContext.Object) OperationNotApplicable("EndArray"); - - m_writer.Write(" }"); + m_context = m_contextStack.Pop(); + WriteIndent(); + m_writer.Write("}"); } public void BeginArray() { if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array) throw new InvalidOperationException(); - if (m_context.needComma) - m_writer.Write(", "); + if (m_context.needComma) { + m_writer.Write(","); + + } m_context.needComma = true; + WriteIndent(); m_contextStack.Push(m_context); - m_context = new Context { element = JSONElementContext.Array, needComma = false }; - m_writer.Write("[ "); + m_writer.Write("["); } public void BeginArray(string name) { @@ -151,15 +179,16 @@ m_contextStack.Push(m_context); m_context = new Context { element = JSONElementContext.Array, needComma = false }; - m_writer.Write("[ "); + m_writer.Write("["); } public void EndArray() { if (m_context.element != JSONElementContext.Array) OperationNotApplicable("EndArray"); - m_writer.Write(" ]"); m_context = m_contextStack.Pop(); + WriteIndent(); + m_writer.Write("]"); } void Write(bool value) {
--- a/Implab/Parallels/ArrayTraits.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/Parallels/ArrayTraits.cs Thu Sep 04 18:47:12 2014 +0400 @@ -174,7 +174,10 @@ if (left == 0) promise.Resolve(res); }, - e => promise.Reject(e) + e => { + promise.Reject(e); + throw new TransientPromiseException(e); + } ); } catch (Exception e) {
--- a/Implab/Promise.cs Wed Sep 03 18:34:02 2014 +0400 +++ b/Implab/Promise.cs Thu Sep 04 18:47:12 2014 +0400 @@ -10,8 +10,8 @@ public delegate void ErrorHandler(Exception e); public delegate T ErrorHandler<out T>(Exception e); public delegate void ResultHandler<in T>(T result); - public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result); - public delegate IPromise<TNew> ChainedOperation<in TSrc, TNew>(TSrc result); + public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result); + public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result); /// <summary> /// Класс для асинхронного получения результатов. Так называемое "обещание". @@ -51,32 +51,51 @@ protected struct HandlerDescriptor { public ResultHandler<T> resultHandler; - public ErrorHandler errorHandler; + public ErrorHandler<T> errorHandler; public Action cancellHandler; + public Promise<T> medium; public void Resolve(T result) { - if (resultHandler != null) + if (resultHandler != null) { try { resultHandler(result); } catch (Exception e) { Reject(e); + return; } + } + if (medium != null) + medium.Resolve(result); } public void Reject(Exception err) { - if (errorHandler != null) + if (errorHandler != null) { try { - errorHandler(err); - } catch { + var res = errorHandler(err); + if (medium != null) + medium.Resolve(res); + } catch (TransientPromiseException err2) { + if (medium != null) + medium.Reject(err2.InnerException); + } catch (Exception err2) { + if (medium != null) + medium.Reject(err2); } + } else if (medium != null) + medium.Reject(err); } public void Cancel() { - if (cancellHandler != null) + if (cancellHandler != null) { try { cancellHandler(); - } catch { + } catch (Exception err) { + Reject(err); + return; } + } + if (medium != null) + medium.Cancel(); } } @@ -102,14 +121,10 @@ public Promise(IPromise parent, bool cancellable) { m_cancellable = cancellable; if (parent != null) - AddHandler( - null, - null, - () => { - if (parent.IsExclusive) - parent.Cancel(); - } - ); + Cancelled(() => { + if (parent.IsExclusive) + parent.Cancel(); + }); } bool BeginTransit() { @@ -197,13 +212,12 @@ /// </summary> /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns> public bool Cancel() { - if (BeginTransit()) { + if (m_cancellable && BeginTransit()) { CompleteTransit(CANCELLED_STATE); OnStateChanged(); return true; - } else { - return false; } + return false; } // сделано для возвращаемого типа void @@ -216,55 +230,6 @@ /// </summary> /// <param name="success">The handler of the successfully completed operation. /// This handler will recieve an operation result as a parameter.</param> - /// <param name="error">Handles an exception that may occur during the operation.</param> - /// <returns>The new promise chained to this one.</returns> - public IPromise<T> Then(ResultHandler<T> success, ErrorHandler error) { - if (success == null && error == null) - return this; - - var medium = new Promise<T>(this, true); - - ResultHandler<T> resultHandler; - if (success != null) - resultHandler = x => { - success(x); - medium.Resolve(x); - }; - else - resultHandler = medium.Resolve; - - ErrorHandler errorHandler; - if (error != null) - errorHandler = x => { - // несмотря на то, что обработчик ошибки вызывается безопасно, - // т.е. возникшие в нем ошибки будут подавлены, нам нужно - // гарантировать, что ошибка будет передана дальше по цепочке обещаний - try { - error(x); - } catch { } - medium.Reject(x); - }; - else - errorHandler = medium.Reject; - - AddHandler(resultHandler, errorHandler, medium.InternalCancel); - - return medium; - } - - public IPromise Then(Action success, ErrorHandler error) { - return Then(x => success(), error); - } - - public IPromise Then(Action success) { - return Then(x => success()); - } - - /// <summary> - /// Adds new handlers to this promise. - /// </summary> - /// <param name="success">The handler of the successfully completed operation. - /// This handler will recieve an operation result as a parameter.</param> /// <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> /// <returns>The new promise chained to this one.</returns> public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) { @@ -273,33 +238,25 @@ var medium = new Promise<T>(this, true); - ResultHandler<T> resultHandler; - ErrorHandler errorHandler; - - if (success != null) - resultHandler = x => { - success(x); - medium.Resolve(x); - }; - else - resultHandler = medium.Resolve; - - if (error != null) - errorHandler = x => { - try { - medium.Resolve(error(x)); - } catch (Exception e) { - medium.Reject(e); - } - }; - else - errorHandler = medium.Reject; - - AddHandler(resultHandler, errorHandler, medium.InternalCancel); + AddHandler(success, error, null, medium); return medium; } + public IPromise Then(Action success, ErrorHandler error) { + return Then( + x => success(), + e => { + error(e); + return default(T); + } + ); + } + + public IPromise Then(Action success) { + return Then(x => success()); + } + public IPromise<T> Then(ResultHandler<T> success) { if (success == null) @@ -307,23 +264,28 @@ var medium = new Promise<T>(this, true); - ResultHandler<T> resultHandler; - - if (success != null) - resultHandler = x => { - success(x); - medium.Resolve(x); - }; - else - resultHandler = medium.Resolve; - - AddHandler(resultHandler, medium.Reject, medium.InternalCancel); + AddHandler(success, null, null, medium); return medium; } - public IPromise<T> Error(ErrorHandler error) { - return Then((ResultHandler<T>)null, error); + public IPromise Error(ErrorHandler error) { + if (error == null) + return this; + + var medium = new Promise<T>(this, true); + + AddHandler( + null, + e => { + error(e); + return default(T); + }, + null, + medium + ); + + return medium; } /// <summary> @@ -340,17 +302,7 @@ var medium = new Promise<T>(this, true); - AddHandler( - x => medium.Resolve(x), - e => { - try { - medium.Resolve(handler(e)); - } catch (Exception e2) { - medium.Reject(e2); - } - }, - medium.InternalCancel - ); + AddHandler(null, handler, null, medium); return medium; } @@ -359,27 +311,16 @@ if (handler == null) return this; - var medium = new Promise<T>(this,true); + var medium = new Promise<T>(this, true); AddHandler( - x => { - // to avoid handler being called multiple times we handle exception by ourselfs - try { - handler(); - medium.Resolve(x); - } catch (Exception e) { - medium.Reject(e); - } + x => handler(), + e => { + handler(); + throw new TransientPromiseException(e); }, - - e => { - try { - handler(); - } catch { } - medium.Reject(e); - }, - - medium.InternalCancel + null, + medium ); return medium; @@ -393,28 +334,37 @@ /// <param name="error">Обработчик ошибки. Данный обработчик получит /// исключение возникшее при выполнении операции.</param> /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> - public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler error) { + public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<T> error) { if (mapper == null) throw new ArgumentNullException("mapper"); // создаем прицепленное обещание - var chained = new Promise<TNew>(this,true); + var chained = new Promise<TNew>(this, true); ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result)); - ErrorHandler errorHandler = delegate(Exception e) { - if (error != null) + ErrorHandler<T> errorHandler; + if (error != null) + errorHandler = e => { try { - error(e); - } catch { } - // в случае ошибки нужно передать исключение дальше по цепочке - chained.Reject(e); - }; + return error(e); + } catch (Exception e2) { + // в случае ошибки нужно передать исключение дальше по цепочке + chained.Reject(e2); + } + return default(T); + }; + else + errorHandler = e => { + chained.Reject(e); + return default(T); + }; AddHandler( resultHandler, errorHandler, - chained.InternalCancel + chained.InternalCancel, + null ); return chained; @@ -434,7 +384,7 @@ /// <param name="error">Обработчик ошибки. Данный обработчик получит /// исключение возникшее при выполнении текуещй операции.</param> /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> - public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler error) { + public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler<T> error) { // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно // создать посредника, к которому будут подвызяваться следующие обработчики. @@ -449,15 +399,18 @@ var promise = chained(result); promise.Then( - x => medium.Resolve(x), - e => medium.Reject(e) + medium.Resolve, + err => { + medium.Reject(err); + throw new TransientPromiseException(err); + } ); // notify chained operation that it's not needed anymore // порядок вызова Then, Cancelled важен, поскольку от этого // зависит IsExclusive medium.Cancelled(() => { - if(promise.IsExclusive) + if (promise.IsExclusive) promise.Cancel(); }); @@ -465,17 +418,25 @@ promise.Cancelled(() => medium.Reject(new OperationCanceledException())); }; - ErrorHandler errorHandler = delegate(Exception e) { - if (error != null) - error(e); + ErrorHandler<T> errorHandler = delegate(Exception e) { + if (error != null) { + try { + return error(e); + } catch (Exception e2) { + medium.Reject(e2); + return default(T); + } + } // в случае ошибки нужно передать исключение дальше по цепочке medium.Reject(e); + return default(T); }; AddHandler( resultHandler, errorHandler, - medium.InternalCancel + medium.InternalCancel, + null ); return medium; @@ -486,7 +447,7 @@ } public IPromise<T> Cancelled(Action handler) { - AddHandler(null, null, handler); + AddHandler(null, null, handler, null); return this; } @@ -500,8 +461,12 @@ throw new ArgumentNullException("handler"); AddHandler( x => handler(), - e => handler(), - handler + e => { + handler(); + throw new TransientPromiseException(e); + }, + handler, + null ); return this; } @@ -560,14 +525,15 @@ return Join(Timeout.Infinite); } - void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) { + void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) { if (success != null || error != null) Interlocked.Increment(ref m_childrenCount); - HandlerDescriptor handler = new HandlerDescriptor { + var handler = new HandlerDescriptor { resultHandler = success, errorHandler = error, - cancellHandler = cancel + cancellHandler = cancel, + medium = medium }; bool queued; @@ -653,7 +619,10 @@ if (Interlocked.Decrement(ref pending) == 0) promise.Resolve(result); }, - e => promise.Reject(e) + e => { + promise.Reject(e); + return default(T); + } ); } else { if (Interlocked.Decrement(ref pending) == 0)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/PromiseExtensions.cs Thu Sep 04 18:47:12 2014 +0400 @@ -0,0 +1,38 @@ +using System.Threading; + +namespace Implab { + public static class PromiseExtensions { + public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) { + var context = SynchronizationContext.Current; + if (context == null) + return that; + + var p = new SyncContextPromise<T>(context, that, true); + + that.Then( + x => p.Resolve(x), + e => { + p.Reject(e); + return default(T); + } + ); + return p; + } + + public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) { + Safe.ArgumentNotNull(context, "context"); + + var p = new SyncContextPromise<T>(context, that, true); + + that.Then( + x => p.Resolve(x), + e => { + p.Reject(e); + return default(T); + } + ); + return p; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/SyncContextPromise.cs Thu Sep 04 18:47:12 2014 +0400 @@ -0,0 +1,22 @@ +using System.Threading; + +namespace Implab { + public class SyncContextPromise<T> : Promise<T> { + readonly SynchronizationContext m_context; + + public SyncContextPromise(SynchronizationContext context) { + Safe.ArgumentNotNull(context, "context"); + m_context = context; + } + + public SyncContextPromise(SynchronizationContext context, IPromise parent, bool cancellable) + : base(parent, cancellable) { + Safe.ArgumentNotNull(context, "context"); + m_context = context; + } + protected override void InvokeHandler(HandlerDescriptor handler) { + m_context.Post(x => base.InvokeHandler(handler),null); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/TransientPromiseException.cs Thu Sep 04 18:47:12 2014 +0400 @@ -0,0 +1,33 @@ +using System; + +namespace Implab { + + [Serializable] + public class TransientPromiseException : Exception { + /// <summary> + /// Initializes a new instance of the <see cref="PromiseFailedException"/> class. + /// </summary> + /// <param name="inner">The exception that is the cause of the current exception.</param> + public TransientPromiseException(Exception inner) : base("The preceding promise has failed", inner) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="PromiseFailedException"/> class + /// </summary> + /// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param> + /// <param name="inner">The exception that is the cause of the current exception. </param> + public TransientPromiseException(string message, Exception inner) + : base(message, inner) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="PromiseFailedException"/> class + /// </summary> + /// <param name="context">The contextual information about the source or destination.</param> + /// <param name="info">The object that holds the serialized object data.</param> + protected TransientPromiseException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) + : base(info, context) { + } + } +} +