Mercurial > pub > ImplabNet
diff Implab/AbstractPromiseT.cs @ 144:8c0b95069066 v2
DRAFT: refactoring
author | cin |
---|---|
date | Fri, 06 Mar 2015 15:45:26 +0300 |
parents | |
children | 706fccb85524 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/AbstractPromiseT.cs Fri Mar 06 15:45:26 2015 +0300 @@ -0,0 +1,185 @@ +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; + } + + 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_mask = mask; + } + + public void SignalSuccess(T result) { + if (m_success != null) { + try { + m_success(result); + } catch(Exception err) { + SignalError(err); + } + } else if (m_mask & PromiseEventType.Success && 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 && 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 && m_handler != null) { + try { + m_handler(); + // Analysis disable once EmptyGeneralCatchClause + } catch { + } + } + } + } + + + + public Type PromiseType { + get { + return typeof(T); + } + } + + public new T Join() { + WaitResult(-1); + return m_result; + } + public new T Join(int timeout) { + WaitResult(timeout); + return m_result; + } + + 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; + } + + 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 SignalSuccess(HandlerDescriptor handler) { + handler.SignalSuccess(m_result); + } + + protected override void SignalError(HandlerDescriptor handler, Exception error) { + handler.SignalError(error); + } + + protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) { + handler.SignalCancel(reason); + } + + #endregion + + T m_result; + + protected void SetResult(T value) { + if (BeginSetResult()) { + m_result = value; + EndSetResult(); + } + } + } +} +