diff Implab/Promise.cs @ 138:f75cfa58e3d4 v2

added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
author cin
date Tue, 17 Feb 2015 18:16:26 +0300
parents 2573b562e328
children 8c0b95069066
line wrap: on
line diff
--- a/Implab/Promise.cs	Mon Feb 16 17:48:39 2015 +0300
+++ b/Implab/Promise.cs	Tue Feb 17 18:16:26 2015 +0300
@@ -7,10 +7,10 @@
         public struct HandlerDescriptor {
             readonly Action m_success;
             readonly Action<Exception> m_error;
-            readonly Action m_cancel;
+            readonly Action<Exception> m_cancel;
             readonly IDeferred m_deferred;
 
-            public HandlerDescriptor(Action success, Action<Exception> error, Action cancel, IDeferred deferred) {
+            public HandlerDescriptor(Action success, Action<Exception> error, Action<Exception> cancel, IDeferred deferred) {
                 m_success = success;
                 m_error = error;
                 m_cancel = cancel;
@@ -45,10 +45,18 @@
                 }
             }
 
-            public void SignalCancel() {
+            public void SignalCancel(Exception reason) {
                 if (m_cancel != null) {
                     try {
-                        m_cancel();
+                        m_cancel(reason);
+                        if (m_deferred != null)
+                            m_deferred.Resolve();
+                    } catch (Exception err) {
+                        SignalError(err);
+                    }
+                } else if (reason != null && m_error != null) {
+                    try {
+                        m_error(new OperationCanceledException("The operation was canceled.", reason));
                         if (m_deferred != null)
                             m_deferred.Resolve();
                     } catch (Exception err) {
@@ -56,7 +64,7 @@
                     }
                 } else {
                     if (m_deferred != null)
-                        m_deferred.Cancel();
+                        m_deferred.Cancel(reason);
                 }
             }
         }
@@ -80,15 +88,15 @@
             handler.SignalError(error);
         }
 
-        protected override void SignalCancelled(HandlerDescriptor handler) {
-            handler.SignalCancel();
+        protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) {
+            handler.SignalCancel(reason);
         }
 
         protected override void Listen(PromiseEventType events, Action handler) {
             AddHandler(new HandlerDescriptor(
                 events.HasFlag(PromiseEventType.Success) ? handler : null,
                 events.HasFlag(PromiseEventType.Error) ? new Action<Exception>(err => handler()) : null,
-                events.HasFlag(PromiseEventType.Cancelled) ? handler : null,
+                events.HasFlag(PromiseEventType.Cancelled) ? new Action<Exception>(reason => handler()) : null,
                 null
             ));
         }
@@ -102,7 +110,7 @@
             }
         }
 
-        public IPromise Then(Action success, Action<Exception> error, Action cancel) {
+        public IPromise Then(Action success, Action<Exception> error, Action<Exception> cancel) {
             var promise = new Promise();
             if (success != null)
                 promise.On(Cancel, PromiseEventType.Cancelled);
@@ -120,7 +128,7 @@
             return Then(success, null, null);
         }
 
-        public IPromise On(Action success, Action<Exception> error, Action cancel) {
+        public IPromise On(Action success, Action<Exception> error, Action<Exception> cancel) {
             AddHandler(new HandlerDescriptor(success, error, cancel, null));
             return this;
         }
@@ -137,7 +145,7 @@
             return On(
                 events.HasFlag(PromiseEventType.Success) ? handler : null,
                 events.HasFlag(PromiseEventType.Error) ? new Action<Exception>(err => handler()) : null,
-                events.HasFlag(PromiseEventType.Cancelled) ? handler : null
+                events.HasFlag(PromiseEventType.Cancelled) ? new Action<Exception>(reason => handler()) : null
             );
         }
 
@@ -145,7 +153,7 @@
             throw new InvalidCastException();
         }
 
-        public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<IPromise> cancel) {
+        public IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<Exception,IPromise> cancel) {
             var medium = new Promise();
 
             On(
@@ -168,13 +176,13 @@
                         medium.Reject(ex);
                     }
                 },
-                () => {
+                reason => {
                     if (medium.IsCancelled)
                         return;
                     if (cancel != null)
-                        ConnectPromise(cancel(), medium);
+                        ConnectPromise(cancel(reason), medium);
                     else
-                        medium.Cancel();
+                        medium.Cancel(reason);
                 }
             );
 
@@ -189,9 +197,9 @@
                 result.On(
                     medium.Resolve,
                     medium.Reject,
-                    () => medium.Reject(new OperationCanceledException())
+                    medium.Cancel
                 );
-                medium.On(result.Cancel, PromiseEventType.Cancelled);
+                medium.On(null,null,result.Cancel);
             } else {
                 medium.Reject(
                     new NullReferenceException(
@@ -209,50 +217,6 @@
         public IPromise Chain(Func<IPromise> chained) {
             return Chain(chained, null, null);
         }
-
-        public IPromise Error(Action<Exception> error) {
-            var promise = new Promise();
-            On(
-                null,
-                err => {
-                    if (error != null)
-                        try {
-                            error(err);
-                            promise.Resolve();
-                        } catch (Exception err2) {
-                            promise.Reject(err2);
-                        }
-                    else
-                        promise.Reject(err);
-                }
-            );
-
-            return promise;
-        }
-
-        public IPromise Cancelled(Action handler) {
-            var promise = new Promise();
-            On(
-                null,
-                null,
-                () => {
-                    if (handler != null) {
-                        try {
-                            handler();
-                            promise.Resolve();
-                        } catch (Exception err) {
-                            promise.Reject(err);
-                        }
-                    } else {
-                        promise.Cancel();
-                    }
-                }
-            );
-
-            return promise;
-        }
-
-
     }
 }