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