Mercurial > pub > ImplabNet
diff Implab/AbstractPromise.cs @ 244:eee3e49dd1ff v3
working on promises
author | cin |
---|---|
date | Thu, 25 Jan 2018 19:09:16 +0300 |
parents | b1e0ffdf3451 |
children | fb70574741a1 |
line wrap: on
line diff
--- a/Implab/AbstractPromise.cs Wed Jan 24 19:24:10 2018 +0300 +++ b/Implab/AbstractPromise.cs Thu Jan 25 19:09:16 2018 +0300 @@ -4,36 +4,21 @@ using Implab.Parallels; namespace Implab { - public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise { - public class HandlerDescriptor { - readonly Action m_resolve; - readonly Action<Exception> m_reject; + public class AbstractPromise : AbstractEvent<IResolvable>, IPromise { - readonly IDeferred m_deferred; - public HandlerDescriptor(Action success, Action<Exception> error) { - m_resolve = success; - m_reject = error; + class ResolvableSignal : IResolvable { + public Signal Signal { get; private set; } + public ResolvableSignal() { + Signal = new Signal(); } - public void SignalSuccess() { - try { - if (m_resolve != null) - m_resolve(); - m_deferred.Resolve(); - } catch (Exception ex) { - m_deferred.Reject(ex); - } + + public void Reject(Exception error) { + Signal.Set(); } - public void SignalError(Exception err) { - if (m_reject != null) { - try { - m_reject(err); - m_deferred.Resolve(); - } catch (Exception ex) { - m_deferred.Reject(ex); - } - } + public void Resolve() { + Signal.Set(); } } @@ -47,9 +32,9 @@ } } - public bool IsResolved { + public bool IsFulfilled { get { - return m_state == PromiseState.Resolved; + return m_state == PromiseState.Fulfilled; } } @@ -60,15 +45,29 @@ } + internal void Resolve() { + if (BeginTransit()) + CompleteResolve(); + } + + internal void Reject(Exception reason) { + if (BeginTransit()) { + m_error = reason; + m_state = PromiseState.Rejected; + CompleteTransit(); + } + } + + #region implemented abstract members of AbstractPromise - protected override void SignalHandler(HandlerDescriptor handler) { + protected override void SignalHandler(IResolvable handler) { switch (m_state) { - case PromiseState.Resolved: - handler.SignalSuccess(); + case PromiseState.Fulfilled: + handler.Resolve(); break; case PromiseState.Rejected: - handler.SignalError(RejectReason); + handler.Reject(RejectReason); break; default: throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state)); @@ -76,15 +75,15 @@ } protected override Signal GetFulfillSignal() { - var signal = new Signal(); - On(signal.Set, e => signal.Set()); - return signal; + var next = new ResolvableSignal(); + Then(next); + return next.Signal; } #endregion protected void CompleteResolve() { - m_state = PromiseState.Resolved; + m_state = PromiseState.Fulfilled; CompleteTransit(); } @@ -94,27 +93,6 @@ } } - /// <summary> - /// Выполняет обещание, сообщая об ошибке - /// </summary> - /// <remarks> - /// Поскольку обещание должно работать в многопточной среде, при его выполнении сразу несколько потоков - /// могу вернуть ошибку, при этом только первая будет использована в качестве результата, остальные - /// будут проигнорированы. - /// </remarks> - /// <param name="error">Исключение возникшее при выполнении операции</param> - /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> - protected void SetError(Exception error) { - if (BeginTransit()) { - m_error = error; - m_state = PromiseState.Rejected; - CompleteTransit(); - } else { - WaitTransition(); - if (m_state == PromiseState.Resolved) - throw new InvalidOperationException("The promise is already resolved"); - } - } protected void Rethrow() { Debug.Assert(m_error != null); @@ -124,8 +102,8 @@ throw new TargetInvocationException(m_error); } - public void On(Action success, Action<Exception> error) { - AddHandler(new HandlerDescriptor(success, error)); + public void Then(IResolvable next) { + AddHandler(next); } public IPromise<T> Cast<T>() {