##// END OF EJS Templates
Working on Unity xml configuration
Working on Unity xml configuration

File last commit:

r248:5cb4826c2c2a v3
r267:6b3e5c48131b v3
Show More
Promise`1.cs
159 lines | 3.9 KiB | text/x-csharp | CSharpLexer
using System;
using System.Diagnostics;
using System.Reflection;
using Implab.Parallels;
namespace Implab {
public class Promise<T> : AbstractEvent<IResolvable<T>>, IPromise<T> {
class ResolvableSignal : IResolvable<T> {
public Signal Signal { get; private set; }
public ResolvableSignal() {
Signal = new Signal();
}
public void Reject(Exception error) {
Signal.Set();
}
public void Resolve(T result) {
Signal.Set();
}
}
class ResolvableWrapper : IResolvable<T> {
readonly IResolvable m_resolvable;
public ResolvableWrapper(IResolvable resolvable) {
m_resolvable = resolvable;
}
public void Reject(Exception reason) {
m_resolvable.Reject(reason);
}
public void Resolve(T value) {
m_resolvable.Resolve();
}
}
PromiseState m_state;
T m_result;
Exception m_error;
public bool IsRejected {
get {
return m_state == PromiseState.Rejected;
}
}
public bool IsFulfilled {
get {
return m_state == PromiseState.Fulfilled;
}
}
public Exception RejectReason {
get {
return m_error;
}
}
internal void ResolvePromise(T result) {
if (BeginTransit()) {
m_result = result;
m_state = PromiseState.Fulfilled;
CompleteTransit();
}
}
internal void RejectPromise(Exception reason) {
if (BeginTransit()) {
m_error = reason;
m_state = PromiseState.Rejected;
CompleteTransit();
}
}
#region implemented abstract members of AbstractPromise
protected override void SignalHandler(IResolvable<T> handler) {
switch (m_state) {
case PromiseState.Fulfilled:
handler.Resolve(m_result);
break;
case PromiseState.Rejected:
handler.Reject(RejectReason);
break;
default:
throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state));
}
}
protected void WaitResult(int timeout) {
if (!(IsResolved || GetFulfillSignal().Wait(timeout)))
throw new TimeoutException();
}
protected Signal GetFulfillSignal() {
var next = new ResolvableSignal();
Then(next);
return next.Signal;
}
#endregion
public Type ResultType {
get {
return typeof(void);
}
}
protected void Rethrow() {
if (m_error is OperationCanceledException)
throw new OperationCanceledException("Operation cancelled", m_error);
else
throw new TargetInvocationException(m_error);
}
public void Then(IResolvable<T> next) {
AddHandler(next);
}
public void Then(IResolvable next) {
AddHandler(new ResolvableWrapper(next));
}
public IPromise<T2> Cast<T2>() {
return (IPromise<T2>)this;
}
void IPromise.Join() {
Join();
}
void IPromise.Join(int timeout) {
Join(timeout);
}
public T Join() {
WaitResult(-1);
if (IsRejected)
Rethrow();
return m_result;
}
public T Join(int timeout) {
WaitResult(timeout);
if (IsRejected)
Rethrow();
return m_result;
}
}
}