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();
+            }
+        }
+    }
+}
+