| @@ -26,7 +26,7 namespace Implab | |||||
| 26 | /// <summary> |
|
26 | /// <summary> | |
| 27 | /// Tries to cancel the promise or the complete chain. |
|
27 | /// Tries to cancel the promise or the complete chain. | |
| 28 | /// </summary> |
|
28 | /// </summary> | |
| 29 |
/// <param name="dependencies">Try to cancel the parent promise |
|
29 | /// <param name="dependencies">Try to cancel the whole promise chain, the parent promise will be cancelled only if it has only one promise</param> | |
| 30 | /// <returns></returns> |
|
30 | /// <returns></returns> | |
| 31 | bool Cancel(bool dependencies); |
|
31 | bool Cancel(bool dependencies); | |
| 32 | } |
|
32 | } | |
| @@ -48,28 +48,32 namespace Implab { | |||||
| 48 | /// ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡ ΠΈΠ½Π°ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ. |
|
48 | /// ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡ ΠΈΠ½Π°ΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ. | |
| 49 | /// </para> |
|
49 | /// </para> | |
| 50 | /// </remarks> |
|
50 | /// </remarks> | |
| 51 | public class Promise<T>: IPromise { |
|
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 | public Action cancelHandler; |
|
|||
| 57 | } |
|
56 | } | |
| 58 |
|
57 | |||
| 59 | LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); |
|
58 | IPromise m_parent; | |
|
|
59 | ||||
|
|
60 | LinkedList<ResultHandlerInfo> m_resultHandlers = new LinkedList<ResultHandlerInfo>(); | |||
|
|
61 | LinkedList<Action> m_cancelHandlers = new LinkedList<Action>(); | |||
|
|
62 | ||||
|
|
63 | object m_lock = new Object(); | |||
|
|
64 | bool m_cancellable; | |||
|
|
65 | ||||
| 60 | PromiseState m_state; |
|
66 | PromiseState m_state; | |
| 61 | bool m_cancellable; |
|
|||
| 62 | T m_result; |
|
67 | T m_result; | |
| 63 | Exception m_error; |
|
68 | Exception m_error; | |
| 64 | IPromise m_parent; |
|
69 | ||
| 65 | int m_childrenCount; |
|
70 | int m_childrenCount; | |
| 66 |
|
71 | |||
| 67 | public Promise() { |
|
72 | public Promise() { | |
| 68 | m_cancellable = true; |
|
73 | m_cancellable = true; | |
| 69 | } |
|
74 | } | |
| 70 |
|
75 | |||
| 71 | public Promise(IPromise parent, bool cancellable) |
|
76 | public Promise(IPromise parent, bool cancellable) { | |
| 72 | { |
|
|||
| 73 | m_cancellable = cancellable; |
|
77 | m_cancellable = cancellable; | |
| 74 | m_parent = parent; |
|
78 | m_parent = parent; | |
| 75 | } |
|
79 | } | |
| @@ -97,9 +101,14 namespace Implab { | |||||
| 97 | m_state = PromiseState.Resolved; |
|
101 | m_state = PromiseState.Resolved; | |
| 98 | } |
|
102 | } | |
| 99 |
|
103 | |||
| 100 | ResultHandlerInfo handler; |
|
104 | // state has been changed to rejected new handlers can't be added | |
|
|
105 | ||||
|
|
106 | foreach (var handler in m_resultHandlers) | |||
|
|
107 | InvokeHandler(handler); | |||
|
|
108 | ||||
|
|
109 | /* ResultHandlerInfo handler; | |||
| 101 | while (FetchNextHandler(out handler)) |
|
110 | while (FetchNextHandler(out handler)) | |
| 102 |
|
|
111 | InvokeHandler(handler); */ | |
| 103 | } |
|
112 | } | |
| 104 |
|
113 | |||
| 105 | /// <summary> |
|
114 | /// <summary> | |
| @@ -117,9 +126,14 namespace Implab { | |||||
| 117 | m_state = PromiseState.Rejected; |
|
126 | m_state = PromiseState.Rejected; | |
| 118 | } |
|
127 | } | |
| 119 |
|
128 | |||
| 120 | ResultHandlerInfo handler; |
|
129 | // state has been changed to rejected new handlers can't be added | |
|
|
130 | ||||
|
|
131 | foreach (var handler in m_resultHandlers) | |||
|
|
132 | InvokeHandler(handler); | |||
|
|
133 | ||||
|
|
134 | /*ResultHandlerInfo handler; | |||
| 121 | while (FetchNextHandler(out handler)) |
|
135 | while (FetchNextHandler(out handler)) | |
| 122 |
|
|
136 | InvokeHandler(handler);*/ | |
| 123 | } |
|
137 | } | |
| 124 |
|
138 | |||
| 125 | /// <summary> |
|
139 | /// <summary> | |
| @@ -127,19 +141,7 namespace Implab { | |||||
| 127 | /// </summary> |
|
141 | /// </summary> | |
| 128 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> |
|
142 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> | |
| 129 | public bool Cancel() { |
|
143 | public bool Cancel() { | |
| 130 | lock (this) { |
|
144 | return Cancel(true); | |
| 131 | if (m_state == PromiseState.Unresolved && m_cancellable) |
|
|||
| 132 | { |
|
|||
| 133 | m_state = PromiseState.Cancelled; |
|
|||
| 134 | EventHandler temp = Cancelled; |
|
|||
| 135 |
|
||||
| 136 | if (temp != null) |
|
|||
| 137 | temp(this, new EventArgs()); |
|
|||
| 138 |
|
||||
| 139 | return true; |
|
|||
| 140 | } else |
|
|||
| 141 | return false; |
|
|||
| 142 | } |
|
|||
| 143 | } |
|
145 | } | |
| 144 |
|
146 | |||
| 145 | /// <summary> |
|
147 | /// <summary> | |
| @@ -353,9 +355,9 namespace Implab { | |||||
| 353 | lock (this) { |
|
355 | lock (this) { | |
| 354 | Debug.Assert(m_state != PromiseState.Unresolved); |
|
356 | Debug.Assert(m_state != PromiseState.Unresolved); | |
| 355 |
|
357 | |||
| 356 |
if (m_ |
|
358 | if (m_resultHandlers.Count > 0) { | |
| 357 |
handler = m_ |
|
359 | handler = m_resultHandlers.First.Value; | |
| 358 |
m_ |
|
360 | m_resultHandlers.RemoveFirst(); | |
| 359 | return true; |
|
361 | return true; | |
| 360 | } else { |
|
362 | } else { | |
| 361 | return false; |
|
363 | return false; | |
| @@ -368,7 +370,7 namespace Implab { | |||||
| 368 |
|
370 | |||
| 369 | lock (this) { |
|
371 | lock (this) { | |
| 370 | if (m_state == PromiseState.Unresolved) |
|
372 | if (m_state == PromiseState.Unresolved) | |
| 371 |
m_ |
|
373 | m_resultHandlers.AddLast(handler); | |
| 372 | else |
|
374 | else | |
| 373 | invokeRequired = true; |
|
375 | invokeRequired = true; | |
| 374 | } |
|
376 | } | |
| @@ -395,5 +397,47 namespace Implab { | |||||
| 395 | } |
|
397 | } | |
| 396 |
|
398 | |||
| 397 |
|
399 | |||
|
|
400 | ||||
|
|
401 | public bool IsExclusive { | |||
|
|
402 | get { | |||
|
|
403 | lock (m_lock) { | |||
|
|
404 | return m_childrenCount <= 1; | |||
|
|
405 | } | |||
|
|
406 | } | |||
|
|
407 | } | |||
|
|
408 | ||||
|
|
409 | public PromiseState State { | |||
|
|
410 | get { | |||
|
|
411 | lock (m_lock) { | |||
|
|
412 | return m_state; | |||
|
|
413 | } | |||
|
|
414 | } | |||
|
|
415 | } | |||
|
|
416 | ||||
|
|
417 | public bool Cancel(bool dependencies) { | |||
|
|
418 | bool result; | |||
|
|
419 | ||||
|
|
420 | lock (m_lock) { | |||
|
|
421 | if (m_state == PromiseState.Unresolved) { | |||
|
|
422 | m_state = PromiseState.Cancelled; | |||
|
|
423 | result = true; | |||
|
|
424 | } else { | |||
|
|
425 | result = false; | |||
|
|
426 | } | |||
|
|
427 | } | |||
|
|
428 | ||||
|
|
429 | if (dependencies && m_parent != null && m_parent.IsExclusive) { | |||
|
|
430 | // TODO syncronize IsExclusive, AddHandler, Cancel (maybe CancelExclusive) | |||
|
|
431 | m_parent.Cancel(true); | |||
|
|
432 | } | |||
|
|
433 | ||||
|
|
434 | if (result) { | |||
|
|
435 | // state has been changed to cancelled, new handlers can't be added | |||
|
|
436 | foreach (var handler in m_cancelHandlers) | |||
|
|
437 | handler(); | |||
|
|
438 | } | |||
|
|
439 | ||||
|
|
440 | return result; | |||
|
|
441 | } | |||
| 398 | } |
|
442 | } | |
| 399 | } |
|
443 | } | |
General Comments 0
You need to be logged in to leave comments.
Login now
