##// END OF EJS Templates
sync
cin -
r9:c82e0dfbb4dd promises
parent child
Show More
@@ -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 is it has the only one child</param>
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 }
@@ -53,23 +53,27 namespace Implab {
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 InvokeHandler(handler);
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 InvokeHandler(handler);
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_handlersChain.Count > 0) {
358 if (m_resultHandlers.Count > 0) {
357 handler = m_handlersChain.First.Value;
359 handler = m_resultHandlers.First.Value;
358 m_handlersChain.RemoveFirst();
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_handlersChain.AddLast(handler);
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 }
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