AbstractPromise.cs
124 lines
| 3.0 KiB
| text/x-csharp
|
CSharpLexer
/ Implab / AbstractPromise.cs
|
|
r119 | using System; | ||
|
|
r243 | using System.Diagnostics; | ||
| using System.Reflection; | ||||
|
|
r119 | using Implab.Parallels; | ||
| namespace Implab { | ||||
|
|
r244 | public class AbstractPromise : AbstractEvent<IResolvable>, IPromise { | ||
|
|
r243 | |||
|
|
r244 | class ResolvableSignal : IResolvable { | ||
| public Signal Signal { get; private set; } | ||||
| public ResolvableSignal() { | ||||
| Signal = new Signal(); | ||||
|
|
r144 | } | ||
|
|
r119 | |||
|
|
r244 | |||
| public void Reject(Exception error) { | ||||
| Signal.Set(); | ||||
|
|
r144 | } | ||
|
|
r119 | |||
|
|
r244 | public void Resolve() { | ||
| Signal.Set(); | ||||
|
|
r119 | } | ||
| } | ||||
|
|
r243 | PromiseState m_state; | ||
| Exception m_error; | ||||
| public bool IsRejected { | ||||
| get { | ||||
| return m_state == PromiseState.Rejected; | ||||
| } | ||||
| } | ||||
|
|
r244 | public bool IsFulfilled { | ||
|
|
r243 | get { | ||
|
|
r244 | return m_state == PromiseState.Fulfilled; | ||
|
|
r243 | } | ||
| } | ||||
| public Exception RejectReason { | ||||
| get { | ||||
| return m_error; | ||||
| } | ||||
| } | ||||
|
|
r119 | |||
|
|
r244 | internal void Resolve() { | ||
| if (BeginTransit()) | ||||
| CompleteResolve(); | ||||
| } | ||||
| internal void Reject(Exception reason) { | ||||
| if (BeginTransit()) { | ||||
| m_error = reason; | ||||
| m_state = PromiseState.Rejected; | ||||
| CompleteTransit(); | ||||
| } | ||||
| } | ||||
|
|
r144 | #region implemented abstract members of AbstractPromise | ||
|
|
r119 | |||
|
|
r244 | protected override void SignalHandler(IResolvable handler) { | ||
|
|
r243 | switch (m_state) { | ||
|
|
r244 | case PromiseState.Fulfilled: | ||
| handler.Resolve(); | ||||
|
|
r156 | break; | ||
|
|
r243 | case PromiseState.Rejected: | ||
|
|
r244 | handler.Reject(RejectReason); | ||
|
|
r156 | break; | ||
| default: | ||||
|
|
r243 | throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state)); | ||
|
|
r156 | } | ||
|
|
r119 | } | ||
|
|
r242 | protected override Signal GetFulfillSignal() { | ||
|
|
r244 | var next = new ResolvableSignal(); | ||
| Then(next); | ||||
| return next.Signal; | ||||
|
|
r119 | } | ||
| #endregion | ||||
|
|
r243 | protected void CompleteResolve() { | ||
|
|
r244 | m_state = PromiseState.Fulfilled; | ||
|
|
r243 | CompleteTransit(); | ||
| } | ||||
|
|
r242 | public Type ResultType { | ||
|
|
r144 | get { | ||
| return typeof(void); | ||||
|
|
r119 | } | ||
| } | ||||
|
|
r243 | |||
| protected void Rethrow() { | ||||
| Debug.Assert(m_error != null); | ||||
| if (m_error is OperationCanceledException) | ||||
| throw new OperationCanceledException("Operation cancelled", m_error); | ||||
| else | ||||
| throw new TargetInvocationException(m_error); | ||||
| } | ||||
|
|
r244 | public void Then(IResolvable next) { | ||
| AddHandler(next); | ||||
|
|
r144 | } | ||
|
|
r119 | |||
|
|
r144 | public IPromise<T> Cast<T>() { | ||
| throw new InvalidCastException(); | ||||
|
|
r119 | } | ||
| public void Join() { | ||||
| WaitResult(-1); | ||||
|
|
r243 | if (IsRejected) | ||
| Rethrow(); | ||||
|
|
r119 | } | ||
|
|
r144 | public void Join(int timeout) { | ||
| WaitResult(timeout); | ||||
|
|
r119 | } | ||
| } | ||||
| } | ||||
