| 
144
 | 
     1 using System;
 | 
| 
 | 
     2 using Implab.Parallels;
 | 
| 
 | 
     3 
 | 
| 
 | 
     4 namespace Implab {
 | 
| 
 | 
     5     public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
 | 
| 
 | 
     6         public struct HandlerDescriptor {
 | 
| 
 | 
     7             readonly Action m_handler;
 | 
| 
 | 
     8             readonly Action<T> m_success;
 | 
| 
 | 
     9             readonly Action<Exception> m_error;
 | 
| 
 | 
    10             readonly Action<Exception> m_cancel;
 | 
| 
 | 
    11             readonly PromiseEventType m_mask;
 | 
| 
 | 
    12 
 | 
| 
 | 
    13             public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
 | 
| 
 | 
    14                 m_success = success;
 | 
| 
 | 
    15                 m_error = error;
 | 
| 
 | 
    16                 m_cancel = cancel;
 | 
| 
145
 | 
    17 
 | 
| 
 | 
    18                 m_handler = null;
 | 
| 
 | 
    19                 m_mask = 0;
 | 
| 
144
 | 
    20             }
 | 
| 
 | 
    21 
 | 
| 
 | 
    22             public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
 | 
| 
 | 
    23                 m_handler = success;
 | 
| 
145
 | 
    24                 m_success = null;
 | 
| 
144
 | 
    25                 m_error = error;
 | 
| 
 | 
    26                 m_cancel = cancel;
 | 
| 
 | 
    27                 m_mask = PromiseEventType.Success;
 | 
| 
 | 
    28             }
 | 
| 
 | 
    29 
 | 
| 
 | 
    30             public HandlerDescriptor(Action handler, PromiseEventType mask) {
 | 
| 
 | 
    31                 m_handler = handler;
 | 
| 
 | 
    32                 m_mask = mask;
 | 
| 
145
 | 
    33                 m_success = null;
 | 
| 
 | 
    34                 m_error = null;
 | 
| 
 | 
    35                 m_cancel = null;
 | 
| 
144
 | 
    36             }
 | 
| 
 | 
    37 
 | 
| 
 | 
    38             public void SignalSuccess(T result) {
 | 
| 
 | 
    39                 if (m_success != null) {
 | 
| 
 | 
    40                     try {
 | 
| 
 | 
    41                         m_success(result);
 | 
| 
 | 
    42                     } catch(Exception err) {
 | 
| 
 | 
    43                         SignalError(err);
 | 
| 
 | 
    44                     }
 | 
| 
145
 | 
    45                 } else if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
 | 
| 
144
 | 
    46                     try {
 | 
| 
 | 
    47                         m_handler();
 | 
| 
 | 
    48                     } catch(Exception err) {
 | 
| 
 | 
    49                         // avoid calling handler twice in case of error
 | 
| 
 | 
    50                         if (m_error != null)
 | 
| 
 | 
    51                             SignalError(err);
 | 
| 
 | 
    52                     }
 | 
| 
 | 
    53                 }
 | 
| 
 | 
    54             }
 | 
| 
 | 
    55 
 | 
| 
 | 
    56             public void SignalError(Exception err) {
 | 
| 
 | 
    57                 if (m_error != null) {
 | 
| 
 | 
    58                     try {
 | 
| 
 | 
    59                         m_error(err);
 | 
| 
 | 
    60                         // Analysis disable once EmptyGeneralCatchClause
 | 
| 
 | 
    61                     } catch {
 | 
| 
 | 
    62                     }
 | 
| 
145
 | 
    63                 } else if ((m_mask & PromiseEventType.Error) != 0 && m_handler != null) {
 | 
| 
144
 | 
    64                     try {
 | 
| 
 | 
    65                         m_handler();
 | 
| 
 | 
    66                         // Analysis disable once EmptyGeneralCatchClause
 | 
| 
 | 
    67                     } catch {
 | 
| 
 | 
    68                     }
 | 
| 
 | 
    69                 }
 | 
| 
 | 
    70             }
 | 
| 
 | 
    71 
 | 
| 
 | 
    72             public void SignalCancel(Exception reason) {
 | 
| 
 | 
    73                 if (m_cancel != null) {
 | 
| 
 | 
    74                     try {
 | 
| 
 | 
    75                         m_cancel(reason);
 | 
| 
 | 
    76                     } catch (Exception err) {
 | 
| 
 | 
    77                         SignalError(err);
 | 
| 
 | 
    78                     }
 | 
| 
145
 | 
    79                 } else if ((m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
 | 
| 
144
 | 
    80                     try {
 | 
| 
 | 
    81                         m_handler();
 | 
| 
 | 
    82                         // Analysis disable once EmptyGeneralCatchClause
 | 
| 
 | 
    83                     } catch {
 | 
| 
 | 
    84                     }
 | 
| 
 | 
    85                 }
 | 
| 
 | 
    86             }
 | 
| 
 | 
    87         }
 | 
| 
 | 
    88 
 | 
| 
 | 
    89         public Type PromiseType {
 | 
| 
 | 
    90             get {
 | 
| 
 | 
    91                 return typeof(T);
 | 
| 
 | 
    92             }
 | 
| 
 | 
    93         }
 | 
| 
 | 
    94 
 | 
| 
145
 | 
    95         public T Join() {
 | 
| 
144
 | 
    96             WaitResult(-1);
 | 
| 
 | 
    97             return m_result;
 | 
| 
 | 
    98         }
 | 
| 
145
 | 
    99         public T Join(int timeout) {
 | 
| 
144
 | 
   100             WaitResult(timeout);
 | 
| 
 | 
   101             return m_result;
 | 
| 
 | 
   102         }
 | 
