Mercurial > pub > ImplabNet
comparison Implab/Promise`1.cs @ 248:5cb4826c2c2a v3
Added awaiters to promises
Added static methods to Promise Resolve, Reject, All.
Updated promise helpers
| author | cin | 
|---|---|
| date | Tue, 30 Jan 2018 01:37:17 +0300 | 
| parents | |
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 247:fb70574741a1 | 248:5cb4826c2c2a | 
|---|---|
| 1 using System; | |
| 2 using System.Diagnostics; | |
| 3 using System.Reflection; | |
| 4 using Implab.Parallels; | |
| 5 | |
| 6 namespace Implab { | |
| 7 public class Promise<T> : AbstractEvent<IResolvable<T>>, IPromise<T> { | |
| 8 | |
| 9 class ResolvableSignal : IResolvable<T> { | |
| 10 public Signal Signal { get; private set; } | |
| 11 public ResolvableSignal() { | |
| 12 Signal = new Signal(); | |
| 13 } | |
| 14 | |
| 15 | |
| 16 public void Reject(Exception error) { | |
| 17 Signal.Set(); | |
| 18 } | |
| 19 | |
| 20 public void Resolve(T result) { | |
| 21 Signal.Set(); | |
| 22 } | |
| 23 } | |
| 24 | |
| 25 class ResolvableWrapper : IResolvable<T> { | |
| 26 readonly IResolvable m_resolvable; | |
| 27 public ResolvableWrapper(IResolvable resolvable) { | |
| 28 m_resolvable = resolvable; | |
| 29 } | |
| 30 | |
| 31 public void Reject(Exception reason) { | |
| 32 m_resolvable.Reject(reason); | |
| 33 } | |
| 34 | |
| 35 public void Resolve(T value) { | |
| 36 m_resolvable.Resolve(); | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 PromiseState m_state; | |
| 41 | |
| 42 T m_result; | |
| 43 | |
| 44 Exception m_error; | |
| 45 | |
| 46 public bool IsRejected { | |
| 47 get { | |
| 48 return m_state == PromiseState.Rejected; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 public bool IsFulfilled { | |
| 53 get { | |
| 54 return m_state == PromiseState.Fulfilled; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 public Exception RejectReason { | |
| 59 get { | |
| 60 return m_error; | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 | |
| 65 internal void ResolvePromise(T result) { | |
| 66 if (BeginTransit()) { | |
| 67 m_result = result; | |
| 68 m_state = PromiseState.Fulfilled; | |
| 69 CompleteTransit(); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 internal void RejectPromise(Exception reason) { | |
| 74 if (BeginTransit()) { | |
| 75 m_error = reason; | |
| 76 m_state = PromiseState.Rejected; | |
| 77 CompleteTransit(); | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 | |
| 82 #region implemented abstract members of AbstractPromise | |
| 83 | |
| 84 protected override void SignalHandler(IResolvable<T> handler) { | |
| 85 switch (m_state) { | |
| 86 case PromiseState.Fulfilled: | |
| 87 handler.Resolve(m_result); | |
| 88 break; | |
| 89 case PromiseState.Rejected: | |
| 90 handler.Reject(RejectReason); | |
| 91 break; | |
| 92 default: | |
| 93 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state)); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 protected void WaitResult(int timeout) { | |
| 98 if (!(IsResolved || GetFulfillSignal().Wait(timeout))) | |
| 99 throw new TimeoutException(); | |
| 100 } | |
| 101 | |
| 102 protected Signal GetFulfillSignal() { | |
| 103 var next = new ResolvableSignal(); | |
| 104 Then(next); | |
| 105 return next.Signal; | |
| 106 } | |
| 107 | |
| 108 #endregion | |
| 109 | |
| 110 public Type ResultType { | |
| 111 get { | |
| 112 return typeof(void); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 | |
| 117 protected void Rethrow() { | |
| 118 if (m_error is OperationCanceledException) | |
| 119 throw new OperationCanceledException("Operation cancelled", m_error); | |
| 120 else | |
| 121 throw new TargetInvocationException(m_error); | |
| 122 } | |
| 123 | |
| 124 public void Then(IResolvable<T> next) { | |
| 125 AddHandler(next); | |
| 126 } | |
| 127 | |
| 128 public void Then(IResolvable next) { | |
| 129 AddHandler(new ResolvableWrapper(next)); | |
| 130 } | |
| 131 | |
| 132 public IPromise<T2> Cast<T2>() { | |
| 133 return (IPromise<T2>)this; | |
| 134 } | |
| 135 | |
| 136 void IPromise.Join() { | |
| 137 Join(); | |
| 138 } | |
| 139 | |
| 140 void IPromise.Join(int timeout) { | |
| 141 Join(timeout); | |
| 142 } | |
| 143 | |
| 144 public T Join() { | |
| 145 WaitResult(-1); | |
| 146 if (IsRejected) | |
| 147 Rethrow(); | |
| 148 return m_result; | |
| 149 } | |
| 150 | |
| 151 public T Join(int timeout) { | |
| 152 WaitResult(timeout); | |
| 153 if (IsRejected) | |
| 154 Rethrow(); | |
| 155 return m_result; | |
| 156 } | |
| 157 } | |
| 158 } | |
| 159 | 
