@@ -26,7 +26,7 namespace Implab | |||
|
26 | 26 | /// <summary> |
|
27 | 27 | /// Tries to cancel the promise or the complete chain. |
|
28 | 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 | 30 | /// <returns></returns> |
|
31 | 31 | bool Cancel(bool dependencies); |
|
32 | 32 | } |
@@ -53,23 +53,27 namespace Implab { | |||
|
53 | 53 | struct ResultHandlerInfo { |
|
54 | 54 | public ResultHandler<T> resultHandler; |
|
55 | 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 | 66 | PromiseState m_state; |
|
61 | bool m_cancellable; | |
|
62 | 67 | T m_result; |
|
63 | 68 | Exception m_error; |
|
64 | IPromise m_parent; | |
|
69 | ||
|
65 | 70 | int m_childrenCount; |
|
66 | 71 | |
|
67 | 72 | public Promise() { |
|
68 | 73 | m_cancellable = true; |
|
69 | 74 | } |
|
70 | 75 | |
|
71 | public Promise(IPromise parent, bool cancellable) | |
|
72 | { | |
|
76 | public Promise(IPromise parent, bool cancellable) { | |
|
73 | 77 | m_cancellable = cancellable; |
|
74 | 78 | m_parent = parent; |
|
75 | 79 | } |
@@ -97,9 +101,14 namespace Implab { | |||
|
97 | 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 | 110 | while (FetchNextHandler(out handler)) |
|
102 |
|
|
|
111 | InvokeHandler(handler); */ | |
|
103 | 112 | } |
|
104 | 113 | |
|
105 | 114 | /// <summary> |
@@ -117,9 +126,14 namespace Implab { | |||
|
117 | 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 | 135 | while (FetchNextHandler(out handler)) |
|
122 |
|
|
|
136 | InvokeHandler(handler);*/ | |
|
123 | 137 | } |
|
124 | 138 | |
|
125 | 139 | /// <summary> |
@@ -127,19 +141,7 namespace Implab { | |||
|
127 | 141 | /// </summary> |
|
128 | 142 | /// <returns><c>true</c> ΠΠΏΠ΅ΡΠ°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΡΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ Π±ΡΠ΄ΡΡ Π²ΡΠ·Π²Π°Π½Ρ.<c>false</c> ΠΎΡΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ ΡΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π»ΠΈ.</returns> |
|
129 | 143 | public bool Cancel() { |
|
130 | lock (this) { | |
|
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 | } | |
|
144 | return Cancel(true); | |
|
143 | 145 | } |
|
144 | 146 | |
|
145 | 147 | /// <summary> |
@@ -353,9 +355,9 namespace Implab { | |||
|
353 | 355 | lock (this) { |
|
354 | 356 | Debug.Assert(m_state != PromiseState.Unresolved); |
|
355 | 357 | |
|
356 |
if (m_ |
|
|
357 |
handler = m_ |
|
|
358 |
m_ |
|
|
358 | if (m_resultHandlers.Count > 0) { | |
|
359 | handler = m_resultHandlers.First.Value; | |
|
360 | m_resultHandlers.RemoveFirst(); | |
|
359 | 361 | return true; |
|
360 | 362 | } else { |
|
361 | 363 | return false; |
@@ -368,7 +370,7 namespace Implab { | |||
|
368 | 370 | |
|
369 | 371 | lock (this) { |
|
370 | 372 | if (m_state == PromiseState.Unresolved) |
|
371 |
m_ |
|
|
373 | m_resultHandlers.AddLast(handler); | |
|
372 | 374 | else |
|
373 | 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 | } | |
|
398 | 414 | } |
|
399 | 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 | } | |
|
442 | } | |
|
443 | } |
General Comments 0
You need to be logged in to leave comments.
Login now