AbstractPromise.cs
142 lines
| 4.5 KiB
| text/x-csharp
|
CSharpLexer
/ Implab / AbstractPromise.cs
cin
|
r119 | using System; | ||
using Implab.Parallels; | ||||
namespace Implab { | ||||
cin
|
r144 | 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; | ||||
cin
|
r119 | |||
cin
|
r144 | public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel) { | ||
m_handler = success; | ||||
m_error = error; | ||||
m_cancel = cancel; | ||||
m_mask = PromiseEventType.Success; | ||||
} | ||||
cin
|
r125 | |||
cin
|
r144 | public HandlerDescriptor(Action handler, PromiseEventType mask) { | ||
m_handler = handler; | ||||
cin
|
r145 | m_error = null; | ||
m_cancel = null; | ||||
cin
|
r144 | m_mask = mask; | ||
} | ||||
cin
|
r119 | |||
cin
|
r144 | public void SignalSuccess() { | ||
cin
|
r145 | if ((m_mask & PromiseEventType.Success) != 0 && m_handler != null) { | ||
cin
|
r144 | try { | ||
m_handler(); | ||||
} catch (Exception err) { | ||||
// avoid calling handler twice in case of error | ||||
if (m_error != null) | ||||
SignalError(err); | ||||
} | ||||
} | ||||
} | ||||
cin
|
r119 | |||
cin
|
r144 | public void SignalError(Exception err) { | ||
if (m_error != null) { | ||||
try { | ||||
m_error(err); | ||||
// Analysis disable once EmptyGeneralCatchClause | ||||
} catch { | ||||
} | ||||
cin
|
r145 | } else if ((m_mask & PromiseEventType.Error ) != 0 && m_handler != null) { | ||
cin
|
r144 | try { | ||
m_handler(); | ||||
// Analysis disable once EmptyGeneralCatchClause | ||||
} catch { | ||||
} | ||||
} | ||||
cin
|
r119 | } | ||
cin
|
r144 | public void SignalCancel(Exception reason) { | ||
if (m_cancel != null) { | ||||
try { | ||||
m_cancel(reason); | ||||
} catch (Exception err) { | ||||
SignalError(err); | ||||
} | ||||
cin
|
r145 | } else if ( (m_mask & PromiseEventType.Cancelled) != 0 && m_handler != null) { | ||
cin
|
r144 | try { | ||
m_handler(); | ||||
// Analysis disable once EmptyGeneralCatchClause | ||||
} catch { | ||||
} | ||||
} | ||||
cin
|
r119 | } | ||
} | ||||
cin
|
r144 | #region implemented abstract members of AbstractPromise | ||
cin
|
r119 | |||
cin
|
r156 | 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)); | ||||
} | ||||
cin
|
r119 | } | ||
cin
|
r144 | protected override Signal GetResolveSignal() { | ||
var signal = new Signal(); | ||||
On(signal.Set, PromiseEventType.All); | ||||
cin
|
r145 | return signal; | ||
cin
|
r119 | } | ||
#endregion | ||||
cin
|
r144 | public Type PromiseType { | ||
get { | ||||
return typeof(void); | ||||
cin
|
r119 | } | ||
} | ||||
cin
|
r144 | 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; | ||||
cin
|
r119 | } | ||
cin
|
r144 | public IPromise On(Action success) { | ||
AddHandler(new HandlerDescriptor(success, null, null)); | ||||
return this; | ||||
} | ||||
cin
|
r119 | |||
cin
|
r144 | public IPromise On(Action handler, PromiseEventType events) { | ||
AddHandler(new HandlerDescriptor(handler,events)); | ||||
return this; | ||||
} | ||||
cin
|
r119 | |||
cin
|
r144 | public IPromise<T> Cast<T>() { | ||
throw new InvalidCastException(); | ||||
cin
|
r119 | } | ||
public void Join() { | ||||
WaitResult(-1); | ||||
} | ||||
cin
|
r144 | public void Join(int timeout) { | ||
WaitResult(timeout); | ||||
cin
|
r119 | } | ||
cin
|
r144 | protected void SetResult() { | ||
cin
|
r186 | if(BeginSetResult()) | ||
EndSetResult(); | ||||
cin
|
r138 | } | ||
cin
|
r119 | } | ||
} | ||||