Mercurial > pub > ImplabNet
diff Implab/PromiseT.cs @ 144:8c0b95069066 v2
DRAFT: refactoring
author | cin |
---|---|
date | Fri, 06 Mar 2015 15:45:26 +0300 |
parents | f75cfa58e3d4 |
children | e03ccec4a08d |
line wrap: on
line diff
--- a/Implab/PromiseT.cs Wed Mar 04 18:05:39 2015 +0300 +++ b/Implab/PromiseT.cs Fri Mar 06 15:45:26 2015 +0300 @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using Implab.Parallels; namespace Implab { @@ -37,538 +38,26 @@ /// только инициатор обещания иначе могут возникнуть противоречия. /// </para> /// </remarks> - public class Promise<T> : AbstractPromise<IDeferred<T>>, IPromise<T>, IDeferred<T> { - - class StubDeferred : IDeferred, IDeferred<T> { - public static readonly StubDeferred instance = new StubDeferred(); - - StubDeferred() { - } - - #region IDeferred implementation - - public void Resolve(T value) { - } - - public void Resolve() { - } - - public void Reject(Exception error) { - } - - #endregion - - #region ICancellable implementation - - public void Cancel() { - } - - public void Cancel(Exception reason) { - } - - #endregion - - - } - - class RemapDescriptor<T2> : IDeferred<T> { - readonly Func<T,T2> m_remap; - readonly Func<Exception, T2> m_failed; - readonly Func<Exception, T2> m_cancel; - readonly IDeferred<T2> m_deferred; - - public RemapDescriptor(Func<T,T2> remap, Func<Exception,T2> failed, Func<Exception, T2> cancel, IDeferred<T2> deferred ) { - Debug.Assert(deferred != null); - m_remap = remap; - m_failed = failed; - m_cancel = cancel; - m_deferred = deferred; - } + public class Promise<T> : AbstractPromise<T>, IDeferred<T> { - - - #region IDeferred implementation - - public void Resolve(T value) { - if (m_remap != null) { - try { - m_deferred.Resolve(m_remap(value)); - } catch (Exception ex) { - Reject(ex); - } - } - } - - public void Reject(Exception error) { - if (m_failed != null) { - try { - m_deferred.Resolve(m_failed(error)); - } catch (Exception ex) { - m_deferred.Reject(ex); - } - } else { - m_deferred.Reject(error); - } - } - - - #endregion - - #region ICancellable implementation - - public void Cancel(Exception reason) { - if (m_cancel != null) { - try { - m_deferred.Resolve(m_cancel(reason)); - } catch (Exception ex) { - Reject(ex); - } - } else { - m_deferred.Cancel(reason); - } - } - - public void Cancel() { - Cancel(null); - } - #endregion + public static IPromise<T> FromResult(T value) { + var p = new Promise<T>(); + p.Resolve(value); + return p; } - class ListenerDescriptor : IDeferred<T> { - readonly Action m_handler; - readonly PromiseEventType m_events; - - public ListenerDescriptor(Action handler, PromiseEventType events) { - Debug.Assert(handler != null); - - m_handler = handler; - m_events = events; - } - - #region IDeferred implementation - - public void Resolve(T value) { - if (m_events.HasFlag(PromiseEventType.Success)) { - try { - m_handler(); - // Analysis disable once EmptyGeneralCatchClause - } catch { - } - } - } - - public void Reject(Exception error) { - if (m_events.HasFlag(PromiseEventType.Error)){ - try { - m_handler(); - // Analysis disable once EmptyGeneralCatchClause - } catch { - } - } - } - - #endregion - - #region ICancellable implementation - - public void Cancel() { - Cancel(null); - } - - public void Cancel(Exception reason) { - if (m_events.HasFlag(PromiseEventType.Cancelled)){ - try { - m_handler(); - // Analysis disable once EmptyGeneralCatchClause - } catch { - } - } - } - - #endregion + public static IPromise<T> FromException(Exception error) { + var p = new Promise<T>(); + p.Reject(error); + return p; } - class ValueEventDescriptor : IDeferred<T> { - readonly Action<T> m_success; - readonly Action<Exception> m_failed; - readonly Action<Exception> m_cancelled; - readonly IDeferred<T> m_deferred; - - public ValueEventDescriptor(Action<T> success, Action<Exception> failed, Action<Exception> cancelled, IDeferred<T> deferred) { - Debug.Assert(deferred != null); - - m_success = success; - m_failed = failed; - m_cancelled = cancelled; - m_deferred = deferred; - } - - #region IDeferred implementation - - public void Resolve(T value) { - if (m_success != null) { - try { - m_success(value); - m_deferred.Resolve(value); - } catch (Exception ex) { - Reject(ex); - } - } - } - - public void Reject(Exception error) { - if (m_failed != null) { - try { - m_failed(error); - m_deferred.Resolve(default(T)); - } catch(Exception ex) { - m_deferred.Reject(ex); - } - } else { - m_deferred.Reject(error); - } - } - - #endregion - - #region ICancellable implementation - - public void Cancel(Exception reason) { - if (m_cancelled != null) { - try { - m_cancelled(reason); - m_deferred.Resolve(default(T)); - } catch (Exception ex) { - Reject(ex); - } - } else { - m_deferred.Cancel(reason); - } - } - - public void Cancel() { - Cancel(null); - } - - #endregion - } - - public class EventDescriptor : IDeferred<T> { - readonly Action m_success; - readonly Action<Exception> m_failed; - readonly Action<Exception> m_cancelled; - readonly IDeferred m_deferred; - - public EventDescriptor(Action success, Action<Exception> failed, Action<Exception> cancelled, IDeferred deferred) { - Debug.Assert(deferred != null); - - m_success = success; - m_failed = failed; - m_cancelled = cancelled; - m_deferred = deferred; - } - - #region IDeferred implementation - - public void Resolve(T value) { - if (m_success != null) { - try { - m_success(); - m_deferred.Resolve(); - } catch (Exception ex) { - Reject(ex); - } - } - } - - public void Reject(Exception error) { - if (m_failed != null) { - try { - m_failed(error); - m_deferred.Resolve(); - } catch (Exception ex) { - m_deferred.Reject(ex); - } - } else { - m_deferred.Reject(error); - } - } - - #endregion - - #region ICancellable implementation - - public void Cancel(Exception reason) { - if (m_cancelled != null) { - try { - m_cancelled(reason); - m_deferred.Resolve(); - } catch (Exception ex) { - Reject(ex); - } - } else { - m_deferred.Cancel(reason); - } - } - - public void Cancel() { - Cancel(null); - } - - #endregion - } - - T m_result; - public virtual void Resolve(T value) { - if (BeginSetResult()) { - m_result = value; - EndSetResult(); - } + SetResult(value); } public void Reject(Exception error) { SetError(error); } - - 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 ValueEventDescriptor(success, error, cancel, StubDeferred.instance)); - return this; - } - - public IPromise<T> On(Action<T> success, Action<Exception> error) { - AddHandler(new ValueEventDescriptor(success, error, null, StubDeferred.instance)); - return this; - } - - public IPromise<T> On(Action<T> success) { - AddHandler(new ValueEventDescriptor(success, null, null, StubDeferred.instance)); - return this; - } - - public IPromise<T> On(Action handler, PromiseEventType events) { - Listen(events, handler); - return this; - } - - public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error, Func<Exception, T2> cancel) { - var promise = new Promise<T2>(); - if (mapper != null) - promise.On((Action)null, null, Cancel); - AddHandler(new RemapDescriptor<T2>(mapper, error, cancel, promise)); - return promise; - } - - public IPromise<T2> Then<T2>(Func<T, T2> mapper, Func<Exception, T2> error) { - var promise = new Promise<T2>(); - if (mapper != null) - promise.On((Action)null, null, Cancel); - AddHandler(new RemapDescriptor<T2>(mapper, error, null, promise)); - return promise; - } - - public IPromise<T2> Then<T2>(Func<T, T2> mapper) { - var promise = new Promise<T2>(); - if (mapper != null) - promise.On((Action)null, null, Cancel); - AddHandler(new RemapDescriptor<T2>(mapper, null, null, promise)); - return promise; - } - - public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error, Func<Exception, IPromise<T2>> cancel) { - // this promise will be resolved when an asyc operation is started - var promise = new Promise<IPromise<T2>>(); - - AddHandler(new RemapDescriptor<IPromise<T2>>( - chained, - error, - cancel, - promise - )); - - var medium = new Promise<T2>(); - - if (chained != null) - medium.On(Cancel, PromiseEventType.Cancelled); - - // we need to connect started async operation with the medium - // if the async operation hasn't been started by the some reason - // report is to the medium - promise.On( - result => ConnectPromise<T2>(result, medium), - medium.Reject, - medium.Cancel - ); - - return medium; - } - - static void ConnectPromise<T2>(IPromise<T2> result, Promise<T2> medium) { - if (result != null) { - result.On( - medium.Resolve, - medium.Reject, - medium.Cancel - ); - medium.On(result.Cancel, PromiseEventType.Cancelled); - } else { - medium.Reject( - new NullReferenceException( - "The chained asynchronous operation returned" + - " 'null' where the promise instance is expected" - ) - ); - } - } - - public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained, Func<Exception, IPromise<T2>> error) { - return Chain(chained, error, null); - } - - public IPromise<T2> Chain<T2>(Func<T, IPromise<T2>> chained) { - return Chain(chained, null, null); - } - - public IPromise Then(Action success, Action<Exception> error, Action<Exception> cancel) { - var promise = new Promise(); - if (success != null) - promise.On(null, null, Cancel); - - AddHandler(new EventDescriptor(success, error, cancel, promise)); - - return promise; - } - - public IPromise Then(Action success, Action<Exception> error) { - return Then(success, error, null); - } - - public IPromise Then(Action success) { - return Then(success, null, null); - } - - public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel) { - var promise = new Promise<IPromise>(); - - AddHandler( - new RemapDescriptor<IPromise>( - x => chained(), - error, - cancel, - promise - ) - ); - - var medium = new Promise(); - if (chained != null) - medium.On(null, null, Cancel); - - promise.On( - result => ConnectPromise(result, medium), - medium.Reject, - medium.Cancel - ); - - return medium; - } - - static void ConnectPromise(IPromise result, Promise medium) { - if (result != null) { - result.On( - medium.Resolve, - medium.Reject, - medium.Cancel - ); - medium.On(null, null, result.Cancel); - } else { - medium.Reject( - new NullReferenceException( - "The chained asynchronous operation returned" + - " 'null' where the promise instance is expected" - ) - ); - } - } - - public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error) { - return Chain(chained, error, null); - } - - public IPromise Chain(Func<IPromise> chained) { - return Chain(chained, null, null); - } - - public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) { - AddHandler(new EventDescriptor(success,error,cancel, StubDeferred.instance)); - return this; - } - - public IPromise On(Action success, Action<Exception> error) { - AddHandler(new EventDescriptor(success, error, null, StubDeferred.instance)); - return this; - } - - public IPromise On(Action success) { - Listen(PromiseEventType.Success, success); - return this; - } - - IPromise IPromise.On(Action handler, PromiseEventType events) { - Listen(events,handler); - return this; - } - - public IPromise<T2> Cast<T2>() { - return (IPromise<T2>)this; - } - - #region implemented abstract members of AbstractPromise - - protected override void SignalSuccess(IDeferred<T> handler) { - handler.Resolve(m_result); - } - - protected override void SignalError(IDeferred<T> handler, Exception error) { - handler.Reject(error); - } - - protected override void SignalCancelled(IDeferred<T> handler, Exception reason) { - handler.Cancel(reason); - } - - protected override void Listen(PromiseEventType events, Action handler) { - if (handler != null) - AddHandler(new ListenerDescriptor(handler, events)); - } - - #endregion - - public static IPromise<T> ResultToPromise(T value) { - var p = new Promise<T>(); - p.Resolve(value); - return p; - } - - public static IPromise<T> ExceptionToPromise(Exception error) { - var p = new Promise<T>(); - p.Reject(error); - return p; - } - } }