Mercurial > pub > ImplabNet
view Implab/AbstractPromise.cs @ 167:96681e9d0cea ref20160224
sync
author | cin |
---|---|
date | Wed, 02 Mar 2016 00:20:48 +0300 |
parents | 97fbbf816844 |
children | 75103928da09 |
line wrap: on
line source
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(); } } }