##// END OF EJS Templates
sync
sync

File last commit:

r156:97fbbf816844 v2
r167:96681e9d0cea ref20160224
Show More
AbstractPromise.cs
142 lines | 4.5 KiB | text/x-csharp | CSharpLexer
using System;
using Implab.Parallels;
namespace Implab {
public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
public struct HandlerDescriptor {
readonly Action m_handler;
readonly Action<Exception> m_error;
readonly Action<Exception> m_cancel;
readonly PromiseEventType m_mask;
public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
m_handler = success;
m_error = error;
m_cancel = cancel;
m_mask = PromiseEventType.Success;
}
public HandlerDescriptor(Action handler, PromiseEventType mask) {
m_handler = handler;
m_error = null;
m_cancel = null;
m_mask = mask;
}
public void SignalSuccess() {
if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) {
try {
m_handler();
} catch (Exception err) {
// avoid calling handler twice in case of error
if (m_error != null)
SignalError(err);
}
}
}
public void SignalError(Exception err) {
if (m_error != null) {
try {
m_error(err);
// Analysis disable once EmptyGeneralCatchClause
} catch {
}
} else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) {
try {
m_handler();
// Analysis disable once EmptyGeneralCatchClause
} catch {
}
}
}
public void SignalCancel(Exception reason) {
if (m_cancel != null) {
try {
m_cancel(reason);
} catch (Exception err) {
SignalError(err);
}
} else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) {
try {
m_handler();
// Analysis disable once EmptyGeneralCatchClause
} catch {
}
}
}
}
#region implemented abstract members of AbstractPromise
protected override void SignalHandler(HandlerDescriptor handler, int signal) {
switch (signal) {
case SUCCEEDED_STATE:
handler.SignalSuccess();
break;
case REJECTED_STATE:
handler.SignalError(Error);
break;
case CANCELLED_STATE:
handler.SignalCancel(CancellationReason);
break;
default:
throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
}
}
protected override Signal GetResolveSignal() {
var signal = new Signal();
On(signal.Set, PromiseEventType.All);
return signal;
}
#endregion
public Type PromiseType {
get {
return typeof(void);
}
}
public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
AddHandler(new HandlerDescriptor(success, error, cancel));
return this;
}
public IPromise On(Action success, Action<Exception> error) {
AddHandler(new HandlerDescriptor(success, error, null));
return this;
}
public IPromise On(Action success) {
AddHandler(new HandlerDescriptor(success, null, null));
return this;
}
public IPromise On(Action handler, PromiseEventType events) {
AddHandler(new HandlerDescriptor(handler,events));
return this;
}
public IPromise<T> Cast<T>() {
throw new InvalidCastException();
}
public void Join() {
WaitResult(-1);
}
public void Join(int timeout) {
WaitResult(timeout);
}
protected void SetResult() {
BeginSetResult();
EndSetResult();
}
}
}