Ejemplo n.º 1
0
        /// <summary>
        /// Chain a sequence of operations using promises.
        /// Takes a collection of functions each of which starts an async operation and yields a promise.
        /// </summary>
        public static IPromise Sequence(IEnumerable <Func <IPromise> > fns)
        {
            var promise = new Promise();

            int count = 0;

            fns.Aggregate(
                Resolved(),
                (prevPromise, fn) =>
            {
                int itemSequence = count;
                ++count;

                return(prevPromise
                       .Then(() =>
                {
                    var sliceLength = 1f / count;
                    promise.ReportProgress(sliceLength * itemSequence);
                    return fn();
                })
                       .Progress(v =>
                {
                    var sliceLength = 1f / count;
                    promise.ReportProgress(sliceLength * (v + itemSequence));
                })
                       );
            }
                )
            .Then(() => promise.Resolve())
            .Catch(promise.Reject);

            return(promise);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise <PromisedT> Catch(Func <Exception, PromisedT> onRejected)
        {
            var resultPromise = new Promise <PromisedT>();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = v => resultPromise.Resolve(v);

            Action <Exception> rejectHandler = ex =>
            {
                try
                {
                    resultPromise.Resolve(onRejected(ex));
                }
                catch (Exception cbEx)
                {
                    resultPromise.Reject(cbEx);
                }
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));

            return(resultPromise);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise Catch(Action <Exception> onRejected)
        {
            //            Argument.NotNull(() => onRejected);

            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action resolveHandler = () => resultPromise.Resolve();

            Action <Exception> rejectHandler = ex =>
            {
                try
                {
                    onRejected(ex);
                    resultPromise.Resolve();
                }
                catch (Exception callbackException)
                {
                    resultPromise.Reject(callbackException);
                }
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));

            return(resultPromise);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise Catch(Action <Exception> onRejected)
        {
            if (CurState == PromiseState.Resolved)
            {
                return(Promise.Resolved());
            }

            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = _ => resultPromise.Resolve();

            Action <Exception> rejectHandler = ex =>
            {
                try
                {
                    onRejected(ex);
                    resultPromise.Resolve();
                }
                catch (Exception cbEx)
                {
                    resultPromise.Reject(cbEx);
                }
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));

            return(resultPromise);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise <PromisedT> Catch(Action <Exception> onRejected)
        {
//            Argument.NotNull(() => onRejected);

            var resultPromise = new Promise <PromisedT>();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = v =>
            {
                resultPromise.Resolve(v);
            };

            Action <Exception> rejectHandler = ex =>
            {
                onRejected(ex);

                resultPromise.Reject(ex);
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            /// ADDED: Progress ripped from 3.0
            ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));

            return(resultPromise);
        }
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a non-value promise.
        /// </summary>
        public IPromise Then(Func <IPromise> onResolved, Action <Exception> onRejected, Action <float> onProgress)
        {
            if (CurState == PromiseState.Resolved)
            {
                try
                {
                    return(onResolved());
                }
                catch (Exception ex)
                {
                    return(Rejected(ex));
                }
            }

            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action resolveHandler;

            if (onResolved != null)
            {
                resolveHandler = () =>
                {
                    onResolved()
                    .Progress(progress => resultPromise.ReportProgress(progress))
                    .Then(
                        () => resultPromise.Resolve(),
                        ex => resultPromise.Reject(ex)
                        );
                };
            }
            else
            {
                resolveHandler = resultPromise.Resolve;
            }

            Action <Exception> rejectHandler;

            if (onRejected != null)
            {
                rejectHandler = ex =>
                {
                    onRejected(ex);
                    resultPromise.Reject(ex);
                };
            }
            else
            {
                rejectHandler = resultPromise.Reject;
            }

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            if (onProgress != null)
            {
                ProgressHandlers(this, onProgress);
            }

            return(resultPromise);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a value promise (optionally converting to a different value type).
        /// </summary>
        public IPromise <ConvertedT> Then <ConvertedT>(
            Func <PromisedT, IPromise <ConvertedT> > onResolved,
            Func <Exception, IPromise <ConvertedT> > onRejected,
            Action <float> onProgress
            )
        {
            // This version of the function must supply an onResolved.
            // Otherwise there is now way to get the converted value to pass to the resulting promise.
            //            Argument.NotNull(() => onResolved);

            lock (this)
            {
                var resultPromise = new Promise <ConvertedT>();
                resultPromise.WithName(Name);

                Action <PromisedT> resolveHandler = v =>
                {
                    onResolved(v)
                    .Progress(progress => resultPromise.ReportProgress(progress))
                    .Then(
                        // Should not be necessary to specify the arg type on the next line, but Unity (mono) has an internal compiler error otherwise.
                        chainedValue => resultPromise.Resolve(chainedValue),
                        ex => resultPromise.Reject(ex)
                        );
                };

                Action <Exception> rejectHandler = ex =>
                {
                    if (onRejected == null)
                    {
                        resultPromise.Reject(ex);
                        return;
                    }

                    try
                    {
                        onRejected(ex)
                        .Then(
                            chainedValue => resultPromise.Resolve(chainedValue),
                            callbackEx => resultPromise.Reject(callbackEx)
                            );
                    }
                    catch (Exception callbackEx)
                    {
                        resultPromise.Reject(callbackEx);
                    }
                };

                ActionHandlers(resultPromise, resolveHandler, rejectHandler);
                if (onProgress != null)
                {
                    ProgressHandlers(this, onProgress);
                }

                return(resultPromise);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Chain a number of operations using promises.
        /// Returns the value of the first promise that resolves, or otherwise the exception thrown by the last operation.
        /// </summary>
        public static IPromise <T> First <T>(IEnumerable <Func <IPromise <T> > > fns)
        {
            var promise = new Promise <T>();

            int count = 0;

            fns.Aggregate(
                Promise <T> .Rejected(null),
                (prevPromise, fn) =>
            {
                int itemSequence = count;
                ++count;

                var newPromise = new Promise <T>();
                prevPromise
                .Progress(v =>
                {
                    var sliceLength = 1f / count;
                    promise.ReportProgress(sliceLength * (v + itemSequence));
                })
                .Then((Action <T>)newPromise.Resolve)
                .Catch(ex =>
                {
                    var sliceLength = 1f / count;
                    promise.ReportProgress(sliceLength * itemSequence);

                    fn()
                    .Then(value => newPromise.Resolve(value))
                    .Catch(newPromise.Reject)
                    .Done()
                    ;
                })
                ;
                return(newPromise);
            })
            .Then(value => promise.Resolve(value))
            .Catch(ex =>
            {
                promise.ReportProgress(1f);
                promise.Reject(ex);
            });

            return(promise);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Returns a promise that resolves when all of the promises in the enumerable argument have resolved.
        /// Returns a promise of a collection of the resolved results.
        /// </summary>
        public static IPromise <IEnumerable <PromisedT> > All(IEnumerable <IPromise <PromisedT> > promises)
        {
            var promisesArray = promises.ToArray();

            if (promisesArray.Length == 0)
            {
                return(Promise <IEnumerable <PromisedT> > .Resolved(Enumerable.Empty <PromisedT>()));
            }

            var remainingCount = promisesArray.Length;
            var results        = new PromisedT[remainingCount];
            var progress       = new float[remainingCount];
            var resultPromise  = new Promise <IEnumerable <PromisedT> >();

            resultPromise.WithName("All");

            promisesArray.Each((promise, index) =>
            {
                promise
                .Progress(v =>
                {
                    progress[index] = v;
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        resultPromise.ReportProgress(progress.Average());
                    }
                })
                .Then(result =>
                {
                    progress[index] = 1f;
                    results[index]  = result;

                    --remainingCount;
                    if (remainingCount <= 0 && resultPromise.CurState == PromiseState.Pending)
                    {
                        // This will never happen if any of the promises errorred.
                        resultPromise.Resolve(results);
                    }
                })
                .Catch(ex =>
                {
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        // If a promise errorred and the result promise is still pending, reject it.
                        resultPromise.Reject(ex);
                    }
                })
                .Done();
            });

            return(resultPromise);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a non-value promise.
        /// </summary>
        public IPromise Then(Func <PromisedT, IPromise> onResolved, Action <Exception> onRejected, Action <float> onProgress)
        {
            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = null;

            if (IsActionHandlersResolveValid())
            {
                resolveHandler = v =>
                {
                    if (onResolved != null)
                    {
                        onResolved(v)
                        .Progress(progress => resultPromise.ReportProgress(progress))
                        .Then(
                            () => resultPromise.Resolve(),
                            ex => resultPromise.Reject(ex)
                            );
                    }
                    else
                    {
                        resultPromise.Resolve();
                    }
                };
            }

            Action <Exception> rejectHandler = null;

            if (IsActionHandlersRejectValid())
            {
                rejectHandler = ex =>
                {
                    if (onRejected != null)
                    {
                        onRejected(ex);
                    }

                    resultPromise.Reject(ex);
                };
            }

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            if (onProgress != null)
            {
                ProgressHandlers(this, onProgress);
            }

            return(resultPromise);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Returns a promise that resolves when all of the promises in the enumerable argument have resolved.
        /// Returns a promise of a collection of the resolved results.
        /// </summary>
        public static IPromise All(IEnumerable <IPromise> promises)
        {
            var promisesArray = promises.ToArray();

            if (promisesArray.Length == 0)
            {
                return(Resolved());
            }

            var remainingCount = promisesArray.Length;
            var resultPromise  = new Promise();

            resultPromise.WithName("All");
            /// ADDED: Progress ripped from 3.0
            var progress = new float[remainingCount];

            promisesArray.Each((promise, index) =>
            {
                promise
                /// ADDED: Progress ripped from 3.0
                .Progress(v =>
                {
                    progress[index] = v;
                    resultPromise.ReportProgress(progress.Average());
                })
                .Catch(ex =>
                {
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        // If a promise errorred and the result promise is still pending, reject it.
                        resultPromise.Reject(ex);
                    }
                })
                .Then(() =>
                {
                    /// ADDED: Progress ripped from 3.0
                    progress[index] = 1f;

                    --remainingCount;
                    if (remainingCount <= 0)
                    {
                        // This will never happen if any of the promises errorred.
                        resultPromise.Resolve();
                    }
                })
                .Done();
            });

            return(resultPromise);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Returns a promise that resolves when the first of the promises in the enumerable argument have resolved.
        /// Returns the value from the first promise that has resolved.
        /// </summary>
        public static IPromise <PromisedT> Race(IEnumerable <IPromise <PromisedT> > promises)
        {
            var promisesArray = promises.ToArray();

            if (promisesArray.Length == 0)
            {
                throw new InvalidOperationException(
                          "At least 1 input promise must be provided for Race"
                          );
            }

            var resultPromise = new Promise <PromisedT>();

            resultPromise.WithName("Race");

            var progress = new float[promisesArray.Length];

            promisesArray.Each((promise, index) =>
            {
                promise
                .Progress(v =>
                {
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        progress[index] = v;
                        resultPromise.ReportProgress(progress.Max());
                    }
                })
                .Then(result =>
                {
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        resultPromise.Resolve(result);
                    }
                })
                .Catch(ex =>
                {
                    if (resultPromise.CurState == PromiseState.Pending)
                    {
                        // If a promise errorred and the result promise is still pending, reject it.
                        resultPromise.Reject(ex);
                    }
                })
                .Done();
            });

            return(resultPromise);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a non-value promise.
        /// </summary>
        /// ADDED: Base class added for all types of promises
        public IBasePromise BaseThen(
            Func <IPromise> onResolved,
            Action <Exception> onRejected,
            Action <float> onProgress)
        {
            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = v =>
            {
                if (onResolved != null)
                {
                    onResolved()
                    /// ADDED: Progress ripped from 3.0
                    .Progress(progress => resultPromise.ReportProgress(progress))
                    .Then(
                        () => resultPromise.Resolve(),
                        ex => resultPromise.Reject(ex)
                        );
                }
                else
                {
                    resultPromise.Resolve();
                }
            };

            Action <Exception> rejectHandler = ex =>
            {
                if (onRejected != null)
                {
                    onRejected(ex);
                }

                resultPromise.Reject(ex);
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            /// ADDED: Progress ripped from 3.0
            if (onProgress != null)
            {
                ProgressHandlers(this, onProgress);
            }

            return(resultPromise);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise Catch(Action <Exception> onRejected)
        {
            var resultPromise = new Promise();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = null;

            if (IsActionHandlersResolveValid())
            {
                resolveHandler = _ => resultPromise.Resolve();
            }

            Action <Exception> rejectHandler = null;

            if (IsActionHandlersRejectValid())
            {
                rejectHandler = ex =>
                {
                    try
                    {
                        onRejected(ex);
                        resultPromise.Resolve();
                    }
                    catch (Exception cbEx)
                    {
                        resultPromise.Reject(cbEx);
                    }
                };
            }

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);

            if (IsProgressHandlersValid())
            {
                ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));
            }

            return(resultPromise);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a value promise (optionally converting to a different value type).
        /// </summary>
        /// ADDED: Base class added for all types of promises
        public IBasePromise BaseThen <ConvertedT>(
            Func <IPromise <ConvertedT> > onResolved,
            Action <Exception> onRejected,
            Action <float> onProgress)
        {
            var resultPromise = new Promise <ConvertedT>();

            resultPromise.WithName(Name);

            Action <PromisedT> resolveHandler = v =>
            {
                onResolved()
                /// ADDED: Progress ripped from 3.0
                .Progress(progress => resultPromise.ReportProgress(progress))
                .Then(
                    // Should not be necessary to specify the arg type on the next line, but Unity (mono) has an internal compiler error otherwise.
                    (ConvertedT chainedValue) => resultPromise.Resolve(chainedValue),
                    ex => resultPromise.Reject(ex)
                    );
            };

            Action <Exception> rejectHandler = ex =>
            {
                if (onRejected != null)
                {
                    onRejected(ex);
                }

                resultPromise.Reject(ex);
            };

            ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            /// ADDED: Progress ripped from 3.0
            if (onProgress != null)
            {
                ProgressHandlers(this, onProgress);
            }

            return(resultPromise);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Add a resolved callback, a rejected callback and a progress callback.
        /// The resolved callback chains a non-value promise.
        /// </summary>
        public IPromise Then(Func <IPromise> onResolved, Action <Exception> onRejected, Action <float> onProgress)
        {
            var resultPromise = new Promise(isSync: true);

            resultPromise.WithName(this.Name);

            Action resolveHandler = () => {
                if (onResolved != null)
                {
                    onResolved()
                    .Progress(progress => resultPromise.ReportProgress(progress))
                    .Then(
                        () => resultPromise.Resolve(),
                        ex => resultPromise.Reject(ex)
                        );
                }
                else
                {
                    resultPromise.Resolve();
                }
            };

            Action <Exception> rejectHandler = ex => {
                if (onRejected != null)
                {
                    onRejected(ex);
                }

                resultPromise.Reject(ex);
            };

            this.ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            if (onProgress != null)
            {
                this.ProgressHandlers(this, onProgress);
            }

            return(resultPromise);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Handle errors for the promise.
        /// </summary>
        public IPromise Catch(Action <Exception> onRejected)
        {
            var resultPromise = new Promise(isSync: true);

            resultPromise.WithName(this.Name);

            Action <PromisedT> resolveHandler = _ => resultPromise.Resolve();

            Action <Exception> rejectHandler = ex => {
                try {
                    onRejected(ex);
                    resultPromise.Resolve();
                }
                catch (Exception cbEx) {
                    resultPromise.Reject(cbEx);
                }
            };

            this.ActionHandlers(resultPromise, resolveHandler, rejectHandler);
            this.ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v));

            return(resultPromise);
        }