|
|
|
|
|
|
using System.Linq; |
|
|
|
using RSG.Exceptions; |
|
|
|
using Unity.UIWidgets.ui; |
|
|
|
using UnityEngine; |
|
|
|
|
|
|
|
namespace RSG |
|
|
|
{ |
|
|
|
|
|
|
/// Tracks the current state of the promise.
|
|
|
|
/// </summary>
|
|
|
|
public PromiseState CurState { get; private set; } |
|
|
|
|
|
|
|
public bool IsSync { get; } |
|
|
|
public Promise() |
|
|
|
{ |
|
|
|
public Promise(bool isSync = false) { |
|
|
|
this.IsSync = isSync; |
|
|
|
this.CurState = PromiseState.Pending; |
|
|
|
this.id = NextId(); |
|
|
|
if (EnablePromiseTracking) |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public Promise(Action<Action, Action<Exception>> resolver) |
|
|
|
{ |
|
|
|
public Promise(Action<Action, Action<Exception>> resolver, bool isSync = false) { |
|
|
|
this.IsSync = isSync; |
|
|
|
this.CurState = PromiseState.Pending; |
|
|
|
this.id = NextId(); |
|
|
|
if (EnablePromiseTracking) |
|
|
|
|
|
|
if (rejectHandlers != null) |
|
|
|
{ |
|
|
|
rejectHandlers.Each(handler => InvokeRejectHandler(handler.callback, handler.rejectable, ex)); |
|
|
|
} else { |
|
|
|
PropagateUnhandledException(this, ex); |
|
|
|
} |
|
|
|
|
|
|
|
ClearHandlers(); |
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Reject the promise with an exception.
|
|
|
|
/// </summary>
|
|
|
|
public void Reject(Exception ex) |
|
|
|
{ |
|
|
|
public void Reject(Exception ex) { |
|
|
|
if (IsSync) { |
|
|
|
RejectSync(ex); |
|
|
|
} else { |
|
|
|
Window.instance.run(() => RejectSync(ex)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void RejectSync(Exception ex) { |
|
|
|
if (CurState != PromiseState.Pending) |
|
|
|
{ |
|
|
|
if (CurState != PromiseState.Pending) { |
|
|
|
"Attempt to reject a promise that is already in state: " + CurState |
|
|
|
+ ", a promise can only be rejected when it is still in state: " |
|
|
|
"Attempt to reject a promise that is already in state: " |
|
|
|
+ CurState |
|
|
|
+ ", a promise can only be rejected when it is still in state: " |
|
|
|
+ PromiseState.Pending |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
if (EnablePromiseTracking) |
|
|
|
{ |
|
|
|
if (EnablePromiseTracking) { |
|
|
|
Window.instance.scheduleMicrotask(() => { |
|
|
|
InvokeRejectHandlers(ex); |
|
|
|
}); |
|
|
|
InvokeRejectHandlers(ex); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Resolve() |
|
|
|
{ |
|
|
|
if (CurState != PromiseState.Pending) |
|
|
|
{ |
|
|
|
public void Resolve() { |
|
|
|
if (IsSync) { |
|
|
|
ResolveSync(); |
|
|
|
} else { |
|
|
|
Window.instance.run(() => ResolveSync()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void ResolveSync() { |
|
|
|
if (CurState != PromiseState.Pending) { |
|
|
|
"Attempt to resolve a promise that is already in state: " + CurState |
|
|
|
+ ", a promise can only be resolved when it is still in state: " |
|
|
|
"Attempt to resolve a promise that is already in state: " |
|
|
|
+ CurState |
|
|
|
+ ", a promise can only be resolved when it is still in state: " |
|
|
|
+ PromiseState.Pending |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
if (EnablePromiseTracking) |
|
|
|
{ |
|
|
|
if (EnablePromiseTracking) { |
|
|
|
Window.instance.scheduleMicrotask(() => { |
|
|
|
InvokeResolveHandlers(); |
|
|
|
}); |
|
|
|
InvokeResolveHandlers(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
// Argument.NotNull(() => onRejected);
|
|
|
|
|
|
|
|
var resultPromise = new Promise(); |
|
|
|
var resultPromise = new Promise(isSync: true); |
|
|
|
resultPromise.WithName(Name); |
|
|
|
|
|
|
|
Action resolveHandler = () => resultPromise.Resolve(); |
|
|
|
|
|
|
/// </summary>
|
|
|
|
public IPromise Then(Func<IPromise> onResolved, Action<Exception> onRejected, Action<float> onProgress) |
|
|
|
{ |
|
|
|
var resultPromise = new Promise(); |
|
|
|
var resultPromise = new Promise(isSync: true); |
|
|
|
resultPromise.WithName(Name); |
|
|
|
|
|
|
|
Action resolveHandler = () => |
|
|
|
|
|
|
/// </summary>
|
|
|
|
public IPromise Then(Action onResolved, Action<Exception> onRejected, Action<float> onProgress) |
|
|
|
{ |
|
|
|
var resultPromise = new Promise(); |
|
|
|
var resultPromise = new Promise(isSync: true); |
|
|
|
resultPromise.WithName(Name); |
|
|
|
|
|
|
|
Action resolveHandler = () => |
|
|
|
|
|
|
private void ActionHandlers(IRejectable resultPromise, Action resolveHandler, Action<Exception> rejectHandler) |
|
|
|
{ |
|
|
|
if (CurState == PromiseState.Resolved) { |
|
|
|
Window.instance.scheduleMicrotask(() => { |
|
|
|
InvokeResolveHandler(resolveHandler, resultPromise); |
|
|
|
}); |
|
|
|
InvokeResolveHandler(resolveHandler, resultPromise); |
|
|
|
Window.instance.scheduleMicrotask(() => { |
|
|
|
InvokeRejectHandler(rejectHandler, resultPromise, rejectionException); |
|
|
|
}); |
|
|
|
InvokeRejectHandler(rejectHandler, resultPromise, rejectionException); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var remainingCount = promisesArray.Length; |
|
|
|
var resultPromise = new Promise(); |
|
|
|
var resultPromise = new Promise(isSync: true); |
|
|
|
resultPromise.WithName("All"); |
|
|
|
var progress = new float[remainingCount]; |
|
|
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
public static IPromise Sequence(IEnumerable<Func<IPromise>> fns) |
|
|
|
{ |
|
|
|
var promise = new Promise(); |
|
|
|
var promise = new Promise(isSync: true); |
|
|
|
|
|
|
|
int count = 0; |
|
|
|
|
|
|
|
|
|
|
throw new InvalidOperationException("At least 1 input promise must be provided for Race"); |
|
|
|
} |
|
|
|
|
|
|
|
var resultPromise = new Promise(); |
|
|
|
var resultPromise = new Promise(isSync: true); |
|
|
|
resultPromise.WithName("Race"); |
|
|
|
|
|
|
|
var progress = new float[promisesArray.Length]; |
|
|
|
|
|
|
|
|
|
|
public IPromise Finally(Action onComplete) |
|
|
|
{ |
|
|
|
var promise = new Promise(); |
|
|
|
var promise = new Promise(isSync: true); |
|
|
|
promise.WithName(Name); |
|
|
|
|
|
|
|
this.Then(() => promise.Resolve()); |
|
|
|
|
|
|
|
|
|
|
public IPromise ContinueWith(Func<IPromise> onComplete) |
|
|
|
{ |
|
|
|
var promise = new Promise(); |
|
|
|
var promise = new Promise(isSync: true); |
|
|
|
promise.WithName(Name); |
|
|
|
|
|
|
|
this.Then(() => promise.Resolve()); |
|
|
|
|
|
|
|
|
|
|
public IPromise<ConvertedT> ContinueWith<ConvertedT>(Func<IPromise<ConvertedT>> onComplete) |
|
|
|
{ |
|
|
|
var promise = new Promise(); |
|
|
|
var promise = new Promise(isSync: true); |
|
|
|
promise.WithName(Name); |
|
|
|
|
|
|
|
this.Then(() => promise.Resolve()); |
|
|
|
|
|
|
if (unhandlerException != null) |
|
|
|
{ |
|
|
|
unhandlerException(sender, new ExceptionEventArgs(ex)); |
|
|
|
} else { |
|
|
|
Debug.LogWarning("Unhandled Exception from " + sender + ": " + ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |