diff Implab/AbstractPromise.cs @ 192:f1da3afc3521 release v2.1

Слияние с v2
author cin
date Fri, 22 Apr 2016 13:10:34 +0300
parents 75103928da09
children 86187b01c4e0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/AbstractPromise.cs	Fri Apr 22 13:10:34 2016 +0300
@@ -0,0 +1,142 @@
+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() {
+            if(BeginSetResult())
+                EndSetResult();
+        }
+    }
+}
+