##// END OF EJS Templates
minor changes
minor changes

File last commit:

r156:97fbbf816844 v2
r195:ea485487a424 v2
Show More
AbstractPromiseT.cs
206 lines | 6.7 KiB | text/x-csharp | CSharpLexer
using System;
using Implab.Parallels;
namespace Implab {
public abstract class AbstractPromise<T> : AbstractEvent<AbstractPromise<T>.HandlerDescriptor>, IPromise<T> {
public struct HandlerDescriptor {
readonly Action m_handler;
readonly Action<T> m_success;
readonly Action<Exception> m_error;
readonly Action<Exception> m_cancel;
readonly PromiseEventType m_mask;
public HandlerDescriptor(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
m_success = success;
m_error = error;
m_cancel = cancel;
m_handler = null;
m_mask = 0;
}
public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) {
m_handler = success;
m_success = null;
m_error = error;
m_cancel = cancel;
m_mask = PromiseEventType.Success;
}
public HandlerDescriptor(Action handler, PromiseEventType mask) {
m_handler = handler;
m_mask = mask;
m_success = null;
m_error = null;
m_cancel = null;
}
public void SignalSuccess(T result) {
if (m_success != null) {
try {
m_success(result);
} catch(Exception err) {
SignalError(err);
}
} else 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 {
}
}
}
}
public Type PromiseType {
get {
return typeof(T);
}
}
public T Join() {
WaitResult(-1);
return m_result;
}
public T Join(int timeout) {
WaitResult(timeout);
return m_result;
}
void IPromise.Join() {
WaitResult(-1);
}
void IPromise.Join(int timeout) {
WaitResult(timeout);
}
public IPromise<T> On(Action<T> success, Action<Exception> error, Action<Exception> cancel) {
AddHandler(new HandlerDescriptor(success, error, cancel));
return this;
}
public IPromise<T> On(Action<T> success, Action<Exception> error) {
AddHandler(new HandlerDescriptor(success, error, null));
return this;
}
public IPromise<T> On(Action<T> success) {
AddHandler(new HandlerDescriptor(success, null, null));
return this;
}
public IPromise<T> On(Action handler, PromiseEventType events) {
AddHandler(new HandlerDescriptor(handler, events));
return this;
}
public IPromise<T> On(Action success, Action<Exception> error, Action<Exception> cancel) {
AddHandler(new HandlerDescriptor(success, error, cancel));
return this;
}
public IPromise<T> On(Action success, Action<Exception> error) {
AddHandler(new HandlerDescriptor(success, error, null));
return this;
}
public IPromise<T> On(Action success) {
AddHandler(new HandlerDescriptor(success, null, null));
return this;
}
IPromise IPromise.On(Action success, Action<Exception> error, Action<Exception> cancel) {
AddHandler(new HandlerDescriptor(success, error, cancel));
return this;
}
IPromise IPromise.On(Action success, Action<Exception> error) {
AddHandler(new HandlerDescriptor(success, error, null));
return this;
}
IPromise IPromise.On(Action success) {
AddHandler(new HandlerDescriptor(success, null, null));
return this;
}
IPromise IPromise.On(Action handler, PromiseEventType events) {
AddHandler(new HandlerDescriptor(handler, events));
return this;
}
public IPromise<T2> Cast<T2>() {
return (IPromise<T2>)this;
}
#region implemented abstract members of AbstractPromise
protected override Signal GetResolveSignal() {
var signal = new Signal();
AddHandler(new HandlerDescriptor(signal.Set, PromiseEventType.All));
return signal;
}
protected override void SignalHandler(HandlerDescriptor handler, int signal) {
switch (signal) {
case SUCCEEDED_STATE:
handler.SignalSuccess(m_result);
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));
}
}
#endregion
T m_result;
protected void SetResult(T value) {
if (BeginSetResult()) {
m_result = value;
EndSetResult();
}
}
}
}