/// <summary> /// Add a resolved callback and a rejected callback. /// </summary> public IFpromise Then(Action onResolved, Action <Exception> onRejected) { var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); Action resolveHandler = () => { if (onResolved != null) { onResolved(); } resultFpromise.Resolve(); }; Action <Exception> rejectHandler = ex => { if (onRejected != null) { onRejected(ex); } resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
/// <summary> /// Convert a simple value directly into a resolved promise. /// </summary> public static IFpromise <FpromisedT> Resolved(FpromisedT promisedValue) { var promise = new Fpromise <FpromisedT>(); promise.Resolve(promisedValue); return(promise); }
/// <summary> /// Convert a simple value directly into a resolved promise. /// </summary> public static IFpromise Resolved() { var promise = new Fpromise(); promise.Resolve(); return(promise); }
/// <summary> /// Add a resolved callback and a rejected callback. /// The resolved callback chains a value promise (optionally converting to a different value type). /// </summary> public IFpromise <ConvertedT> Then <ConvertedT>(Func <IFpromise <ConvertedT> > onResolved, Action <Exception> onRejected) { // 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); var resultFpromise = new Fpromise <ConvertedT>(); resultFpromise.WithName(Name); Action resolveHandler = () => { onResolved() .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) => resultFpromise.Resolve(chainedValue), ex => resultFpromise.Reject(ex) ); }; Action <Exception> rejectHandler = ex => { if (onRejected != null) { onRejected(ex); } resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
/// <summary> /// Returns true if promise is not null and pending /// </summary> public static bool Exists <T>(this Fpromise <T> promise) { if (promise.IsNotNull() && promise.IsPending()) { return(true); } return(false); }
public static bool IsPending <T>(this Fpromise <T> promise) { if (promise.CurState == FpromiseState.Pending) { return(true); } return(false); }
public static Fpromise SoftResolve(this Fpromise promise) { if (promise.IsNotNull() && promise.IsPending()) { promise.Resolve(); } return(promise); }
public static bool IsNotNull <T>(this Fpromise <T> promise) { if (promise != null) { return(true); } return(false); }
public static Fpromise <T> SoftResolve <T>(this Fpromise <T> promise, T data) { if (promise.IsNotNull() && promise.IsPending()) { promise.Resolve(data); } return(promise); }
public static Fpromise <T> SoftReject <T>(this Fpromise <T> promise, Exception exception) { if (promise.IsNotNull() && promise.IsPending()) { promise.Reject(exception); } return(promise); }
/// <summary> /// Convert an exception directly into a rejected promise. /// </summary> public static IFpromise Rejected(Exception ex) { // Argument.NotNull(() => ex); var promise = new Fpromise(); promise.Reject(ex); return(promise); }
/// <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 IFpromise Sequence(IEnumerable <Func <IFpromise> > fns) { return(fns.Aggregate( Fpromise.Resolved(), (prevFpromise, fn) => { return prevFpromise.Then(() => fn()); } )); }
public static IFpromise WaitForEndOfFrame() { var promise = new Fpromise(); var routine = _ResolverAfterEndOfFrame(promise); Fcoroutine.Start(routine); return(promise); }
public static IFpromise WaitForSeconds(float seconds) { var promise = new Fpromise(); var routine = _ResolveAfterSeconds(promise, seconds); Fcoroutine.Start(routine); return(promise); }
public static IFpromise WaitUntil(Func <bool> condition) { var promise = new Fpromise(); var routine = _ResolveAfterCondition(promise, condition); Fcoroutine.Start(routine); return(promise); }
/// <summary> /// Completes the promise. /// onResolved is called on successful completion. /// onRejected is called on error. /// </summary> public void Done(Action onResolved, Action <Exception> onRejected) { // Argument.NotNull(() => onResolved); // Argument.NotNull(() => onRejected); var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); ActionHandlers(resultFpromise, onResolved, onRejected); }
/// <summary> /// Completes the promise. /// onResolved is called on successful completion. /// Adds a default error handler. /// </summary> public void Done(Action onResolved) { // Argument.NotNull(() => onResolved); var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); ActionHandlers(resultFpromise, onResolved, ex => Fpromise.PropagateUnhandledException(this, ex) ); }
/// <summary> /// Complete the promise. Adds a defualt error handler. /// </summary> public void Done() { var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); ActionHandlers(resultFpromise, () => { }, ex => Fpromise.PropagateUnhandledException(this, ex) ); }
/// <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 IFpromise <IEnumerable <FpromisedT> > All(IEnumerable <IFpromise <FpromisedT> > promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { return(Fpromise <IEnumerable <FpromisedT> > .Resolved(EnumerableExtensions.Empty <FpromisedT>())); } var remainingCount = promisesArray.Length; var results = new FpromisedT[remainingCount]; var resultFpromise = new Fpromise <IEnumerable <FpromisedT> >(); resultFpromise.WithName("All"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultFpromise.CurState == FpromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultFpromise.Reject(ex); } }) .Then(result => { results[index] = result; --remainingCount; if (remainingCount <= 0) { // This will never happen if any of the promises errorred. resultFpromise.Resolve(results); } }) .Done(); }); return(resultFpromise); }
public static IFpromise WaitUntilOrForSeconds(Func <bool> condition, float secondsToReject) { var promise = new Fpromise(); var routine = _ResolveAfterCondition(promise, condition); var coroutine = Fcoroutine.Start(routine); WaitForSeconds(secondsToReject) .Then(() => { if (coroutine != null) { Fcoroutine.Stop(coroutine); } promise.SoftReject(new Exception("FpromiseWaitUntilOrForSecondsTimeoutException")); }); return(promise); }
/// <summary> /// Return a new promise with a different value. /// May also change the type of the value. /// </summary> public IFpromise <ConvertedT> Transform <ConvertedT>(Func <FpromisedT, ConvertedT> transform) { // Argument.NotNull(() => transform); var resultFpromise = new Fpromise <ConvertedT>(); resultFpromise.WithName(Name); Action <FpromisedT> resolveHandler = v => { resultFpromise.Resolve(transform(v)); }; Action <Exception> rejectHandler = ex => { resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
/// <summary> /// Add a resolved callback and a rejected callback. /// The resolved callback chains a non-value promise. /// </summary> public IFpromise Then(Func <FpromisedT, IFpromise> onResolved, Action <Exception> onRejected) { var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); Action <FpromisedT> resolveHandler = v => { if (onResolved != null) { onResolved(v) .Then( () => resultFpromise.Resolve(), ex => resultFpromise.Reject(ex) ); } else { resultFpromise.Resolve(); } }; Action <Exception> rejectHandler = ex => { if (onRejected != null) { onRejected(ex); } resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
/// <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 IFpromise Race(IEnumerable <IFpromise> promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { throw new ApplicationException("At least 1 input promise must be provided for Race"); } var resultFpromise = new Fpromise(); resultFpromise.WithName("Race"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultFpromise.CurState == FpromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultFpromise.Reject(ex); } }) .Then(() => { if (resultFpromise.CurState == FpromiseState.Pending) { resultFpromise.Resolve(); } }) .Done(); }); return(resultFpromise); }
/// <summary> /// Handle errors for the promise. /// </summary> public IFpromise Catch(Action <Exception> onRejected) { // Argument.NotNull(() => onRejected); var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); Action resolveHandler = () => { resultFpromise.Resolve(); }; Action <Exception> rejectHandler = ex => { onRejected(ex); resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
static IEnumerator _ResolverAfterEndOfFrame(Fpromise promise) { yield return(new WaitForEndOfFrame()); promise.SoftResolve(); }
static IEnumerator _ResolveAfterCondition(Fpromise promise, Func <bool> condition) { yield return(new WaitUntil(condition)); promise.SoftResolve(); }
static IEnumerator _ResolveAfterSeconds(Fpromise promise, float seconds) { yield return(new WaitForSeconds(seconds)); promise.SoftResolve(); }
/// <summary> /// Takes a function that yields an enumerable of promises. /// Returns a promise that resolves when the first of the promises has resolved. /// </summary> public IFpromise ThenRace(Func <IEnumerable <IFpromise> > chain) { return(Then(() => Fpromise.Race(chain()))); }
/// <summary> /// Takes a function that yields an enumerable of promises. /// Converts to a value promise. /// Returns a promise that resolves when the first of the promises has resolved. /// </summary> public IFpromise <ConvertedT> ThenRace <ConvertedT>(Func <IEnumerable <IFpromise <ConvertedT> > > chain) { return(Then(() => Fpromise <ConvertedT> .Race(chain()))); }
/// <summary> /// Takes a function that yields an enumerable of promises. /// Converts to a non-value promise. /// Returns a promise that resolves when the first of the promises has resolved. /// Yields the value from the first promise that has resolved. /// </summary> public IFpromise ThenRace(Func <FpromisedT, IEnumerable <IFpromise> > chain) { return(Then(value => Fpromise.Race(chain(value)))); }