view Implab/AbstractPromise.cs @ 242:cbe10ac0731e v3

Working on promises
author cin
date Wed, 24 Jan 2018 03:03:21 +0300
parents 86187b01c4e0
children b1e0ffdf3451
line wrap: on
line source

using System;
using Implab.Parallels;

namespace Implab {
    public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
        public class HandlerDescriptor {
            readonly Action m_handler;
            readonly Action<Exception> m_error;
            public HandlerDescriptor(Action success, Action<Exception> error) {
                m_handler = success;
                m_error = error;
            }

            public void SignalSuccess() {
                if (m_handler != null) {
                    try {
                        m_handler();
                        // Analysis disable once EmptyGeneralCatchClause
                    } catch {
                    }
                }
            }

            public void SignalError(Exception err) {
                if (m_error != null) {
                    try {
                        m_error(err);
                        // 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(RejectReason);
                    break;
                default:
                    throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal));
            }
        }

        protected override Signal GetFulfillSignal() {
            var signal = new Signal();
            On(signal.Set, e => signal.Set());
            return signal;
        }

        #endregion

        public Type ResultType {
            get {
                return typeof(void);
            }
        }

        public void On(Action success, Action<Exception> error) {
            AddHandler(new HandlerDescriptor(success, error));
        }

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