##// END OF EJS Templates
major refactoring, added tasks support
cin -
r75:4439140706d0 v2
parent child
Show More
@@ -1,92 +1,109
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 3 <PropertyGroup>
4 4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 6 <ProductVersion>8.0.30703</ProductVersion>
7 7 <SchemaVersion>2.0</SchemaVersion>
8 8 <ProjectGuid>{2F31E405-E267-4195-A05D-574093C21209}</ProjectGuid>
9 9 <OutputType>Library</OutputType>
10 10 <AppDesignerFolder>Properties</AppDesignerFolder>
11 11 <RootNamespace>Implab.Fx.Test</RootNamespace>
12 12 <AssemblyName>Implab.Fx.Test</AssemblyName>
13 13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14 14 <FileAlignment>512</FileAlignment>
15 15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
16 16 </PropertyGroup>
17 17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18 18 <DebugSymbols>true</DebugSymbols>
19 19 <DebugType>full</DebugType>
20 20 <Optimize>false</Optimize>
21 21 <OutputPath>bin\Debug\</OutputPath>
22 22 <DefineConstants>DEBUG;TRACE</DefineConstants>
23 23 <ErrorReport>prompt</ErrorReport>
24 24 <WarningLevel>4</WarningLevel>
25 25 </PropertyGroup>
26 26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27 27 <DebugType>pdbonly</DebugType>
28 28 <Optimize>true</Optimize>
29 29 <OutputPath>bin\Release\</OutputPath>
30 30 <DefineConstants>TRACE</DefineConstants>
31 31 <ErrorReport>prompt</ErrorReport>
32 32 <WarningLevel>4</WarningLevel>
33 33 </PropertyGroup>
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
35 <DebugSymbols>true</DebugSymbols>
36 <DebugType>full</DebugType>
37 <Optimize>false</Optimize>
38 <OutputPath>bin\Debug\</OutputPath>
39 <DefineConstants>DEBUG;TRACE</DefineConstants>
40 <ErrorReport>prompt</ErrorReport>
41 <WarningLevel>4</WarningLevel>
42 </PropertyGroup>
43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
44 <DebugType>pdbonly</DebugType>
45 <Optimize>true</Optimize>
46 <OutputPath>bin\Release\</OutputPath>
47 <DefineConstants>TRACE</DefineConstants>
48 <ErrorReport>prompt</ErrorReport>
49 <WarningLevel>4</WarningLevel>
50 </PropertyGroup>
34 51 <ItemGroup>
35 52 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
36 53 <Reference Include="System" />
37 54 <Reference Include="System.Core">
38 55 <RequiredTargetFramework>3.5</RequiredTargetFramework>
39 56 </Reference>
40 57 <Reference Include="System.Data" />
41 58 <Reference Include="System.Drawing" />
42 59 <Reference Include="System.Windows.Forms" />
43 60 <Reference Include="System.Xml" />
44 61 <Reference Include="WindowsBase" />
45 62 </ItemGroup>
46 63 <ItemGroup>
47 64 <Compile Include="Properties\AssemblyInfo.cs" />
48 65 <Compile Include="OverlayTest.cs" />
49 66 <Compile Include="Sample\MainForm.cs">
50 67 <SubType>Form</SubType>
51 68 </Compile>
52 69 <Compile Include="Sample\MainForm.Designer.cs">
53 70 <DependentUpon>MainForm.cs</DependentUpon>
54 71 </Compile>
55 72 <Compile Include="Sample\OverlayForm.cs">
56 73 <SubType>Form</SubType>
57 74 </Compile>
58 75 <Compile Include="Sample\OverlayForm.Designer.cs">
59 76 <DependentUpon>OverlayForm.cs</DependentUpon>
60 77 </Compile>
61 78 </ItemGroup>
62 79 <ItemGroup>
63 80 <EmbeddedResource Include="Sample\MainForm.resx">
64 81 <DependentUpon>MainForm.cs</DependentUpon>
65 82 <LogicalName>
66 83 </LogicalName>
67 84 </EmbeddedResource>
68 85 <EmbeddedResource Include="Sample\OverlayForm.resx">
69 86 <DependentUpon>OverlayForm.cs</DependentUpon>
70 87 <LogicalName>
71 88 </LogicalName>
72 89 </EmbeddedResource>
73 90 </ItemGroup>
74 91 <ItemGroup>
75 92 <ProjectReference Include="..\Implab.Fx\Implab.Fx.csproj">
76 93 <Project>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</Project>
77 94 <Name>Implab.Fx</Name>
78 95 </ProjectReference>
79 96 <ProjectReference Include="..\Implab\Implab.csproj">
80 97 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
81 98 <Name>Implab</Name>
82 99 </ProjectReference>
83 100 </ItemGroup>
84 101 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
85 102 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
86 103 Other similar extension points exist, see Microsoft.Common.targets.
87 104 <Target Name="BeforeBuild">
88 105 </Target>
89 106 <Target Name="AfterBuild">
90 107 </Target>
91 108 -->
92 109 </Project> No newline at end of file
@@ -1,65 +1,82
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 3 <PropertyGroup>
4 4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 6 <ProductVersion>8.0.30703</ProductVersion>
7 7 <SchemaVersion>2.0</SchemaVersion>
8 8 <ProjectGuid>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</ProjectGuid>
9 9 <OutputType>Library</OutputType>
10 10 <AppDesignerFolder>Properties</AppDesignerFolder>
11 11 <RootNamespace>Implab.Fx</RootNamespace>
12 12 <AssemblyName>Implab.Fx</AssemblyName>
13 13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14 14 <FileAlignment>512</FileAlignment>
15 15 </PropertyGroup>
16 16 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 17 <DebugSymbols>true</DebugSymbols>
18 18 <DebugType>full</DebugType>
19 19 <Optimize>false</Optimize>
20 20 <OutputPath>bin\Debug\</OutputPath>
21 21 <DefineConstants>DEBUG;TRACE</DefineConstants>
22 22 <ErrorReport>prompt</ErrorReport>
23 23 <WarningLevel>4</WarningLevel>
24 24 </PropertyGroup>
25 25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 26 <DebugType>pdbonly</DebugType>
27 27 <Optimize>true</Optimize>
28 28 <OutputPath>bin\Release\</OutputPath>
29 29 <DefineConstants>TRACE</DefineConstants>
30 30 <ErrorReport>prompt</ErrorReport>
31 31 <WarningLevel>4</WarningLevel>
32 32 </PropertyGroup>
33 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
34 <DebugSymbols>true</DebugSymbols>
35 <DebugType>full</DebugType>
36 <Optimize>false</Optimize>
37 <OutputPath>bin\Debug\</OutputPath>
38 <DefineConstants>DEBUG;TRACE</DefineConstants>
39 <ErrorReport>prompt</ErrorReport>
40 <WarningLevel>4</WarningLevel>
41 </PropertyGroup>
42 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
43 <DebugType>pdbonly</DebugType>
44 <Optimize>true</Optimize>
45 <OutputPath>bin\Release\</OutputPath>
46 <DefineConstants>TRACE</DefineConstants>
47 <ErrorReport>prompt</ErrorReport>
48 <WarningLevel>4</WarningLevel>
49 </PropertyGroup>
33 50 <ItemGroup>
34 51 <Reference Include="System" />
35 52 <Reference Include="System.Core" />
36 53 <Reference Include="System.Drawing" />
37 54 <Reference Include="System.Windows.Forms" />
38 55 <Reference Include="System.Xml.Linq" />
39 56 <Reference Include="System.Data.DataSetExtensions" />
40 57 <Reference Include="Microsoft.CSharp" />
41 58 <Reference Include="System.Data" />
42 59 <Reference Include="System.Xml" />
43 60 </ItemGroup>
44 61 <ItemGroup>
45 62 <Compile Include="Animation.cs" />
46 63 <Compile Include="AnimationHelpers.cs" />
47 64 <Compile Include="PromiseHelpers.cs" />
48 65 <Compile Include="Properties\AssemblyInfo.cs" />
49 66 <Compile Include="ControlBoundPromise.cs" />
50 67 </ItemGroup>
51 68 <ItemGroup>
52 69 <ProjectReference Include="..\Implab\Implab.csproj">
53 70 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
54 71 <Name>Implab</Name>
55 72 </ProjectReference>
56 73 </ItemGroup>
57 74 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
58 75 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
59 76 Other similar extension points exist, see Microsoft.Common.targets.
60 77 <Target Name="BeforeBuild">
61 78 </Target>
62 79 <Target Name="AfterBuild">
63 80 </Target>
64 81 -->
65 82 </Project> No newline at end of file
@@ -1,60 +1,77
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 3 <PropertyGroup>
4 4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 6 <ProductVersion>8.0.30703</ProductVersion>
7 7 <SchemaVersion>2.0</SchemaVersion>
8 8 <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid>
9 9 <OutputType>Library</OutputType>
10 10 <AppDesignerFolder>Properties</AppDesignerFolder>
11 11 <RootNamespace>Implab.Test</RootNamespace>
12 12 <AssemblyName>Implab.Test</AssemblyName>
13 13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14 14 <FileAlignment>512</FileAlignment>
15 15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
16 16 </PropertyGroup>
17 17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18 18 <DebugSymbols>true</DebugSymbols>
19 19 <DebugType>full</DebugType>
20 20 <Optimize>false</Optimize>
21 21 <OutputPath>bin\Debug\</OutputPath>
22 22 <DefineConstants>DEBUG;TRACE</DefineConstants>
23 23 <ErrorReport>prompt</ErrorReport>
24 24 <WarningLevel>4</WarningLevel>
25 25 </PropertyGroup>
26 26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27 27 <DebugType>pdbonly</DebugType>
28 28 <Optimize>true</Optimize>
29 29 <OutputPath>bin\Release\</OutputPath>
30 30 <DefineConstants>TRACE</DefineConstants>
31 31 <ErrorReport>prompt</ErrorReport>
32 32 <WarningLevel>4</WarningLevel>
33 33 </PropertyGroup>
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
35 <DebugSymbols>true</DebugSymbols>
36 <DebugType>full</DebugType>
37 <Optimize>false</Optimize>
38 <OutputPath>bin\Debug\</OutputPath>
39 <DefineConstants>DEBUG;TRACE</DefineConstants>
40 <ErrorReport>prompt</ErrorReport>
41 <WarningLevel>4</WarningLevel>
42 </PropertyGroup>
43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
44 <DebugType>pdbonly</DebugType>
45 <Optimize>true</Optimize>
46 <OutputPath>bin\Release\</OutputPath>
47 <DefineConstants>TRACE</DefineConstants>
48 <ErrorReport>prompt</ErrorReport>
49 <WarningLevel>4</WarningLevel>
50 </PropertyGroup>
34 51 <ItemGroup>
35 52 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
36 53 <Reference Include="System" />
37 54 <Reference Include="System.Core">
38 55 <RequiredTargetFramework>3.5</RequiredTargetFramework>
39 56 </Reference>
40 57 </ItemGroup>
41 58 <ItemGroup>
42 59 <Compile Include="AsyncTests.cs" />
43 60 <Compile Include="PromiseHelper.cs" />
44 61 <Compile Include="Properties\AssemblyInfo.cs" />
45 62 </ItemGroup>
46 63 <ItemGroup>
47 64 <ProjectReference Include="..\Implab\Implab.csproj">
48 65 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
49 66 <Name>Implab</Name>
50 67 </ProjectReference>
51 68 </ItemGroup>
52 69 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
53 70 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
54 71 Other similar extension points exist, see Microsoft.Common.targets.
55 72 <Target Name="BeforeBuild">
56 73 </Target>
57 74 <Target Name="AfterBuild">
58 75 </Target>
59 76 -->
60 77 </Project> No newline at end of file
@@ -1,252 +1,270
1 1 
2 2 Microsoft Visual Studio Solution File, Format Version 11.00
3 3 # Visual Studio 2010
4 4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
5 5 EndProject
6 6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
7 7 ProjectSection(SolutionItems) = preProject
8 8 Implab.vsmdi = Implab.vsmdi
9 9 Local.testsettings = Local.testsettings
10 10 TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
11 11 EndProjectSection
12 12 EndProject
13 13 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test", "Implab.Test\Implab.Test.csproj", "{63F92C0C-61BF-48C0-A377-8D67C3C661D0}"
14 14 EndProject
15 15 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
16 16 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 20 GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 21 Debug|Any CPU = Debug|Any CPU
22 22 Release|Any CPU = Release|Any CPU
23 Debug 4.5|Any CPU = Debug 4.5|Any CPU
24 Release 4.5|Any CPU = Release 4.5|Any CPU
23 25 EndGlobalSection
24 26 GlobalSection(ProjectConfigurationPlatforms) = postSolution
27 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
28 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
25 29 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 30 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
32 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
27 33 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 34 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
35 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
36 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
29 37 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 38 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
40 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
31 41 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 42 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
43 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
44 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
33 45 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 46 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
47 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
48 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
35 49 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 50 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
51 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
52 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
37 53 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 54 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
55 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
56 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
39 57 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 58 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
41 59 EndGlobalSection
42 60 GlobalSection(NestedProjects) = preSolution
43 61 EndGlobalSection
44 62 GlobalSection(MonoDevelopProperties) = preSolution
45 63 StartupItem = Implab\Implab.csproj
46 64 Policies = $0
47 65 $0.CSharpFormattingPolicy = $1
48 66 $1.IndentSwitchBody = True
49 67 $1.NamespaceBraceStyle = EndOfLine
50 68 $1.ClassBraceStyle = EndOfLine
51 69 $1.InterfaceBraceStyle = EndOfLine
52 70 $1.StructBraceStyle = EndOfLine
53 71 $1.EnumBraceStyle = EndOfLine
54 72 $1.MethodBraceStyle = EndOfLine
55 73 $1.ConstructorBraceStyle = EndOfLine
56 74 $1.DestructorBraceStyle = EndOfLine
57 75 $1.BeforeMethodDeclarationParentheses = False
58 76 $1.BeforeMethodCallParentheses = False
59 77 $1.BeforeConstructorDeclarationParentheses = False
60 78 $1.NewLineBeforeConstructorInitializerColon = NewLine
61 79 $1.NewLineAfterConstructorInitializerColon = SameLine
62 80 $1.BeforeIndexerDeclarationBracket = False
63 81 $1.BeforeDelegateDeclarationParentheses = False
64 82 $1.NewParentheses = False
65 83 $1.SpacesBeforeBrackets = False
66 84 $1.inheritsSet = Mono
67 85 $1.inheritsScope = text/x-csharp
68 86 $1.scope = text/x-csharp
69 87 $0.TextStylePolicy = $2
70 88 $2.FileWidth = 120
71 89 $2.EolMarker = Unix
72 90 $2.inheritsSet = VisualStudio
73 91 $2.inheritsScope = text/plain
74 92 $2.scope = text/x-csharp
75 93 $0.DotNetNamingPolicy = $3
76 94 $3.DirectoryNamespaceAssociation = PrefixedHierarchical
77 95 $3.ResourceNamePolicy = MSBuild
78 96 $0.TextStylePolicy = $4
79 97 $4.FileWidth = 120
80 98 $4.TabsToSpaces = False
81 99 $4.inheritsSet = VisualStudio
82 100 $4.inheritsScope = text/plain
83 101 $4.scope = application/xml
84 102 $0.XmlFormattingPolicy = $5
85 103 $5.inheritsSet = Mono
86 104 $5.inheritsScope = application/xml
87 105 $5.scope = application/xml
88 106 $0.TextStylePolicy = $6
89 107 $6.FileWidth = 120
90 108 $6.TabsToSpaces = False
91 109 $6.inheritsSet = VisualStudio
92 110 $6.inheritsScope = text/plain
93 111 $6.scope = text/plain
94 112 $0.NameConventionPolicy = $7
95 113 $7.Rules = $8
96 114 $8.NamingRule = $9
97 115 $9.Name = Namespaces
98 116 $9.AffectedEntity = Namespace
99 117 $9.VisibilityMask = VisibilityMask
100 118 $9.NamingStyle = PascalCase
101 119 $9.IncludeInstanceMembers = True
102 120 $9.IncludeStaticEntities = True
103 121 $8.NamingRule = $10
104 122 $10.Name = Types
105 123 $10.AffectedEntity = Class, Struct, Enum, Delegate
106 124 $10.VisibilityMask = VisibilityMask
107 125 $10.NamingStyle = PascalCase
108 126 $10.IncludeInstanceMembers = True
109 127 $10.IncludeStaticEntities = True
110 128 $8.NamingRule = $11
111 129 $11.Name = Interfaces
112 130 $11.RequiredPrefixes = $12
113 131 $12.String = I
114 132 $11.AffectedEntity = Interface
115 133 $11.VisibilityMask = VisibilityMask
116 134 $11.NamingStyle = PascalCase
117 135 $11.IncludeInstanceMembers = True
118 136 $11.IncludeStaticEntities = True
119 137 $8.NamingRule = $13
120 138 $13.Name = Attributes
121 139 $13.RequiredSuffixes = $14
122 140 $14.String = Attribute
123 141 $13.AffectedEntity = CustomAttributes
124 142 $13.VisibilityMask = VisibilityMask
125 143 $13.NamingStyle = PascalCase
126 144 $13.IncludeInstanceMembers = True
127 145 $13.IncludeStaticEntities = True
128 146 $8.NamingRule = $15
129 147 $15.Name = Event Arguments
130 148 $15.RequiredSuffixes = $16
131 149 $16.String = EventArgs
132 150 $15.AffectedEntity = CustomEventArgs
133 151 $15.VisibilityMask = VisibilityMask
134 152 $15.NamingStyle = PascalCase
135 153 $15.IncludeInstanceMembers = True
136 154 $15.IncludeStaticEntities = True
137 155 $8.NamingRule = $17
138 156 $17.Name = Exceptions
139 157 $17.RequiredSuffixes = $18
140 158 $18.String = Exception
141 159 $17.AffectedEntity = CustomExceptions
142 160 $17.VisibilityMask = VisibilityMask
143 161 $17.NamingStyle = PascalCase
144 162 $17.IncludeInstanceMembers = True
145 163 $17.IncludeStaticEntities = True
146 164 $8.NamingRule = $19
147 165 $19.Name = Methods
148 166 $19.AffectedEntity = Methods
149 167 $19.VisibilityMask = VisibilityMask
150 168 $19.NamingStyle = PascalCase
151 169 $19.IncludeInstanceMembers = True
152 170 $19.IncludeStaticEntities = True
153 171 $8.NamingRule = $20
154 172 $20.Name = Static Readonly Fields
155 173 $20.AffectedEntity = ReadonlyField
156 174 $20.VisibilityMask = Internal, Protected, Public
157 175 $20.NamingStyle = CamelCase
158 176 $20.IncludeInstanceMembers = False
159 177 $20.IncludeStaticEntities = True
160 178 $8.NamingRule = $21
161 179 $21.Name = Fields (Non Private)
162 180 $21.AffectedEntity = Field
163 181 $21.VisibilityMask = Internal, Public
164 182 $21.NamingStyle = CamelCase
165 183 $21.IncludeInstanceMembers = True
166 184 $21.IncludeStaticEntities = True
167 185 $8.NamingRule = $22
168 186 $22.Name = ReadOnly Fields (Non Private)
169 187 $22.AffectedEntity = ReadonlyField
170 188 $22.VisibilityMask = Internal, Public
171 189 $22.NamingStyle = CamelCase
172 190 $22.IncludeInstanceMembers = True
173 191 $22.IncludeStaticEntities = False
174 192 $8.NamingRule = $23
175 193 $23.Name = Fields (Private)
176 194 $23.RequiredPrefixes = $24
177 195 $24.String = m_
178 196 $23.AffectedEntity = Field, ReadonlyField
179 197 $23.VisibilityMask = Private, Protected
180 198 $23.NamingStyle = CamelCase
181 199 $23.IncludeInstanceMembers = True
182 200 $23.IncludeStaticEntities = False
183 201 $8.NamingRule = $25
184 202 $25.Name = Static Fields (Private)
185 203 $25.RequiredPrefixes = $26
186 204 $26.String = _
187 205 $25.AffectedEntity = Field
188 206 $25.VisibilityMask = Private
189 207 $25.NamingStyle = CamelCase
190 208 $25.IncludeInstanceMembers = False
191 209 $25.IncludeStaticEntities = True
192 210 $8.NamingRule = $27
193 211 $27.Name = ReadOnly Fields (Private)
194 212 $27.RequiredPrefixes = $28
195 213 $28.String = m_
196 214 $27.AffectedEntity = ReadonlyField
197 215 $27.VisibilityMask = Private, Protected
198 216 $27.NamingStyle = CamelCase
199 217 $27.IncludeInstanceMembers = True
200 218 $27.IncludeStaticEntities = False
201 219 $8.NamingRule = $29
202 220 $29.Name = Constant Fields
203 221 $29.AffectedEntity = ConstantField
204 222 $29.VisibilityMask = VisibilityMask
205 223 $29.NamingStyle = AllUpper
206 224 $29.IncludeInstanceMembers = True
207 225 $29.IncludeStaticEntities = True
208 226 $8.NamingRule = $30
209 227 $30.Name = Properties
210 228 $30.AffectedEntity = Property
211 229 $30.VisibilityMask = VisibilityMask
212 230 $30.NamingStyle = PascalCase
213 231 $30.IncludeInstanceMembers = True
214 232 $30.IncludeStaticEntities = True
215 233 $8.NamingRule = $31
216 234 $31.Name = Events
217 235 $31.AffectedEntity = Event
218 236 $31.VisibilityMask = VisibilityMask
219 237 $31.NamingStyle = PascalCase
220 238 $31.IncludeInstanceMembers = True
221 239 $31.IncludeStaticEntities = True
222 240 $8.NamingRule = $32
223 241 $32.Name = Enum Members
224 242 $32.AffectedEntity = EnumMember
225 243 $32.VisibilityMask = VisibilityMask
226 244 $32.NamingStyle = PascalCase
227 245 $32.IncludeInstanceMembers = True
228 246 $32.IncludeStaticEntities = True
229 247 $8.NamingRule = $33
230 248 $33.Name = Parameters
231 249 $33.AffectedEntity = Parameter, LocalVariable
232 250 $33.VisibilityMask = VisibilityMask
233 251 $33.NamingStyle = CamelCase
234 252 $33.IncludeInstanceMembers = True
235 253 $33.IncludeStaticEntities = True
236 254 $8.NamingRule = $34
237 255 $34.Name = Type Parameters
238 256 $34.RequiredPrefixes = $35
239 257 $35.String = T
240 258 $34.AffectedEntity = TypeParameter
241 259 $34.VisibilityMask = VisibilityMask
242 260 $34.NamingStyle = PascalCase
243 261 $34.IncludeInstanceMembers = True
244 262 $34.IncludeStaticEntities = True
245 263 EndGlobalSection
246 264 GlobalSection(TestCaseManagementSettings) = postSolution
247 265 CategoryFile = Implab.vsmdi
248 266 EndGlobalSection
249 267 GlobalSection(SolutionProperties) = preSolution
250 268 HideSolutionNode = FALSE
251 269 EndGlobalSection
252 270 EndGlobal
@@ -1,72 +1,82
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4 using System.Text;
5 5
6 6 namespace Implab {
7 7 public interface IPromise: ICancellable {
8 8 /// <summary>
9 9 /// Check whereather the promise has no more than one dependent promise.
10 10 /// </summary>
11 11 bool IsExclusive {
12 12 get;
13 13 }
14 14
15 15 /// <summary>
16 16 /// Тип результата, получаемого через данное обещание.
17 17 /// </summary>
18 18 Type PromiseType { get; }
19 19
20 20 /// <summary>
21 21 /// Обещание является выполненым, либо успешно, либо с ошибкой.
22 22 /// </summary>
23 23 bool IsResolved { get; }
24 24
25 25 /// <summary>
26 26 /// Обещание было отменено.
27 27 /// </summary>
28 28 bool IsCancelled { get; }
29 29
30 IPromise Then(Action success,ErrorHandler error);
30 IPromise Then(Action success, ErrorHandler error, Action cancel);
31 IPromise Then(Action success, ErrorHandler error);
31 32 IPromise Then(Action success);
33
34 /// <summary>
35 /// Добавляет последнй обработчик в цепочку обещаний, не создает промежуточных обещаний.
36 /// </summary>
37 /// <param name="success">Success.</param>
38 /// <param name="error">Error.</param>
39 /// <param name="cancel">Cancel.</param>
40 void Last(Action success, ErrorHandler error, Action cancel);
41 void Last(Action success, ErrorHandler error);
42 void Last(Action success);
43
32 44 IPromise Error(ErrorHandler error);
33 45 /// <summary>
34 46 /// Обрабатывает либо ошибку, либо результат. Событие отмены не обрабатывается.
35 47 /// </summary>
36 48 /// <param name="handler">Обработчик.</param>
37 49 /// <remarks>После обработке ошибки, она передается дальше.</remarks>
38 IPromise Anyway(Action handler);
39
40 50 /// <summary>
41 51 /// Обрабатывает либо ошибку, либо результат, либо отмену обещания.
42 52 /// </summary>
43 53 /// <param name="handler">Обработчик.</param>
44 54 /// <remarks>После обработке ошибки, она передается дальше.</remarks>
45 55 IPromise Finally(Action handler);
46 56 /// <summary>
47 57 /// Обработчик для регистрации отмены обещания, событие отмены не может быть подавлено.
48 58 /// </summary>
49 59 /// <returns>Новое обещание, связанное с текущим.</returns>
50 60 /// <param name="handler">Обработчик события.</param>
51 61 /// <remarks>Если обработчик вызывает исключение, то оно передается обработчику ошибки, результат работы
52 62 /// которого будет передан связанному обещанию</remarks>
53 63 IPromise Cancelled(Action handler);
54 64
55 65 /// <summary>
56 66 /// Преобразует результат обещания к заданному типу и возвращает новое обещание.
57 67 /// </summary>
58 68 IPromise<T> Cast<T>();
59 69
60 70 /// <summary>
61 71 /// Синхронизирует текущий поток с обещанием.
62 72 /// </summary>
63 73 void Join();
64 74 /// <summary>
65 75 /// Синхронизирует текущий поток с обещанием.
66 76 /// </summary>
67 77 /// <param name="timeout">Время ожидания, по его истечению возникнет исключение.</param>
68 78 /// <exception cref="TimeoutException">Превышено время ожидания.</exception>
69 79 void Join(int timeout);
70 80
71 81 }
72 82 }
@@ -1,29 +1,37
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4 using System.Text;
5 5
6 namespace Implab
7 {
8 public interface IPromise<T>: IPromise
9 {
6 namespace Implab {
7 public interface IPromise<T>: IPromise {
10 8
11 9 new T Join();
10
12 11 new T Join(int timeout);
13 12
13 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error, Action cancel);
14
14 15 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
16
15 17 IPromise<T> Then(ResultHandler<T> success);
18
19 void Last(ResultHandler<T> success, ErrorHandler error, Action cancel);
20 void Last(ResultHandler<T> success, ErrorHandler error);
21 void Last(ResultHandler<T> success);
22
16 23 IPromise<T> Error(ErrorHandler<T> error);
17 24
18 IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler<T> error);
19 IPromise<T2> Map<T2>(ResultMapper<T, T2> mapper);
25 IPromise<T2> Then<T2>(ResultMapper<T,T2> mapper, ErrorHandler<T> error);
26
27 IPromise<T2> Then<T2>(ResultMapper<T,T2> mapper);
20 28
21 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler<T> error);
22 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained);
29 IPromise<T2> Then<T2>(ChainedOperation<T, T2> chained, ErrorHandler<T> error);
30
31 IPromise<T2> Then<T2>(ChainedOperation<T, T2> chained);
23 32
24 33 new IPromise<T> Cancelled(Action handler);
34
25 35 new IPromise<T> Finally(Action handler);
26 new IPromise<T> Anyway(Action handler);
27
28 36 }
29 37 }
@@ -1,179 +1,198
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 3 <PropertyGroup>
4 4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 7 <OutputType>Library</OutputType>
8 8 <RootNamespace>Implab</RootNamespace>
9 9 <AssemblyName>Implab</AssemblyName>
10 10 <ProductVersion>8.0.30703</ProductVersion>
11 11 <SchemaVersion>2.0</SchemaVersion>
12 12 </PropertyGroup>
13 13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14 14 <DebugSymbols>true</DebugSymbols>
15 15 <DebugType>full</DebugType>
16 16 <Optimize>false</Optimize>
17 17 <OutputPath>bin\Debug</OutputPath>
18 18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
19 19 <ErrorReport>prompt</ErrorReport>
20 20 <WarningLevel>4</WarningLevel>
21 21 <ConsolePause>false</ConsolePause>
22 22 <RunCodeAnalysis>true</RunCodeAnalysis>
23 23 </PropertyGroup>
24 24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 25 <DebugType>full</DebugType>
26 26 <Optimize>true</Optimize>
27 27 <OutputPath>bin\Release</OutputPath>
28 28 <ErrorReport>prompt</ErrorReport>
29 29 <WarningLevel>4</WarningLevel>
30 30 <ConsolePause>false</ConsolePause>
31 31 </PropertyGroup>
32 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
33 <DebugSymbols>true</DebugSymbols>
34 <DebugType>full</DebugType>
35 <Optimize>false</Optimize>
36 <OutputPath>bin\Debug</OutputPath>
37 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
38 <ErrorReport>prompt</ErrorReport>
39 <WarningLevel>4</WarningLevel>
40 <RunCodeAnalysis>true</RunCodeAnalysis>
41 <ConsolePause>false</ConsolePause>
42 </PropertyGroup>
43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
44 <Optimize>true</Optimize>
45 <OutputPath>bin\Release</OutputPath>
46 <ErrorReport>prompt</ErrorReport>
47 <WarningLevel>4</WarningLevel>
48 <ConsolePause>false</ConsolePause>
49 <DefineConstants>NET_4_5</DefineConstants>
50 </PropertyGroup>
32 51 <ItemGroup>
33 52 <Reference Include="System" />
34 53 <Reference Include="System.Xml" />
35 54 </ItemGroup>
36 55 <ItemGroup>
37 56 <Compile Include="Component.cs" />
38 57 <Compile Include="CustomEqualityComparer.cs" />
39 58 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
40 59 <Compile Include="Diagnostics\EventText.cs" />
41 60 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
42 61 <Compile Include="Diagnostics\LogChannel.cs" />
43 62 <Compile Include="Diagnostics\LogicalOperation.cs" />
44 63 <Compile Include="Diagnostics\TextFileListener.cs" />
45 64 <Compile Include="Diagnostics\TextListenerBase.cs" />
46 65 <Compile Include="Diagnostics\TraceLog.cs" />
47 66 <Compile Include="Diagnostics\TraceContext.cs" />
48 67 <Compile Include="Diagnostics\TraceEvent.cs" />
49 68 <Compile Include="Diagnostics\TraceEventType.cs" />
50 69 <Compile Include="Disposable.cs" />
51 70 <Compile Include="ICancellable.cs" />
52 71 <Compile Include="IProgressHandler.cs" />
53 72 <Compile Include="IProgressNotifier.cs" />
54 73 <Compile Include="IPromiseT.cs" />
55 74 <Compile Include="IPromise.cs" />
56 75 <Compile Include="IServiceLocator.cs" />
57 76 <Compile Include="ITaskController.cs" />
58 77 <Compile Include="JSON\JSONElementContext.cs" />
59 78 <Compile Include="JSON\JSONElementType.cs" />
60 79 <Compile Include="JSON\JSONGrammar.cs" />
61 80 <Compile Include="JSON\JSONParser.cs" />
62 81 <Compile Include="JSON\JSONScanner.cs" />
63 82 <Compile Include="JSON\JsonTokenType.cs" />
64 83 <Compile Include="JSON\JSONWriter.cs" />
65 84 <Compile Include="JSON\JSONXmlReader.cs" />
66 85 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
67 86 <Compile Include="JSON\StringTranslator.cs" />
68 87 <Compile Include="Parallels\DispatchPool.cs" />
69 88 <Compile Include="Parallels\ArrayTraits.cs" />
70 89 <Compile Include="Parallels\MTQueue.cs" />
71 90 <Compile Include="Parallels\WorkerPool.cs" />
72 91 <Compile Include="Parsing\Alphabet.cs" />
73 92 <Compile Include="Parsing\AlphabetBase.cs" />
74 93 <Compile Include="Parsing\AltToken.cs" />
75 94 <Compile Include="Parsing\BinaryToken.cs" />
76 95 <Compile Include="Parsing\CatToken.cs" />
77 96 <Compile Include="Parsing\CDFADefinition.cs" />
78 97 <Compile Include="Parsing\DFABuilder.cs" />
79 98 <Compile Include="Parsing\DFADefinitionBase.cs" />
80 99 <Compile Include="Parsing\DFAStateDescriptor.cs" />
81 100 <Compile Include="Parsing\DFAutomaton.cs" />
82 101 <Compile Include="Parsing\EDFADefinition.cs" />
83 102 <Compile Include="Parsing\EmptyToken.cs" />
84 103 <Compile Include="Parsing\EndToken.cs" />
85 104 <Compile Include="Parsing\EnumAlphabet.cs" />
86 105 <Compile Include="Parsing\Grammar.cs" />
87 106 <Compile Include="Parsing\IAlphabet.cs" />
88 107 <Compile Include="Parsing\IDFADefinition.cs" />
89 108 <Compile Include="Parsing\IVisitor.cs" />
90 109 <Compile Include="Parsing\ParserException.cs" />
91 110 <Compile Include="Parsing\Scanner.cs" />
92 111 <Compile Include="Parsing\StarToken.cs" />
93 112 <Compile Include="Parsing\SymbolToken.cs" />
94 113 <Compile Include="Parsing\Token.cs" />
95 114 <Compile Include="SafePool.cs" />
96 115 <Compile Include="ServiceLocator.cs" />
97 116 <Compile Include="TaskController.cs" />
98 117 <Compile Include="ProgressInitEventArgs.cs" />
99 118 <Compile Include="Properties\AssemblyInfo.cs" />
100 119 <Compile Include="Promise.cs" />
101 120 <Compile Include="Parallels\AsyncPool.cs" />
102 121 <Compile Include="Safe.cs" />
103 122 <Compile Include="ValueEventArgs.cs" />
104 123 <Compile Include="PromiseExtensions.cs" />
105 124 <Compile Include="TransientPromiseException.cs" />
106 125 <Compile Include="SyncContextPromise.cs" />
107 126 </ItemGroup>
108 127 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
109 128 <ItemGroup />
110 129 <ProjectExtensions>
111 130 <MonoDevelop>
112 131 <Properties>
113 132 <Policies>
114 133 <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 134 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
116 135 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
117 136 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
118 137 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
119 138 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
120 139 <NameConventionPolicy>
121 140 <Rules>
122 141 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
123 142 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
124 143 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
125 144 <RequiredPrefixes>
126 145 <String>I</String>
127 146 </RequiredPrefixes>
128 147 </NamingRule>
129 148 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
130 149 <RequiredSuffixes>
131 150 <String>Attribute</String>
132 151 </RequiredSuffixes>
133 152 </NamingRule>
134 153 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
135 154 <RequiredSuffixes>
136 155 <String>EventArgs</String>
137 156 </RequiredSuffixes>
138 157 </NamingRule>
139 158 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
140 159 <RequiredSuffixes>
141 160 <String>Exception</String>
142 161 </RequiredSuffixes>
143 162 </NamingRule>
144 163 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
145 164 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
146 165 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
147 166 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
148 167 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
149 168 <RequiredPrefixes>
150 169 <String>m_</String>
151 170 </RequiredPrefixes>
152 171 </NamingRule>
153 172 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
154 173 <RequiredPrefixes>
155 174 <String>_</String>
156 175 </RequiredPrefixes>
157 176 </NamingRule>
158 177 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
159 178 <RequiredPrefixes>
160 179 <String>m_</String>
161 180 </RequiredPrefixes>
162 181 </NamingRule>
163 182 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
164 183 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
165 184 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
166 185 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
167 186 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
168 187 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
169 188 <RequiredPrefixes>
170 189 <String>T</String>
171 190 </RequiredPrefixes>
172 191 </NamingRule>
173 192 </Rules>
174 193 </NameConventionPolicy>
175 194 </Policies>
176 195 </Properties>
177 196 </MonoDevelop>
178 197 </ProjectExtensions>
179 198 </Project> No newline at end of file
@@ -1,194 +1,193
1 1 using Implab.Diagnostics;
2 2 using System;
3 3 using System.Collections.Generic;
4 4 using System.Diagnostics;
5 5 using System.Linq;
6 6 using System.Text;
7 7 using System.Threading;
8 8
9 9 namespace Implab.Parallels {
10 10 public static class ArrayTraits {
11 11 class ArrayIterator<TSrc> : DispatchPool<int> {
12 12 readonly Action<TSrc> m_action;
13 13 readonly TSrc[] m_source;
14 14 readonly Promise<int> m_promise = new Promise<int>();
15 15 readonly TraceContext m_traceContext;
16 16
17 17 int m_pending;
18 18 int m_next;
19 19
20 20 public ArrayIterator(TSrc[] source, Action<TSrc> action, int threads)
21 21 : base(threads) {
22 22
23 23 Debug.Assert(source != null);
24 24 Debug.Assert(action != null);
25 25
26 26 m_traceContext = TraceContext.Snapshot();
27 27 m_next = 0;
28 28 m_source = source;
29 29 m_pending = source.Length;
30 30 m_action = action;
31 31
32 m_promise.Anyway(() => Dispose());
33 m_promise.Cancelled(() => Dispose());
32 m_promise.Finally(Dispose);
34 33
35 34 InitPool();
36 35 }
37 36
38 37 public Promise<int> Promise {
39 38 get {
40 39 return m_promise;
41 40 }
42 41 }
43 42
44 43 protected override void Worker() {
45 44 TraceContext.Fork(m_traceContext);
46 45 base.Worker();
47 46 }
48 47
49 48 protected override bool TryDequeue(out int unit) {
50 49 unit = Interlocked.Increment(ref m_next) - 1;
51 return unit >= m_source.Length ? false : true;
50 return unit < m_source.Length;
52 51 }
53 52
54 53 protected override void InvokeUnit(int unit) {
55 54 try {
56 55 m_action(m_source[unit]);
57 56 var pending = Interlocked.Decrement(ref m_pending);
58 57 if (pending == 0)
59 58 m_promise.Resolve(m_source.Length);
60 59 } catch (Exception e) {
61 60 m_promise.Reject(e);
62 61 }
63 62 }
64 63 }
65 64
66 65 class ArrayMapper<TSrc, TDst>: DispatchPool<int> {
67 66 readonly Func<TSrc, TDst> m_transform;
68 67 readonly TSrc[] m_source;
69 68 readonly TDst[] m_dest;
70 69 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
71 70 readonly TraceContext m_traceContext;
72 71
73 72 int m_pending;
74 73 int m_next;
75 74
76 75 public ArrayMapper(TSrc[] source, Func<TSrc, TDst> transform, int threads)
77 76 : base(threads) {
78 77
79 78 Debug.Assert (source != null);
80 79 Debug.Assert( transform != null);
81 80
82 81 m_next = 0;
83 82 m_source = source;
84 83 m_dest = new TDst[source.Length];
85 84 m_pending = source.Length;
86 85 m_transform = transform;
87 86 m_traceContext = TraceContext.Snapshot();
88 87
89 m_promise.Anyway(() => Dispose());
90 m_promise.Cancelled(() => Dispose());
88 m_promise.Finally(Dispose);
91 89
92 90 InitPool();
93 91 }
94 92
95 93 public Promise<TDst[]> Promise {
96 94 get {
97 95 return m_promise;
98 96 }
99 97 }
100 98
101 99 protected override void Worker() {
102 100 TraceContext.Fork(m_traceContext);
103 101 base.Worker();
104 102 }
105 103
106 104 protected override bool TryDequeue(out int unit) {
107 105 unit = Interlocked.Increment(ref m_next) - 1;
108 106 return unit >= m_source.Length ? false : true;
109 107 }
110 108
111 109 protected override void InvokeUnit(int unit) {
112 110 try {
113 111 m_dest[unit] = m_transform(m_source[unit]);
114 112 var pending = Interlocked.Decrement(ref m_pending);
115 113 if (pending == 0)
116 114 m_promise.Resolve(m_dest);
117 115 } catch (Exception e) {
118 116 m_promise.Reject(e);
119 117 }
120 118 }
121 119 }
122 120
123 121 public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) {
124 122 if (source == null)
125 123 throw new ArgumentNullException("source");
126 124 if (transform == null)
127 125 throw new ArgumentNullException("transform");
128 126
129 127 var mapper = new ArrayMapper<TSrc, TDst>(source, transform, threads);
130 128 return mapper.Promise;
131 129 }
132 130
133 131 public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) {
134 132 if (source == null)
135 133 throw new ArgumentNullException("source");
136 134 if (action == null)
137 135 throw new ArgumentNullException("action");
138 136
139 137 var iter = new ArrayIterator<TSrc>(source, action, threads);
140 138 return iter.Promise;
141 139 }
142 140
143 141 public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, ChainedOperation<TSrc, TDst> transform, int threads) {
144 142 if (source == null)
145 143 throw new ArgumentNullException("source");
146 144 if (transform == null)
147 145 throw new ArgumentNullException("transform");
148 146 if (threads <= 0)
149 147 throw new ArgumentOutOfRangeException("Threads number must be greater then zero");
150 148
151 149 if (source.Length == 0)
152 150 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
153 151
154 152 var promise = new Promise<TDst[]>();
155 153 var res = new TDst[source.Length];
156 154 var pending = source.Length;
157 155
158 156 var semaphore = new Semaphore(threads, threads);
159 157
158 // Analysis disable AccessToDisposedClosure
160 159 AsyncPool.InvokeNewThread(() => {
161 160 for (int i = 0; i < source.Length; i++) {
162 161 if(promise.IsResolved)
163 162 break; // stop processing in case of error or cancellation
164 163 var idx = i;
164
165 165 semaphore.WaitOne();
166 166 try {
167 167 var p1 = transform(source[i]);
168 p1.Anyway(() => semaphore.Release());
169 p1.Cancelled(() => semaphore.Release());
168 p1.Finally(() => semaphore.Release());
170 169 p1.Then(
171 170 x => {
172 171 res[idx] = x;
173 172 var left = Interlocked.Decrement(ref pending);
174 173 if (left == 0)
175 174 promise.Resolve(res);
176 175 },
177 176 e => {
178 177 promise.Reject(e);
179 178 throw new TransientPromiseException(e);
180 179 }
181 180 );
182 181
183 182 } catch (Exception e) {
184 183 promise.Reject(e);
185 184 }
186 185 }
187 186 return 0;
188 187 });
189 188
190 return promise.Anyway(() => semaphore.Dispose());
189 return promise.Finally(semaphore.Dispose);
191 190 }
192 191
193 192 }
194 193 }
@@ -1,732 +1,764
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Reflection;
4 4 using System.Diagnostics;
5 5 using System.Threading;
6 6 using Implab.Parallels;
7 7
8 8 namespace Implab {
9 9
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 13 public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result);
14 14 public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result);
15 15
16 16 /// <summary>
17 17 /// Класс для асинхронного получения результатов. Так называемое "обещание".
18 18 /// </summary>
19 19 /// <typeparam name="T">Тип получаемого результата</typeparam>
20 20 /// <remarks>
21 21 /// <para>Сервис при обращении к его методу дает обещаиние о выполнении операции,
22 22 /// клиент получив такое обещание может установить ряд обратных вызово для получения
23 23 /// событий выполнения обещания, тоесть завершения операции и предоставлении результатов.</para>
24 24 /// <para>
25 25 /// Обещение может быть как выполнено, так и выполнено с ошибкой. Для подписки на
26 26 /// данные события клиент должен использовать методы <c>Then</c>.
27 27 /// </para>
28 28 /// <para>
29 29 /// Сервис, в свою очередь, по окончанию выполнения операции (возможно с ошибкой),
30 30 /// использует методы <c>Resolve</c> либо <c>Reject</c> для оповещения клиетна о
31 31 /// выполнении обещания.
32 32 /// </para>
33 33 /// <para>
34 34 /// Если сервер успел выполнить обещание еще до того, как клиент на него подписался,
35 35 /// то в момент подписки клиента будут вызваны соответсвующие события в синхронном
36 36 /// режиме и клиент будет оповещен в любом случае. Иначе, обработчики добавляются в
37 37 /// список в порядке подписания и в этом же порядке они будут вызваны при выполнении
38 38 /// обещания.
39 39 /// </para>
40 40 /// <para>
41 41 /// Обрабатывая результаты обещания можно преобразовывать результаты либо инициировать
42 42 /// связанные асинхронные операции, которые также возвращают обещания. Для этого следует
43 43 /// использовать соответствующую форму методе <c>Then</c>.
44 44 /// </para>
45 45 /// <para>
46 46 /// Также хорошим правилом является то, что <c>Resolve</c> и <c>Reject</c> должен вызывать
47 47 /// только инициатор обещания иначе могут возникнуть противоречия.
48 48 /// </para>
49 49 /// </remarks>
50 50 public class Promise<T> : IPromise<T> {
51 51
52 52 protected struct HandlerDescriptor {
53 53 public ResultHandler<T> resultHandler;
54 54 public ErrorHandler<T> errorHandler;
55 55 public Action cancellHandler;
56 56 public Promise<T> medium;
57 57
58 58 public void Resolve(T result) {
59 59 if (resultHandler != null) {
60 60 try {
61 61 resultHandler(result);
62 62 } catch (Exception e) {
63 63 Reject(e);
64 64 return;
65 65 }
66 66 }
67 67 if (medium != null)
68 68 medium.Resolve(result);
69 69 }
70 70
71 71 public void Reject(Exception err) {
72 72 if (errorHandler != null) {
73 73 try {
74 74 var res = errorHandler(err);
75 75 if (medium != null)
76 76 medium.Resolve(res);
77 77 } catch (TransientPromiseException err2) {
78 78 if (medium != null)
79 79 medium.Reject(err2.InnerException);
80 80 } catch (Exception err2) {
81 81 if (medium != null)
82 82 medium.Reject(err2);
83 83 }
84 84 } else if (medium != null)
85 85 medium.Reject(err);
86 86 }
87 87
88 88 public void Cancel() {
89 89 if (cancellHandler != null) {
90 90 try {
91 91 cancellHandler();
92 92 } catch (Exception err) {
93 93 Reject(err);
94 94 return;
95 95 }
96 96 }
97 97 if (medium != null)
98 98 medium.Cancel();
99 99 }
100 100 }
101 101
102 102 const int UNRESOLVED_SATE = 0;
103 103 const int TRANSITIONAL_STATE = 1;
104 104 const int SUCCEEDED_STATE = 2;
105 105 const int REJECTED_STATE = 3;
106 106 const int CANCELLED_STATE = 4;
107 107
108 108 readonly bool m_cancellable;
109 109
110 110 int m_childrenCount = 0;
111 111 int m_state;
112 112 T m_result;
113 113 Exception m_error;
114 114
115 115 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
116 116
117 117 public Promise() {
118 118 m_cancellable = true;
119 119 }
120 120
121 121 public Promise(IPromise parent, bool cancellable) {
122 122 m_cancellable = cancellable;
123 123 if (parent != null)
124 124 Cancelled(() => {
125 125 if (parent.IsExclusive)
126 126 parent.Cancel();
127 127 });
128 128 }
129 129
130 130 bool BeginTransit() {
131 131 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
132 132 }
133 133
134 134 void CompleteTransit(int state) {
135 135 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
136 136 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
137 137 }
138 138
139 139 void WaitTransition() {
140 140 while (m_state == TRANSITIONAL_STATE) {
141 141 /* noop */
142 142 }
143 143 }
144 144
145 145 public bool IsResolved {
146 146 get {
147 147 return m_state > 1;
148 148 }
149 149 }
150 150
151 151 public bool IsCancelled {
152 152 get {
153 153 return m_state == CANCELLED_STATE;
154 154 }
155 155 }
156 156
157 157 public Type PromiseType {
158 158 get { return typeof(T); }
159 159 }
160 160
161 161 /// <summary>
162 162 /// Выполняет обещание, сообщая об успешном выполнении.
163 163 /// </summary>
164 164 /// <param name="result">Результат выполнения.</param>
165 165 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
166 166 public void Resolve(T result) {
167 167 if (BeginTransit()) {
168 168 m_result = result;
169 169 CompleteTransit(SUCCEEDED_STATE);
170 170 OnStateChanged();
171 171 } else {
172 172 WaitTransition();
173 173 if (m_state != CANCELLED_STATE)
174 174 throw new InvalidOperationException("The promise is already resolved");
175 175 }
176 176 }
177 177
178 178 /// <summary>
179 179 /// Выполняет обещание, сообщая об успешном выполнении. Результатом выполнения будет пустое значения.
180 180 /// </summary>
181 181 /// <remarks>
182 182 /// Данный вариант удобен в случаях, когда интересен факт выполнения операции, нежели полученное значение.
183 183 /// </remarks>
184 184 public void Resolve() {
185 185 Resolve(default(T));
186 186 }
187 187
188 188 /// <summary>
189 189 /// Выполняет обещание, сообщая об ошибке
190 190 /// </summary>
191 191 /// <remarks>
192 192 /// Поскольку обещание должно работать в многопточной среде, при его выполнении сразу несколько потоков
193 193 /// могу вернуть ошибку, при этом только первая будет использована в качестве результата, остальные
194 194 /// будут проигнорированы.
195 195 /// </remarks>
196 196 /// <param name="error">Исключение возникшее при выполнении операции</param>
197 197 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
198 198 public void Reject(Exception error) {
199 199 if (BeginTransit()) {
200 200 m_error = error;
201 201 CompleteTransit(REJECTED_STATE);
202 202 OnStateChanged();
203 203 } else {
204 204 WaitTransition();
205 205 if (m_state == SUCCEEDED_STATE)
206 206 throw new InvalidOperationException("The promise is already resolved");
207 207 }
208 208 }
209 209
210 210 /// <summary>
211 211 /// Отменяет операцию, если это возможно.
212 212 /// </summary>
213 213 /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns>
214 214 public bool Cancel() {
215 215 if (m_cancellable && BeginTransit()) {
216 216 CompleteTransit(CANCELLED_STATE);
217 217 OnStateChanged();
218 218 return true;
219 219 }
220 220 return false;
221 221 }
222 222
223 223 // сделано для возвращаемого типа void
224 224 protected void InternalCancel() {
225 225 Cancel();
226 226 }
227 227
228
229 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error, Action cancel) {
230 if (success == null && error == null && cancel == null)
231 return this;
232
233 var medium = new Promise<T>(this, true);
234
235 AddHandler(success, error, cancel, medium);
236
237 return medium;
238 }
239
228 240 /// <summary>
229 241 /// Adds new handlers to this promise.
230 242 /// </summary>
231 243 /// <param name="success">The handler of the successfully completed operation.
232 244 /// This handler will recieve an operation result as a parameter.</param>
233 245 /// <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>
234 246 /// <returns>The new promise chained to this one.</returns>
235 247 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) {
236 248 if (success == null && error == null)
237 249 return this;
238 250
239 251 var medium = new Promise<T>(this, true);
240 252
241 253 AddHandler(success, error, null, medium);
242 254
243 255 return medium;
244 256 }
245 257
258 public IPromise Then(Action success, ErrorHandler error, Action cancel) {
259 return Then(
260 x => success(),
261 e => {
262 error(e);
263 return default(T);
264 },
265 cancel
266 );
267 }
268
246 269 public IPromise Then(Action success, ErrorHandler error) {
247 270 return Then(
248 271 x => success(),
249 272 e => {
250 273 error(e);
251 274 return default(T);
252 275 }
253 276 );
254 277 }
255 278
256 279 public IPromise Then(Action success) {
257 280 return Then(x => success());
258 281 }
259 282
260 283
261 284 public IPromise<T> Then(ResultHandler<T> success) {
262 285 if (success == null)
263 286 return this;
264 287
265 288 var medium = new Promise<T>(this, true);
266 289
267 290 AddHandler(success, null, null, medium);
268 291
269 292 return medium;
270 293 }
271 294
295 public void Last(ResultHandler<T> success, ErrorHandler error, Action cancel) {
296 if (success == null && error == null && cancel == null)
297 return;
298
299 ErrorHandler<T> errorHandler = null;
300 if (error != null)
301 errorHandler = err => {
302 error(err);
303 return default(T);
304 };
305 AddHandler(success, errorHandler, cancel, null);
306 }
307
308 public void Last(ResultHandler<T> success, ErrorHandler error) {
309 Last(success, error, null);
310 }
311
312 public void Last(ResultHandler<T> success) {
313 Last(success, null, null);
314 }
315
316 public void Last(Action success,ErrorHandler error, Action cancel) {
317 Last(x => success(), error, cancel);
318 }
319
320 public void Last(Action success,ErrorHandler error) {
321 Last(x => success(), error, null);
322 }
323
324 public void Last(Action success) {
325 Last(x => success(), null, null);
326 }
327
272 328 public IPromise Error(ErrorHandler error) {
273 329 if (error == null)
274 330 return this;
275 331
276 332 var medium = new Promise<T>(this, true);
277 333
278 334 AddHandler(
279 335 null,
280 336 e => {
281 337 error(e);
282 338 return default(T);
283 339 },
284 340 null,
285 341 medium
286 342 );
287 343
288 344 return medium;
289 345 }
290 346
291 347 /// <summary>
292 348 /// Handles error and allows to keep the promise.
293 349 /// </summary>
294 350 /// <remarks>
295 351 /// If the specified handler throws an exception, this exception will be used to reject the promise.
296 352 /// </remarks>
297 353 /// <param name="handler">The error handler which returns the result of the promise.</param>
298 354 /// <returns>New promise.</returns>
299 355 public IPromise<T> Error(ErrorHandler<T> handler) {
300 356 if (handler == null)
301 357 return this;
302 358
303 359 var medium = new Promise<T>(this, true);
304 360
305 361 AddHandler(null, handler, null, medium);
306 362
307 363 return medium;
308 364 }
309 365
310 public IPromise<T> Anyway(Action handler) {
311 if (handler == null)
312 return this;
313
314 var medium = new Promise<T>(this, true);
315
316 AddHandler(
317 x => handler(),
318 e => {
319 handler();
320 throw new TransientPromiseException(e);
321 },
322 null,
323 medium
324 );
325
326 return medium;
327 }
328
329 366 /// <summary>
330 367 /// Позволяет преобразовать результат выполения операции к новому типу.
331 368 /// </summary>
332 369 /// <typeparam name="TNew">Новый тип результата.</typeparam>
333 370 /// <param name="mapper">Преобразование результата к новому типу.</param>
334 371 /// <param name="error">Обработчик ошибки. Данный обработчик получит
335 372 /// исключение возникшее при выполнении операции.</param>
336 373 /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns>
337 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<T> error) {
374 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<T> error) {
338 375 if (mapper == null)
339 376 throw new ArgumentNullException("mapper");
340 377
341 378 // создаем прицепленное обещание
342 379 var chained = new Promise<TNew>(this, true);
343 380
344 381 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
345 382 ErrorHandler<T> errorHandler;
346 383 if (error != null)
347 384 errorHandler = e => {
348 385 try {
349 386 return error(e);
350 387 } catch (Exception e2) {
351 388 // в случае ошибки нужно передать исключение дальше по цепочке
352 389 chained.Reject(e2);
353 390 }
354 391 return default(T);
355 392 };
356 393 else
357 394 errorHandler = e => {
358 395 chained.Reject(e);
359 396 return default(T);
360 397 };
361 398
362 399
363 400 AddHandler(
364 401 resultHandler,
365 402 errorHandler,
366 403 chained.InternalCancel,
367 404 null
368 405 );
369 406
370 407 return chained;
371 408 }
372 409
373 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper) {
374 return Map(mapper, null);
410 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper) {
411 return Then(mapper, null);
375 412 }
376 413
377 414 /// <summary>
378 415 /// Сцепляет несколько аснхронных операций. Указанная асинхронная операция будет вызвана после
379 416 /// выполнения текущей, а результат текущей операции может быть использован для инициализации
380 417 /// новой операции.
381 418 /// </summary>
382 419 /// <typeparam name="TNew">Тип результата указанной асинхронной операции.</typeparam>
383 420 /// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param>
384 421 /// <param name="error">Обработчик ошибки. Данный обработчик получит
385 422 /// исключение возникшее при выполнении текуещй операции.</param>
386 423 /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns>
387 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler<T> error) {
424 public IPromise<TNew> Then<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler<T> error) {
388 425
389 426 // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно
390 427 // создать посредника, к которому будут подвызяваться следующие обработчики.
391 428 // когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы
392 429 // передать через него результаты работы.
393 430 var medium = new Promise<TNew>(this, true);
394 431
395 432 ResultHandler<T> resultHandler = delegate(T result) {
396 433 if (medium.IsCancelled)
397 434 return;
398 435
399 436 var promise = chained(result);
400 437
401 438 promise.Then(
402 439 medium.Resolve,
403 440 err => {
404 441 medium.Reject(err);
405 442 throw new TransientPromiseException(err);
406 443 }
407 444 );
408 445
409 446 // notify chained operation that it's not needed anymore
410 447 // порядок вызова Then, Cancelled важен, поскольку от этого
411 448 // зависит IsExclusive
412 449 medium.Cancelled(() => {
413 450 if (promise.IsExclusive)
414 451 promise.Cancel();
415 452 });
416 453
417 454 // внешняя отмена связанной операции рассматривается как ошибка
418 455 promise.Cancelled(() => medium.Reject(new OperationCanceledException()));
419 456 };
420 457
421 458 ErrorHandler<T> errorHandler = delegate(Exception e) {
422 459 if (error != null) {
423 460 try {
424 461 return error(e);
425 462 } catch (Exception e2) {
426 463 medium.Reject(e2);
427 464 return default(T);
428 465 }
429 466 }
430 467 // в случае ошибки нужно передать исключение дальше по цепочке
431 468 medium.Reject(e);
432 469 return default(T);
433 470 };
434 471
435 472 AddHandler(
436 473 resultHandler,
437 474 errorHandler,
438 475 medium.InternalCancel,
439 476 null
440 477 );
441 478
442 479 return medium;
443 480 }
444 481
445 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained) {
446 return Chain(chained, null);
482 public IPromise<TNew> Then<TNew>(ChainedOperation<T, TNew> chained) {
483 return Then(chained, null);
447 484 }
448 485
449 486 public IPromise<T> Cancelled(Action handler) {
450 487 var medium = new Promise<T>(this, true);
451 488 AddHandler(null, null, handler, medium);
452 489 return medium;
453 490 }
454 491
455 492 /// <summary>
456 493 /// Adds the specified handler for all cases (success, error, cancel)
457 494 /// </summary>
458 495 /// <param name="handler">The handler that will be called anyway</param>
459 496 /// <returns>self</returns>
460 497 public IPromise<T> Finally(Action handler) {
461 498 if (handler == null)
462 499 throw new ArgumentNullException("handler");
463 500 AddHandler(
464 501 x => handler(),
465 502 e => {
466 503 handler();
467 504 throw new TransientPromiseException(e);
468 505 },
469 506 handler,
470 507 null
471 508 );
472 509 return this;
473 510 }
474 511
475 512 /// <summary>
476 513 /// Преобразует результат обещания к нужному типу
477 514 /// </summary>
478 515 /// <typeparam name="T2"></typeparam>
479 516 /// <returns></returns>
480 517 public IPromise<T2> Cast<T2>() {
481 return Map(x => (T2)(object)x, null);
518 return Then(x => (T2)(object)x, null);
482 519 }
483 520
484 521 /// <summary>
485 522 /// Дожидается отложенного обещания и в случае успеха, возвращает
486 523 /// его, результат, в противном случае бросает исключение.
487 524 /// </summary>
488 525 /// <remarks>
489 526 /// <para>
490 527 /// Если ожидание обещания было прервано по таймауту, это не значит,
491 528 /// что обещание было отменено или что-то в этом роде, это только
492 529 /// означает, что мы его не дождались, однако все зарегистрированные
493 530 /// обработчики, как были так остались и они будут вызваны, когда
494 531 /// обещание будет выполнено.
495 532 /// </para>
496 533 /// <para>
497 534 /// Такое поведение вполне оправдано поскольку таймаут может истечь
498 535 /// в тот момент, когда началась обработка цепочки обработчиков, и
499 536 /// к тому же текущее обещание может стоять в цепочке обещаний и его
500 537 /// отклонение может привести к непрогнозируемому результату.
501 538 /// </para>
502 539 /// </remarks>
503 540 /// <param name="timeout">Время ожидания</param>
504 541 /// <returns>Результат выполнения обещания</returns>
505 542 public T Join(int timeout) {
506 543 var evt = new ManualResetEvent(false);
507 Anyway(() => evt.Set());
508 Cancelled(() => evt.Set());
544 Finally(() => evt.Set());
509 545
510 546 if (!evt.WaitOne(timeout, true))
511 547 throw new TimeoutException();
512 548
513 549 switch (m_state) {
514 550 case SUCCEEDED_STATE:
515 551 return m_result;
516 552 case CANCELLED_STATE:
517 553 throw new OperationCanceledException();
518 554 case REJECTED_STATE:
519 555 throw new TargetInvocationException(m_error);
520 556 default:
521 557 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
522 558 }
523 559 }
524 560
525 561 public T Join() {
526 562 return Join(Timeout.Infinite);
527 563 }
528 564
529 565 void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) {
530 566 if (success != null || error != null)
531 567 Interlocked.Increment(ref m_childrenCount);
532 568
533 569 var handler = new HandlerDescriptor {
534 570 resultHandler = success,
535 571 errorHandler = error,
536 572 cancellHandler = cancel,
537 573 medium = medium
538 574 };
539 575
540 576 bool queued;
541 577
542 578 if (!IsResolved) {
543 579 m_handlers.Enqueue(handler);
544 580 queued = true;
545 581 } else {
546 582 // the promise is in resolved state, just invoke the handled with minimum overhead
547 583 queued = false;
548 584 InvokeHandler(handler);
549 585 }
550 586
551 587 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
552 588 // if the promise have been resolved while we was adding handler to the queue
553 589 // we can't guarantee that someone is still processing it
554 590 // therefore we will fetch a handler from the queue and execute it
555 591 // note that fetched handler may be not the one that we have added
556 592 // even we can fetch no handlers at all :)
557 593 InvokeHandler(handler);
558 594 }
559 595
560 596 protected virtual void InvokeHandler(HandlerDescriptor handler) {
561 597 switch (m_state) {
562 598 case SUCCEEDED_STATE:
563 599 handler.Resolve(m_result);
564 600 break;
565 601 case REJECTED_STATE:
566 602 handler.Reject(m_error);
567 603 break;
568 604 case CANCELLED_STATE:
569 605 handler.Cancel();
570 606 break;
571 607 default:
572 608 // do nothing
573 609 return;
574 610 }
575 611 }
576 612
577 613 void OnStateChanged() {
578 614 HandlerDescriptor handler;
579 615 while (m_handlers.TryDequeue(out handler))
580 616 InvokeHandler(handler);
581 617 }
582 618
583 619 public bool IsExclusive {
584 620 get {
585 621 return m_childrenCount <= 1;
586 622 }
587 623 }
588 624
589 625 /// <summary>
590 626 /// Объединяет несколько обещаний в одно, результатом которого является массив результатов других обещаний.
591 627 /// Если хотябы одно из переданных обещаний не будет выполнено, то новое обещение тоже не будет выполнено.
592 628 /// При отмене нового обещания, переданные обещания также будут отменены, если никто больше на них не подписан.
593 629 /// </summary>
594 630 /// <param name="promises">Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным.</param>
595 631 /// <returns>Обещание объединяющее в себе результат переданных обещаний.</returns>
596 632 /// <exception cref="ArgumentNullException"><paramref name="promises"/> не может быть null</exception>
597 633 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
598 634 if (promises == null)
599 635 throw new ArgumentNullException();
600 636
601 637 // создаем аккумулятор для результатов и результирующее обещание
602 638 var result = new T[promises.Count];
603 639 var promise = new Promise<T[]>();
604 640
605 641 // special case
606 642 if (promises.Count == 0) {
607 643 promise.Resolve(result);
608 644 return promise;
609 645 }
610 646
611 647 int pending = promises.Count;
612 648
613 649 for (int i = 0; i < promises.Count; i++) {
614 650 var dest = i;
615 651
616 652 if (promises[i] != null) {
617 653 promises[i].Then(
618 654 x => {
619 655 result[dest] = x;
620 656 if (Interlocked.Decrement(ref pending) == 0)
621 657 promise.Resolve(result);
622 658 },
623 659 e => {
624 660 promise.Reject(e);
625 661 return default(T);
626 662 }
627 663 );
628 664 } else {
629 665 if (Interlocked.Decrement(ref pending) == 0)
630 666 promise.Resolve(result);
631 667 }
632 668 }
633 669
634 670 promise.Cancelled(
635 671 () => {
636 672 foreach (var d in promises)
637 673 if (d != null && d.IsExclusive)
638 674 d.Cancel();
639 675 }
640 676 );
641 677
642 678 return promise;
643 679 }
644 680
645 681 /// <summary>
646 682 /// Объединяет несколько обещаний в одно. Результирующее обещание будет выполнено при
647 683 /// выполнении всех указанных обещаний. При этом возвращаемые значения первичных обещаний
648 684 /// игнорируются.
649 685 /// </summary>
650 686 /// <param name="promises">Коллекция первичных обещаний, которые будут объеденены в одно.</param>
651 687 /// <returns>Новое обещание, объединяющее в себе переданные.</returns>
652 688 /// <remarks>
653 689 /// Если в коллекции встречаюься <c>null</c>, то они воспринимаются как выполненные обещания.
654 690 /// </remarks>
655 691 public static IPromise CreateComposite(ICollection<IPromise> promises) {
656 692 if (promises == null)
657 693 throw new ArgumentNullException();
658 694 if (promises.Count == 0)
659 695 return Promise<object>.ResultToPromise(null);
660 696
661 697 int countdown = promises.Count;
662 698
663 699 var result = new Promise<object>();
664 700
665 701 foreach (var d in promises) {
666 702 if (d == null) {
667 703 if (Interlocked.Decrement(ref countdown) == 0)
668 704 result.Resolve(null);
669 705 } else {
670 706 d.Then(() => {
671 707 if (Interlocked.Decrement(ref countdown) == 0)
672 708 result.Resolve(null);
673 709 });
674 710 }
675 711 }
676 712
677 713 result.Cancelled(() => {
678 714 foreach (var d in promises)
679 715 if (d != null && d.IsExclusive)
680 716 d.Cancel();
681 717 });
682 718
683 719 return result;
684 720 }
685 721
686 722 public static Promise<T> ResultToPromise(T result) {
687 723 var p = new Promise<T>();
688 724 p.Resolve(result);
689 725 return p;
690 726 }
691 727
692 728 public static Promise<T> ExceptionToPromise(Exception error) {
693 729 if (error == null)
694 730 throw new ArgumentNullException();
695 731
696 732 var p = new Promise<T>();
697 733 p.Reject(error);
698 734 return p;
699 735 }
700 736
701 737 #region IPromiseBase explicit implementation
702 738
703 739 IPromise IPromise.Error(ErrorHandler error) {
704 740 return Error(error);
705 741 }
706 742
707 IPromise IPromise.Anyway(Action handler) {
708 return Anyway(handler);
709 }
710
711 743 IPromise IPromise.Finally(Action handler) {
712 744 return Finally(handler);
713 745 }
714 746
715 747 IPromise IPromise.Cancelled(Action handler) {
716 748 return Cancelled(handler);
717 749 }
718 750
719 751 void IPromise.Join() {
720 752 Join();
721 753 }
722 754
723 755 void IPromise.Join(int timeout) {
724 756 Join(timeout);
725 757 }
726 758
727 759 #endregion
728 760
729 761
730 762
731 763 }
732 764 }
@@ -1,38 +1,69
1 1 using System.Threading;
2 using System;
3 #if NET_4_5
4 using System.Threading.Tasks;
5 #endif
2 6
3 7 namespace Implab {
4 8 public static class PromiseExtensions {
5 9 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
10 Safe.ArgumentNotNull(that, "that");
6 11 var context = SynchronizationContext.Current;
7 12 if (context == null)
8 13 return that;
9 14
10 15 var p = new SyncContextPromise<T>(context, that, true);
11 16
12 17 that.Then(
13 18 x => p.Resolve(x),
14 19 e => {
15 20 p.Reject(e);
16 21 return default(T);
17 22 }
18 23 );
19 24 return p;
20 25 }
21 26
22 27 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
28 Safe.ArgumentNotNull(that, "that");
23 29 Safe.ArgumentNotNull(context, "context");
24 30
25 31 var p = new SyncContextPromise<T>(context, that, true);
26 32
27 33 that.Then(
28 34 x => p.Resolve(x),
29 35 e => {
30 36 p.Reject(e);
31 37 return default(T);
32 38 }
33 39 );
34 40 return p;
35 41 }
42
43 public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult,T> callback) {
44 Safe.ArgumentNotNull(that, "that");
45 Safe.ArgumentNotNull(callback, "callback");
46 return ar => {
47 try {
48 that.Resolve(callback(ar));
49 } catch (Exception err) {
50 that.Reject(err);
51 }
52 };
53 }
54
55 #if NET_4_5
56
57 public static Task<T> GetTask<T>(this IPromise<T> that) {
58 Safe.ArgumentNotNull(that, "that");
59 var tcs = new TaskCompletionSource<T>();
60
61 that.Last(tcs.SetResult, tcs.SetException, tcs.SetCanceled);
62
63 return tcs.Task;
64 }
65
66 #endif
36 67 }
37 68 }
38 69
General Comments 0
You need to be logged in to leave comments. Login now