| @@ -0,0 +1,33 | |||||
|  | 1 | using System; | |||
|  | 2 | using System.Collections.Generic; | |||
|  | 3 | using System.Linq; | |||
|  | 4 | using System.Text; | |||
|  | 5 | ||||
|  | 6 | namespace Implab | |||
|  | 7 | { | |||
|  | 8 | public interface IPromise | |||
|  | 9 | { | |||
|  | 10 | /// <summary> | |||
|  | 11 | /// Check whereather the promise has no more than one dependent promise. | |||
|  | 12 | /// </summary> | |||
|  | 13 | bool IsExclusive | |||
|  | 14 | { | |||
|  | 15 | get; | |||
|  | 16 | } | |||
|  | 17 | ||||
|  | 18 | /// <summary> | |||
|  | 19 | /// The current state of the promise. | |||
|  | 20 | /// </summary> | |||
|  | 21 | PromiseState State | |||
|  | 22 | { | |||
|  | 23 | get; | |||
|  | 24 | } | |||
|  | 25 | ||||
|  | 26 | /// <summary> | |||
|  | 27 | /// Tries to cancel the promise or the complete chain. | |||
|  | 28 | /// </summary> | |||
|  | 29 | /// <param name="dependencies">Try to cancel the parent promise is it has the only one child</param> | |||
|  | 30 | /// <returns></returns> | |||
|  | 31 | bool Cancel(bool dependencies); | |||
|  | 32 | } | |||
|  | 33 | } | |||
| @@ -0,0 +1,36 | |||||
|  | 1 | using System; | |||
|  | 2 | using System.Collections.Generic; | |||
|  | 3 | using System.Linq; | |||
|  | 4 | using System.Text; | |||
|  | 5 | ||||
|  | 6 | namespace Implab | |||
|  | 7 | { | |||
|  | 8 | ||||
|  | 9 | public class ProgressInitEventArgs: EventArgs | |||
|  | 10 | { | |||
|  | 11 | public float MaxProgress | |||
|  | 12 | { | |||
|  | 13 | get; | |||
|  | 14 | private set; | |||
|  | 15 | } | |||
|  | 16 | ||||
|  | 17 | public float CurrentProgress | |||
|  | 18 | { | |||
|  | 19 | get; | |||
|  | 20 | private set; | |||
|  | 21 | } | |||
|  | 22 | ||||
|  | 23 | public string Message | |||
|  | 24 | { | |||
|  | 25 | get; | |||
|  | 26 | private set; | |||
|  | 27 | } | |||
|  | 28 | ||||
|  | 29 | public ProgressInitEventArgs(float current, float max, string message) | |||
|  | 30 | { | |||
|  | 31 | this.MaxProgress = max; | |||
|  | 32 | this.CurrentProgress = current; | |||
|  | 33 | this.Message = message; | |||
|  | 34 | } | |||
|  | 35 | } | |||
|  | 36 | } | |||
| @@ -0,0 +1,15 | |||||
|  | 1 | using System; | |||
|  | 2 | using System.Collections.Generic; | |||
|  | 3 | using System.Linq; | |||
|  | 4 | using System.Text; | |||
|  | 5 | ||||
|  | 6 | namespace Implab | |||
|  | 7 | { | |||
|  | 8 | public enum PromiseState | |||
|  | 9 | { | |||
|  | 10 | Unresolved, | |||
|  | 11 | Resolved, | |||
|  | 12 | Cancelled, | |||
|  | 13 | Rejected | |||
|  | 14 | } | |||
|  | 15 | } | |||
| @@ -0,0 +1,113 | |||||
|  | 1 | using System; | |||
|  | 2 | using System.Collections.Generic; | |||
|  | 3 | using System.Linq; | |||
|  | 4 | using System.Text; | |||
|  | 5 | using System.Threading; | |||
|  | 6 | ||||
|  | 7 | namespace Implab | |||
|  | 8 | { | |||
|  | 9 | /// <summary> | |||
|  | 10 | /// This class allows to interact with asyncronuos task. | |||
|  | 11 | /// </summary> | |||
|  | 12 | /// <remarks> | |||
|  | 13 | /// Members of this object are thread safe. | |||
|  | 14 | /// </remarks> | |||
|  | 15 | class TaskController | |||
|  | 16 | { | |||
|  | 17 | object m_lock; | |||
|  | 18 | string m_message; | |||
|  | 19 | bool m_cancelled; | |||
|  | 20 | ||||
|  | 21 | float m_current; | |||
|  | 22 | float m_max; | |||
|  | 23 | ||||
|  | 24 | public event EventHandler<ValueEventArgs<string>> MessageUpdated; | |||
|  | 25 | public event EventHandler<ValueEventArgs<float>> ProgressUpdated; | |||
|  | 26 | public event EventHandler<ProgressInitEventArgs> ProgressInit; | |||
|  | 27 | ||||
|  | 28 | public TaskController() | |||
|  | 29 | { | |||
|  | 30 | m_lock = new Object(); | |||
|  | 31 | } | |||
|  | 32 | ||||
|  | 33 | public string Message | |||
|  | 34 | { | |||
|  | 35 | get | |||
|  | 36 | { | |||
|  | 37 | lock (m_lock) | |||
|  | 38 | return m_message; | |||
|  | 39 | } | |||
|  | 40 | set | |||
|  | 41 | { | |||
|  | 42 | lock (m_lock) | |||
|  | 43 | { | |||
|  | 44 | m_message = value; | |||
|  | 45 | OnMessageUpdated(); | |||
|  | 46 | } | |||
|  | 47 | } | |||
|  | 48 | } | |||
|  | 49 | ||||
|  | 50 | public float CurrentProgress | |||
|  | 51 | { | |||
|  | 52 | get | |||
|  | 53 | { | |||
|  | 54 | lock (m_lock) | |||
|  | 55 | return m_current; | |||
|  | 56 | } | |||
|  | 57 | set | |||
|  | 58 | { | |||
|  | 59 | lock (m_lock) | |||
|  | 60 | { | |||
|  | 61 | var prev = m_current; | |||
|  | 62 | m_current = value; | |||
|  | 63 | if (m_current >= m_max) | |||
|  | 64 | m_current = m_max; | |||
|  | 65 | if (m_current != prev) | |||
|  | 66 | OnProgressUpdated(); | |||
|  | 67 | } | |||
|  | 68 | } | |||
|  | 69 | } | |||
|  | 70 | ||||
|  | 71 | public void InitProgress(float current, float max, string message) | |||
|  | 72 | { | |||
|  | 73 | if (max < 0) | |||
|  | 74 | throw new ArgumentOutOfRangeException("max"); | |||
|  | 75 | if (current < 0 || current > max) | |||
|  | 76 | throw new ArgumentOutOfRangeException("current"); | |||
|  | 77 | ||||
|  | 78 | lock(m_lock) { | |||
|  | 79 | m_current = current; | |||
|  | 80 | m_max = max; | |||
|  | 81 | m_message = message; | |||
|  | 82 | OnProgressInit(); | |||
|  | 83 | } | |||
|  | 84 | } | |||
|  | 85 | ||||
|  | 86 | protected virtual void OnMessageUpdated() | |||
|  | 87 | { | |||
|  | 88 | var temp = MessageUpdated; | |||
|  | 89 | if (temp != null) | |||
|  | 90 | { | |||
|  | 91 | temp(this, new ValueEventArgs<string>(m_message)); | |||
|  | 92 | } | |||
|  | 93 | } | |||
|  | 94 | ||||
|  | 95 | protected virtual void OnProgressUpdated() | |||
|  | 96 | { | |||
|  | 97 | var temp = ProgressUpdated; | |||
|  | 98 | if (temp != null) | |||
|  | 99 | { | |||
|  | 100 | temp(this,new ValueEventArgs<float>(m_current)); | |||
|  | 101 | } | |||
|  | 102 | } | |||
|  | 103 | ||||
|  | 104 | protected virtual void OnProgressInit() | |||
|  | 105 | { | |||
|  | 106 | var temp = ProgressInit; | |||
|  | 107 | if (temp != null) | |||
|  | 108 | { | |||
|  | 109 | temp(this, new ProgressInitEventArgs(m_current,m_max, m_message)); | |||
|  | 110 | } | |||
|  | 111 | } | |||
|  | 112 | } | |||
|  | 113 | } | |||
| @@ -0,0 +1,20 | |||||
|  | 1 | using System; | |||
|  | 2 | using System.Collections.Generic; | |||
|  | 3 | using System.Linq; | |||
|  | 4 | using System.Text; | |||
|  | 5 | ||||
|  | 6 | namespace Implab | |||
|  | 7 | { | |||
|  | 8 | public class ValueEventArgs<T>: EventArgs | |||
|  | 9 | { | |||
|  | 10 | public ValueEventArgs(T value) | |||
|  | 11 | { | |||
|  | 12 | this.Value = value; | |||
|  | 13 | } | |||
|  | 14 | public T Value | |||
|  | 15 | { | |||
|  | 16 | get; | |||
|  | 17 | private set; | |||
|  | 18 | } | |||
|  | 19 | } | |||
|  | 20 | } | |||
| 1 | NO CONTENT: modified file, binary diff hidden |  | NO CONTENT: modified file, binary diff hidden | 
| @@ -32,10 +32,14 | |||||
| 32 | <Reference Include="System" /> |  | 32 | <Reference Include="System" /> | |
| 33 | </ItemGroup> |  | 33 | </ItemGroup> | |
| 34 | <ItemGroup> |  | 34 | <ItemGroup> | |
|  | 35 | <Compile Include="ICancellable.cs" /> | |||
|  | 36 | <Compile Include="TaskController.cs" /> | |||
|  | 37 | <Compile Include="ProgressInitEventArgs.cs" /> | |||
| 35 | <Compile Include="Properties\AssemblyInfo.cs" /> |  | 38 | <Compile Include="Properties\AssemblyInfo.cs" /> | |
| 36 | <Compile Include="Promise.cs" /> |  | 39 | <Compile Include="Promise.cs" /> | |
| 37 | <Compile Include="AsyncPool.cs" /> |  | 40 | <Compile Include="AsyncPool.cs" /> | |
| 38 | <Compile Include="Safe.cs" /> |  | 41 | <Compile Include="Safe.cs" /> | |
|  | 42 | <Compile Include="ValueEventArgs.cs" /> | |||
| 39 | </ItemGroup> |  | 43 | </ItemGroup> | |
| 40 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |  | 44 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | |
| 41 | <ItemGroup> |  | 45 | <ItemGroup> | |
| @@ -48,30 +48,32 namespace Implab { | |||||
| 48 | /// ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡ ΠΈΠ½Π°ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ. |  | 48 | /// ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡ ΠΈΠ½Π°ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ. | |
| 49 | /// </para> |  | 49 | /// </para> | |
| 50 | /// </remarks> |  | 50 | /// </remarks> | |
| 51 | public class Promise<T> { |  | 51 | public class Promise<T>: IPromise { | |
| 52 |  | 52 | |||
| 53 | struct ResultHandlerInfo { |  | 53 | struct ResultHandlerInfo { | |
| 54 | public ResultHandler<T> resultHandler; |  | 54 | public ResultHandler<T> resultHandler; | |
| 55 | public ErrorHandler errorHandler; |  | 55 | public ErrorHandler errorHandler; | |
| 56 | } |  | 56 | public Action cancelHandler; | |
| 57 |  | ||||
| 58 | enum State { |  | |||
| 59 | Unresolved, |  | |||
| 60 | Resolving, |  | |||
| 61 | Resolved, |  | |||
| 62 | Cancelled |  | |||
| 63 | } |  | 57 | } | |
| 64 |  | 58 | |||
| 65 | LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); |  | 59 | LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); | |
| 66 | State m_state; |  | 60 | PromiseState m_state; | |
| 67 | bool m_cancellable; |  | 61 | bool m_cancellable; | |
| 68 | T m_result; |  | 62 | T m_result; | |
| 69 | Exception m_error; |  | 63 | Exception m_error; | |
|  | 64 | IPromise m_parent; | |||
|  | 65 | int m_childrenCount; | |||
| 70 |  | 66 | |||
| 71 | public Promise() { |  | 67 | public Promise() { | |
| 72 | m_cancellable = true; |  | 68 | m_cancellable = true; | |
| 73 | } |  | 69 | } | |
| 74 |  | 70 | |||
|  | 71 | public Promise(IPromise parent, bool cancellable) | |||
|  | 72 | { | |||
|  | 73 | m_cancellable = cancellable; | |||
|  | 74 | m_parent = parent; | |||
|  | 75 | } | |||
|  | 76 | ||||
| 75 | /// <summary> |  | 77 | /// <summary> | |
| 76 | /// Π‘ΠΎΠ±ΡΡΠΈΠ΅, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡΠ΅Π΅ ΠΏΡΠΈ ΠΎΡΠΌΠ΅Π½Π΅ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ. |  | 78 | /// Π‘ΠΎΠ±ΡΡΠΈΠ΅, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡΠ΅Π΅ ΠΏΡΠΈ ΠΎΡΠΌΠ΅Π½Π΅ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ. | |
| 77 | /// </summary> |  | 79 | /// </summary> | |
| @@ -87,12 +89,12 namespace Implab { | |||||
| 87 | /// <exception cref="InvalidOperationException">ΠΠ°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception> |  | 89 | /// <exception cref="InvalidOperationException">ΠΠ°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception> | |
| 88 | public void Resolve(T result) { |  | 90 | public void Resolve(T result) { | |
| 89 | lock (this) { |  | 91 | lock (this) { | |
| 90 | if (m_state == State.Cancelled) |  | 92 | if (m_state == PromiseState.Cancelled) | |
| 91 | return; |  | 93 | return; | |
| 92 | if (m_state != State.Unresolved) |  | 94 | if (m_state != PromiseState.Unresolved) | |
| 93 | throw new InvalidOperationException("The promise is already resolved"); |  | 95 | throw new InvalidOperationException("The promise is already resolved"); | |
| 94 | m_result = result; |  | 96 | m_result = result; | |
| 95 | m_state = State.Resolv |  | 97 | m_state = PromiseState.Resolved; | |
| 96 | } |  | 98 | } | |
| 97 |  | 99 | |||
| 98 | ResultHandlerInfo handler; |  | 100 | ResultHandlerInfo handler; | |
| @@ -107,12 +109,12 namespace Implab { | |||||
| 107 | /// <exception cref="InvalidOperationException">ΠΠ°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception> |  | 109 | /// <exception cref="InvalidOperationException">ΠΠ°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception> | |
| 108 | public void Reject(Exception error) { |  | 110 | public void Reject(Exception error) { | |
| 109 | lock (this) { |  | 111 | lock (this) { | |
| 110 | if (m_state == State.Cancelled) |  | 112 | if (m_state == PromiseState.Cancelled) | |
| 111 | return; |  | 113 | return; | |
| 112 | if (m_state != State.Unresolved) |  | 114 | if (m_state != PromiseState.Unresolved) | |
| 113 | throw new InvalidOperationException("The promise is already resolved"); |  | 115 | throw new InvalidOperationException("The promise is already resolved"); | |
| 114 | m_error = error; |  | 116 | m_error = error; | |
| 115 | m_state = State.Re |  | 117 | m_state = PromiseState.Rejected; | |
| 116 | } |  | 118 | } | |
| 117 |  | 119 | |||
| 118 | ResultHandlerInfo handler; |  | 120 | ResultHandlerInfo handler; | |
| @@ -126,8 +128,9 namespace Implab { | |||||
| 126 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> |  | 128 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> | |
| 127 | public bool Cancel() { |  | 129 | public bool Cancel() { | |
| 128 | lock (this) { |  | 130 | lock (this) { | |
| 129 | if (m_state == State.Unresolved && m_cancellable) |  | 131 | if (m_state == PromiseState.Unresolved && m_cancellable) | |
| 130 | m_state = State.Cancelled; |  | 132 | { | |
|  | 133 | m_state = PromiseState.Cancelled; | |||
| 131 | EventHandler temp = Cancelled; |  | 134 | EventHandler temp = Cancelled; | |
| 132 |  | 135 | |||
| 133 | if (temp != null) |  | 136 | if (temp != null) | |
| @@ -348,14 +351,13 namespace Implab { | |||||
| 348 | handler = default(ResultHandlerInfo); |  | 351 | handler = default(ResultHandlerInfo); | |
| 349 |  | 352 | |||
| 350 | lock (this) { |  | 353 | lock (this) { | |
| 351 | Debug.Assert(m_state |  | 354 | Debug.Assert(m_state != PromiseState.Unresolved); | |
| 352 |  | 355 | |||
| 353 | if (m_handlersChain.Count > 0) { |  | 356 | if (m_handlersChain.Count > 0) { | |
| 354 | handler = m_handlersChain.First.Value; |  | 357 | handler = m_handlersChain.First.Value; | |
| 355 | m_handlersChain.RemoveFirst(); |  | 358 | m_handlersChain.RemoveFirst(); | |
| 356 | return true; |  | 359 | return true; | |
| 357 | } else { |  | 360 | } else { | |
| 358 | m_state = State.Resolved; |  | |||
| 359 | return false; |  | 361 | return false; | |
| 360 | } |  | 362 | } | |
| 361 | } |  | 363 | } | |
| @@ -365,7 +367,7 namespace Implab { | |||||
| 365 | bool invokeRequired = false; |  | 367 | bool invokeRequired = false; | |
| 366 |  | 368 | |||
| 367 | lock (this) { |  | 369 | lock (this) { | |
| 368 | if (m_state |  | 370 | if (m_state == PromiseState.Unresolved) | |
| 369 | m_handlersChain.AddLast(handler); |  | 371 | m_handlersChain.AddLast(handler); | |
| 370 | else |  | 372 | else | |
| 371 | invokeRequired = true; |  | 373 | invokeRequired = true; | |
        
        General Comments 0
    
    
  
  
                      You need to be logged in to leave comments.
                      Login now
                    
                