comparison Implab/Promise.cs @ 104:5f10d54b45df v2

renamed Promise.Last -> Promise.On Promise.On doesn't changes Promise.IsExclusive property
author cin
date Sun, 09 Nov 2014 23:03:45 +0300
parents 279e226dffdd
children 4d308952fd5e
comparison
equal deleted inserted replaced
103:b3f5bc613905 104:5f10d54b45df
115 null, 115 null,
116 () => { 116 () => {
117 if (parent.IsExclusive) 117 if (parent.IsExclusive)
118 parent.Cancel(); 118 parent.Cancel();
119 }, 119 },
120 null 120 null,
121 false
121 ); 122 );
122 } 123 }
123 124
124 bool BeginTransit() { 125 bool BeginTransit() {
125 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE); 126 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
218 if (success == null && error == null && cancel == null) 219 if (success == null && error == null && cancel == null)
219 return this; 220 return this;
220 221
221 var medium = new Promise<T>(this); 222 var medium = new Promise<T>(this);
222 223
223 AddHandler(success, error, cancel, medium); 224 AddHandler(success, error, cancel, medium, true);
224 225
225 return medium; 226 return medium;
226 } 227 }
227 228
228 /// <summary> 229 /// <summary>
236 if (success == null && error == null) 237 if (success == null && error == null)
237 return this; 238 return this;
238 239
239 var medium = new Promise<T>(this); 240 var medium = new Promise<T>(this);
240 241
241 AddHandler(success, error, null, medium); 242 AddHandler(success, error, null, medium, true);
242 243
243 return medium; 244 return medium;
244 } 245 }
245 246
246 247
250 if (success == null) 251 if (success == null)
251 return this; 252 return this;
252 253
253 var medium = new Promise<T>(this); 254 var medium = new Promise<T>(this);
254 255
255 AddHandler(success, null, null, medium); 256 AddHandler(success, null, null, medium, true);
256 257
257 return medium; 258 return medium;
258 } 259 }
259 260
260 /// <summary> 261 /// <summary>
272 /// Если данный метод вызвать несколько раз, либо добавить другие обработчики, то цепочка 273 /// Если данный метод вызвать несколько раз, либо добавить другие обработчики, то цепочка
273 /// не будет одиночной <see cref="IsExclusive"/> и, как следствие, будет невозможна отмена 274 /// не будет одиночной <see cref="IsExclusive"/> и, как следствие, будет невозможна отмена
274 /// всей цепи обещаний снизу (с самого последнего обещания). 275 /// всей цепи обещаний снизу (с самого последнего обещания).
275 /// </para> 276 /// </para>
276 /// </remarks> 277 /// </remarks>
277 public void Last(Action<T> success, Action<Exception> error, Action cancel) { 278 public void On(Action<T> success, Action<Exception> error, Action cancel) {
278 if (success == null && error == null && cancel == null) 279 if (success == null && error == null && cancel == null)
279 return; 280 return;
280 281
281 Func<Exception,T> errorHandler = null; 282 Func<Exception,T> errorHandler = null;
282 if (error != null) 283 if (error != null)
283 errorHandler = err => { 284 errorHandler = err => {
284 error(err); 285 error(err);
285 return default(T); 286 return default(T);
286 }; 287 };
287 AddHandler(success, errorHandler, cancel, null); 288 AddHandler(success, errorHandler, cancel, null, false);
288 } 289 }
289 290
290 public void Last(Action<T> success, Action<Exception> error) { 291 public void On(Action<T> success, Action<Exception> error) {
291 Last(success, error, null); 292 On(success, error, null);
292 } 293 }
293 294
294 public void Last(Action<T> success) { 295 public void On(Action<T> success) {
295 Last(success, null, null); 296 On(success, null, null);
297 }
298
299 public void On(Action handler, PromiseEventType events) {
300 Safe.ArgumentNotNull(handler, "handler");
301
302 Action<T> success = events.HasFlag(PromiseEventType.Success) ? new Action<T>(x => handler()) : null;
303 Func<Exception,T> error = events.HasFlag(PromiseEventType.Error) ? new Func<Exception,T>(e => {
304 handler();
305 return default(T);
306 }) : null;
307 Action cancel = events.HasFlag(PromiseEventType.Cancelled) ? handler : null;
308
309 AddHandler(success, error, cancel, null, false);
296 } 310 }
297 311
298 public IPromise Error(Action<Exception> error) { 312 public IPromise Error(Action<Exception> error) {
299 if (error == null) 313 if (error == null)
300 return this; 314 return this;
306 e => { 320 e => {
307 error(e); 321 error(e);
308 return default(T); 322 return default(T);
309 }, 323 },
310 null, 324 null,
311 medium 325 medium,
326 true
312 ); 327 );
313 328
314 return medium; 329 return medium;
315 } 330 }
316 331
326 if (handler == null) 341 if (handler == null)
327 return this; 342 return this;
328 343
329 var medium = new Promise<T>(this); 344 var medium = new Promise<T>(this);
330 345
331 AddHandler(null, handler, null, medium); 346 AddHandler(null, handler, null, medium, true);
332 347
333 return medium; 348 return medium;
334 } 349 }
335 350
336 /// <summary> 351 /// <summary>
378 393
379 AddHandler( 394 AddHandler(
380 resultHandler, 395 resultHandler,
381 errorHandler, 396 errorHandler,
382 cancelHandler, 397 cancelHandler,
383 null 398 null,
399 true
384 ); 400 );
385 401
386 return medium; 402 return medium;
387 } 403 }
388 404
419 if (medium.IsCancelled) 435 if (medium.IsCancelled)
420 return; 436 return;
421 437
422 var promise = chained(result); 438 var promise = chained(result);
423 439
424 promise.Last( 440 promise.On(
425 medium.Resolve, 441 medium.Resolve,
426 medium.Reject, 442 medium.Reject,
427 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка 443 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка
428 ); 444 );
429 445
430 // notify chained operation that it's not needed anymore 446 // notify chained operation that it's not needed anymore
431 // порядок вызова Then, Cancelled важен, поскольку от этого 447 // порядок вызова Then, Cancelled важен, поскольку от этого
432 // зависит IsExclusive 448 // зависит IsExclusive
433 medium.Last( 449 medium.On(
434 null, 450 null,
435 null, 451 null,
436 () => { 452 () => {
437 if (promise.IsExclusive) 453 if (promise.IsExclusive)
438 promise.Cancel(); 454 promise.Cancel();
445 if (error != null) 461 if (error != null)
446 errorHandler = delegate(Exception e) { 462 errorHandler = delegate(Exception e) {
447 try { 463 try {
448 var promise = error(e); 464 var promise = error(e);
449 465
450 promise.Last( 466 promise.On(
451 medium.Resolve, 467 medium.Resolve,
452 medium.Reject, 468 medium.Reject,
453 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка 469 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка
454 ); 470 );
455 471
484 500
485 AddHandler( 501 AddHandler(
486 resultHandler, 502 resultHandler,
487 errorHandler, 503 errorHandler,
488 cancelHandler, 504 cancelHandler,
489 null 505 null,
506 true
490 ); 507 );
491 508
492 return medium; 509 return medium;
493 } 510 }
494 511
500 return Chain(chained, null, null); 517 return Chain(chained, null, null);
501 } 518 }
502 519
503 public IPromise<T> Cancelled(Action handler) { 520 public IPromise<T> Cancelled(Action handler) {
504 var medium = new Promise<T>(this); 521 var medium = new Promise<T>(this);
505 AddHandler(null, null, handler, medium); 522 AddHandler(null, null, handler, medium, false);
506 return medium; 523 return medium;
507 } 524 }
508 525
509 /// <summary> 526 /// <summary>
510 /// Adds the specified handler for all cases (success, error, cancel) 527 /// Adds the specified handler for all cases (success, error, cancel)
511 /// </summary> 528 /// </summary>
512 /// <param name="handler">The handler that will be called anyway</param> 529 /// <param name="handler">The handler that will be called anyway</param>
513 /// <returns>self</returns> 530 /// <returns>self</returns>
514 public IPromise<T> Anyway(Action handler) { 531 public IPromise<T> Anyway(Action handler) {
515 Safe.ArgumentNotNull(handler, "handler"); 532 Safe.ArgumentNotNull(handler, "handler");
516 533
534 var medium = new Promise<T>(this);
535
517 AddHandler( 536 AddHandler(
518 x => handler(), 537 x => handler(),
519 e => { 538 e => {
520 handler(); 539 handler();
521 throw new TransientPromiseException(e); 540 throw new TransientPromiseException(e);
522 }, 541 },
523 handler, 542 handler,
524 null 543 medium,
544 true
525 ); 545 );
526 return this; 546
547 return medium;
527 } 548 }
528 549
529 /// <summary> 550 /// <summary>
530 /// Преобразует результат обещания к нужному типу 551 /// Преобразует результат обещания к нужному типу
531 /// </summary> 552 /// </summary>
577 598
578 public T Join() { 599 public T Join() {
579 return Join(Timeout.Infinite); 600 return Join(Timeout.Infinite);
580 } 601 }
581 602
582 void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium) { 603 void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium, bool inc) {
583 if (success != null || error != null) 604 if (inc)
584 Interlocked.Increment(ref m_childrenCount); 605 Interlocked.Increment(ref m_childrenCount);
585 606
586 var handler = new HandlerDescriptor { 607 var handler = new HandlerDescriptor {
587 resultHandler = success, 608 resultHandler = success,
588 errorHandler = error, 609 errorHandler = error,
782 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { 803 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
783 return ChainNoResult(chained, error, cancel); 804 return ChainNoResult(chained, error, cancel);
784 } 805 }
785 806
786 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { 807 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) {
787 Safe.ArgumentNotNull(chained, "chained"); 808 Safe.ArgumentNotNull(chained, "chained");
788 809
789 var medium = new Promise<object>(this); 810 var medium = new Promise<object>(this);
790 811
791 Action<T> resultHandler = delegate { 812 Action<T> resultHandler = delegate {
792 if (medium.IsCancelled) 813 if (medium.IsCancelled)
793 return; 814 return;
794 815
795 var promise = chained(); 816 var promise = chained();
796 817
797 promise.Last( 818 promise.On(
798 medium.Resolve, 819 medium.Resolve,
799 medium.Reject, 820 medium.Reject,
800 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка 821 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка
801 ); 822 );
802 823
803 // notify chained operation that it's not needed anymore 824 // notify chained operation that it's not needed anymore
804 // порядок вызова Then, Cancelled важен, поскольку от этого 825 // порядок вызова Then, Cancelled важен, поскольку от этого
805 // зависит IsExclusive 826 // зависит IsExclusive
806 medium.Cancelled(() => { 827 medium.Cancelled(() => {
807 if (promise.IsExclusive) 828 if (promise.IsExclusive)
808 promise.Cancel(); 829 promise.Cancel();
809 }); 830 });
810 }; 831 };
811 832
812 Func<Exception,T> errorHandler; 833 Func<Exception,T> errorHandler;
813 834
814 if (error != null) 835 if (error != null)
815 errorHandler = delegate(Exception e) { 836 errorHandler = delegate(Exception e) {
816 try { 837 try {
817 var promise = error(e); 838 var promise = error(e);
818 839
819 promise.Last( 840 promise.On(
820 medium.Resolve, 841 medium.Resolve,
821 medium.Reject, 842 medium.Reject,
822 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка 843 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка
823 ); 844 );
824 845
832 } catch (Exception e2) { 853 } catch (Exception e2) {
833 medium.Reject(e2); 854 medium.Reject(e2);
834 } 855 }
835 return default(T); 856 return default(T);
836 }; 857 };
837 else 858 else
838 errorHandler = err => { 859 errorHandler = err => {
839 medium.Reject(err); 860 medium.Reject(err);
840 return default(T); 861 return default(T);
841 }; 862 };
842 863
843 864
844 Action cancelHandler; 865 Action cancelHandler;
845 if (cancel != null) 866 if (cancel != null)
846 cancelHandler = () => { 867 cancelHandler = () => {
847 if (cancel != null) 868 if (cancel != null)
848 cancel(); 869 cancel();
849 medium.Cancel(); 870 medium.Cancel();
850 }; 871 };
851 else 872 else
852 cancelHandler = medium.Cancel; 873 cancelHandler = medium.Cancel;
853 874
854 AddHandler( 875 AddHandler(
855 resultHandler, 876 resultHandler,
856 errorHandler, 877 errorHandler,
857 cancelHandler, 878 cancelHandler,
858 null 879 null,
859 ); 880 true
860 881 );
861 return medium; 882
862 } 883 return medium;
884 }
885
863 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) { 886 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) {
864 return ChainNoResult(chained, error, null); 887 return ChainNoResult(chained, error, null);
865 } 888 }
889
866 IPromise IPromise.Chain(Func<IPromise> chained) { 890 IPromise IPromise.Chain(Func<IPromise> chained) {
867 return ChainNoResult(chained, null, null); 891 return ChainNoResult(chained, null, null);
868 } 892 }
869 893
870 894
871 void IPromise.Last(Action success, Action<Exception> error, Action cancel) { 895 void IPromise.On(Action success, Action<Exception> error, Action cancel) {
872 Last(x => success(), error, cancel); 896 On(x => success(), error, cancel);
873 } 897 }
874 898
875 void IPromise.Last(Action success, Action<Exception> error) { 899 void IPromise.On(Action success, Action<Exception> error) {
876 Last(x => success(), error, null); 900 On(x => success(), error, null);
877 } 901 }
878 902
879 void IPromise.Last(Action success) { 903 void IPromise.On(Action success) {
880 Last(x => success(), null, null); 904 On(x => success(), null, null);
881 } 905 }
882 906
883 IPromise IPromise.Error(Action<Exception> error) { 907 IPromise IPromise.Error(Action<Exception> error) {
884 return Error(error); 908 return Error(error);
885 } 909 }