##// END OF EJS Templates
minor fixes and optimizations
cin -
r107:f5220e5472ef v2
parent child
Show More
@@ -48,14 +48,14 namespace Implab {
48 48 public abstract void Cancel();
49 49 }
50 50
51 protected class HandlerDescriptor<T2> : AbstractHandler {
51 protected class RemapDescriptor<T2> : AbstractHandler {
52 52
53 53 readonly Func<T,T2> m_resultHandler;
54 54 readonly Func<Exception,T2> m_errorHandler;
55 55 readonly Action m_cancellHandler;
56 56 readonly Promise<T2> m_medium;
57 57
58 public HandlerDescriptor(Func<T,T2> resultHandler, Func<Exception,T2> errorHandler, Action cancelHandler, Promise<T2> medium) {
58 public RemapDescriptor(Func<T,T2> resultHandler, Func<Exception,T2> errorHandler, Action cancelHandler, Promise<T2> medium) {
59 59 m_resultHandler = resultHandler;
60 60 m_errorHandler = errorHandler;
61 61 m_cancellHandler = cancelHandler;
@@ -82,9 +82,61 namespace Implab {
82 82 var res = m_errorHandler(error);
83 83 if (m_medium != null)
84 84 m_medium.Resolve(res);
85 /*} catch (TransientPromiseException err2) {
86 if (medium != null)
87 medium.Reject(err2.InnerException);*/
85 } catch (Exception err2) {
86 if (m_medium != null)
87 m_medium.Reject(err2);
88 }
89 } else if (m_medium != null)
90 m_medium.Reject(error);
91 }
92
93 public override void Cancel() {
94 if (m_cancellHandler != null) {
95 try {
96 m_cancellHandler();
97 } catch (Exception err) {
98 Reject(err);
99 return;
100 }
101 }
102 if (m_medium != null)
103 m_medium.Cancel();
104 }
105 }
106
107 protected class HandlerDescriptor : AbstractHandler {
108
109 readonly Action<T> m_resultHandler;
110 readonly Action<Exception> m_errorHandler;
111 readonly Action m_cancellHandler;
112 readonly Promise<T> m_medium;
113
114 public HandlerDescriptor(Action<T> resultHandler, Action<Exception> errorHandler, Action cancelHandler, Promise<T> medium) {
115 m_resultHandler = resultHandler;
116 m_errorHandler = errorHandler;
117 m_cancellHandler = cancelHandler;
118 m_medium = medium;
119 }
120
121 public override void Resolve(T result) {
122 if (m_resultHandler != null) {
123 try {
124 m_resultHandler(result);
125 } catch (Exception e) {
126 Reject(e);
127 return;
128 }
129 }
130 if(m_medium != null)
131 m_medium.Resolve(result);
132 }
133
134 public override void Reject(Exception error) {
135 if (m_errorHandler != null) {
136 try {
137 m_errorHandler(error);
138 if (m_medium != null)
139 m_medium.Resolve(default(T));
88 140 } catch (Exception err2) {
89 141 if (m_medium != null)
90 142 m_medium.Reject(err2);
@@ -126,7 +178,7 namespace Implab {
126 178
127 179 public Promise(IPromise parent) {
128 180 if (parent != null)
129 AddHandler<T>(
181 AddMappers<T>(
130 182 null,
131 183 null,
132 184 () => {
@@ -252,43 +304,28 namespace Implab {
252 304 if (success == null && error == null && cancel == null)
253 305 return;
254 306
255 AddHandler(
256 success != null ? new Func<T,T>(x => {
257 success(x);
258 return x;
259 }) : null,
260 error != null ? new Func<Exception,T>(e => {
261 error(e);
262 return default(T);
263 }) : null,
264 cancel,
265 null,
266 false
267 );
307 AddHandler(success, error, cancel, null, false);
268 308 }
269 309
270 310 public void On(Action<T> success, Action<Exception> error) {
271 On(success, error, null);
311 AddHandler(success, error, null, null, false);
272 312 }
273 313
274 314 public void On(Action<T> success) {
275 On(success, null, null);
315 AddHandler(success, null, null, null, false);
276 316 }
277 317
278 318 public void On(Action handler, PromiseEventType events) {
279 319 Safe.ArgumentNotNull(handler, "handler");
280 320
281 Func<T,T> success = events.HasFlag(PromiseEventType.Success) ? new Func<T,T>(x => {
282 handler();
283 return x;
284 }) : null;
285 Func<Exception,T> error = events.HasFlag(PromiseEventType.Error) ? new Func<Exception,T>(e => {
286 handler();
287 return default(T);
288 }) : null;
289 Action cancel = events.HasFlag(PromiseEventType.Cancelled) ? handler : null;
290 321
291 AddHandler(success, error, cancel, null, false);
322 AddHandler(
323 events.HasFlag(PromiseEventType.Success) ? new Action<T>(x => handler()) : null,
324 events.HasFlag(PromiseEventType.Error) ? new Action<Exception>( x => handler()) : null,
325 events.HasFlag(PromiseEventType.Cancelled) ? handler : null,
326 null,
327 false
328 );
292 329 }
293 330
294 331 public IPromise Error(Action<Exception> error) {
@@ -297,7 +334,7 namespace Implab {
297 334
298 335 var medium = new Promise<T>(this);
299 336
300 AddHandler(
337 AddMappers(
301 338 null,
302 339 e => {
303 340 error(e);
@@ -325,7 +362,7 namespace Implab {
325 362
326 363 var medium = new Promise<T>(this);
327 364
328 AddHandler(null, handler, null, medium, true);
365 AddMappers(null, handler, null, medium, true);
329 366
330 367 return medium;
331 368 }
@@ -345,7 +382,7 namespace Implab {
345 382 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
346 383 var medium = new Promise<TNew>(this);
347 384
348 AddHandler(
385 AddMappers(
349 386 mapper,
350 387 error,
351 388 cancel,
@@ -454,7 +491,7 namespace Implab {
454 491 else
455 492 cancelHandler = medium.Cancel;
456 493
457 AddHandler(
494 AddMappers(
458 495 resultHandler,
459 496 errorHandler,
460 497 cancelHandler,
@@ -490,10 +527,7 namespace Implab {
490 527 var medium = new Promise<T>(this);
491 528
492 529 AddHandler(
493 x => {
494 handler();
495 return x;
496 },
530 x => handler(),
497 531 e => {
498 532 handler();
499 533 throw new TransientPromiseException(e);
@@ -559,11 +593,37 namespace Implab {
559 593 return Join(Timeout.Infinite);
560 594 }
561 595
562 void AddHandler<T2>(Func<T,T2> success, Func<Exception,T2> error, Action cancel, Promise<T2> medium, bool inc) {
596 void AddMappers<T2>(Func<T,T2> success, Func<Exception,T2> error, Action cancel, Promise<T2> medium, bool inc) {
563 597 if (inc)
564 598 Interlocked.Increment(ref m_childrenCount);
565 599
566 AbstractHandler handler = new HandlerDescriptor<T2>(success, error, cancel, medium);
600 AbstractHandler handler = new RemapDescriptor<T2>(success, error, cancel, medium);
601
602 bool queued;
603
604 if (!IsResolved) {
605 m_handlers.Enqueue(handler);
606 queued = true;
607 } else {
608 // the promise is in resolved state, just invoke the handled with minimum overhead
609 queued = false;
610 InvokeHandler(handler);
611 }
612
613 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
614 // if the promise have been resolved while we was adding handler to the queue
615 // we can't guarantee that someone is still processing it
616 // therefore we will fetch a handler from the queue and execute it
617 // note that fetched handler may be not the one that we have added
618 // even we can fetch no handlers at all :)
619 InvokeHandler(handler);
620 }
621
622 void AddHandler(Action<T> success, Action<Exception> error, Action cancel, Promise<T> medium, bool inc) {
623 if (inc)
624 Interlocked.Increment(ref m_childrenCount);
625
626 AbstractHandler handler = new HandlerDescriptor(success, error, cancel, medium);
567 627
568 628 bool queued;
569 629
@@ -834,7 +894,7 namespace Implab {
834 894 else
835 895 cancelHandler = medium.Cancel;
836 896
837 AddHandler(
897 AddMappers(
838 898 resultHandler,
839 899 errorHandler,
840 900 cancelHandler,
General Comments 0
You need to be logged in to leave comments. Login now