| 
 | 
   103 
 | 
| 
145
 | 
   104         void IPromise.Join() {
 | 
| 
 | 
   105             WaitResult(-1);
 | 
| 
 | 
   106         }
 | 
| 
 | 
   107         void IPromise.Join(int timeout) {
 | 
| 
 | 
   108             WaitResult(timeout);
 | 
| 
 | 
   109         }
 | 
| 
 | 
   110 
 | 
| 
144
 | 
   111         public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
 | 
| 
 | 
   112             AddHandler(new HandlerDescriptor(success, error, cancel));
 | 
| 
 | 
   113             return this;
 | 
| 
 | 
   114         }
 | 
| 
 | 
   115 
 | 
| 
 | 
   116         public IPromise<T> On(Action<T> success, Action<Exception> error) {
 | 
| 
 | 
   117             AddHandler(new HandlerDescriptor(success, error, null));
 | 
| 
 | 
   118             return this;
 | 
| 
 | 
   119         }
 | 
| 
 | 
   120 
 | 
| 
 | 
   121         public IPromise<T> On(Action<T> success) {
 | 
| 
 | 
   122             AddHandler(new HandlerDescriptor(success, null, null));
 | 
| 
 | 
   123             return this;
 | 
| 
 | 
   124         }
 | 
| 
 | 
   125 
 | 
| 
 | 
   126         public IPromise<T> On(Action handler, PromiseEventType events) {
 | 
| 
 | 
   127             AddHandler(new HandlerDescriptor(handler, events));
 | 
| 
 | 
   128             return this;
 | 
| 
 | 
   129         }
 | 
| 
 | 
   130 
 | 
| 
 | 
   131         public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
 | 
| 
 | 
   132             AddHandler(new HandlerDescriptor(success, error, cancel));
 | 
| 
 | 
   133             return this;
 | 
| 
 | 
   134         }
 | 
| 
 | 
   135 
 | 
| 
 | 
   136         public IPromise<T> On(Action success, Action<Exception> error) {
 | 
| 
 | 
   137             AddHandler(new HandlerDescriptor(success, error, null));
 | 
| 
 | 
   138             return this;
 | 
| 
 | 
   139         }
 | 
| 
 | 
   140 
 | 
| 
 | 
   141         public IPromise<T> On(Action success) {
 | 
| 
 | 
   142             AddHandler(new HandlerDescriptor(success, null, null));
 | 
| 
 | 
   143             return this;
 | 
| 
 | 
   144         }
 | 
| 
 | 
   145 
 | 
| 
 | 
   146         IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
 | 
| 
 | 
   147             AddHandler(new HandlerDescriptor(success, error, cancel));
 | 
| 
 | 
   148             return this;
 | 
| 
 | 
   149         }
 | 
| 
 | 
   150 
 | 
| 
 | 
   151         IPromise IPromise.On(Action success, Action<Exception> error) {
 | 
| 
 | 
   152             AddHandler(new HandlerDescriptor(success, error, null));
 | 
| 
 | 
   153             return this;
 | 
| 
 | 
   154         }
 | 
| 
 | 
   155 
 | 
| 
 | 
   156         IPromise IPromise.On(Action success) {
 | 
| 
 | 
   157             AddHandler(new HandlerDescriptor(success, null, null));
 | 
| 
 | 
   158             return this;
 | 
| 
 | 
   159         }
 | 
| 
 | 
   160 
 | 
| 
145
 | 
   161         IPromise IPromise.On(Action handler, PromiseEventType events) {
 | 
| 
 | 
   162             AddHandler(new HandlerDescriptor(handler, events));
 | 
| 
 | 
   163             return this;
 | 
| 
 | 
   164         }
 | 
| 
 | 
   165 
 | 
| 
144
 | 
   166         public IPromise<T2> Cast<T2>() {
 | 
| 
 | 
   167             return (IPromise<T2>)this;
 | 
| 
 | 
   168         }
 | 
| 
 | 
   169 
 | 
| 
 | 
   170         #region implemented abstract members of AbstractPromise
 | 
| 
 | 
   171 
 | 
| 
 | 
   172         protected override Signal GetResolveSignal() {
 | 
| 
 | 
   173             var signal = new Signal();
 | 
| 
 | 
   174             AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
 | 
| 
 | 
   175             return signal;
 | 
| 
 | 
   176         }
 | 
| 
 | 
   177 
 | 
| 
 | 
   178         protected override void SignalSuccess(HandlerDescriptor handler) {
 | 
| 
 | 
   179             handler.SignalSuccess(m_result);
 | 
| 
 | 
   180         }
 | 
| 
 | 
   181 
 | 
| 
 | 
   182         protected override void SignalError(HandlerDescriptor handler, Exception error) {
 | 
| 
 | 
   183             handler.SignalError(error);
 | 
| 
 | 
   184         }
 | 
| 
 | 
   185 
 | 
| 
 | 
   186         protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) {
 | 
| 
 | 
   187             handler.SignalCancel(reason);
 | 
| 
 | 
   188         }
 | 
| 
 | 
   189 
 | 
| 
 | 
   190         #endregion
 | 
| 
 | 
   191 
 | 
| 
 | 
   192         T m_result;
 | 
| 
 | 
   193 
 | 
| 
 | 
   194         protected void SetResult(T value) {
 | 
| 
 | 
   195             if (BeginSetResult()) {
 | 
| 
 | 
   196                 m_result = value;
 | 
| 
 | 
   197                 EndSetResult();
 | 
| 
 | 
   198             }
 | 
| 
 | 
   199         }
 | 
| 
 | 
   200     }
 | 
| 
 | 
   201 }
 | 
| 
 | 
   202 
 |