static partial void ValidateElementNotNull(Promise promise, string argName, string message, int skipFrames) { if (promise == null) { throw new ElementNullException(argName, message, Internal.GetFormattedStacktrace(skipFrames + 1)); } }
static protected void ValidateNotDisposed(object valueContainer, int skipFrames) { Internal.ValidateThreadAccess(skipFrames + 1); if (IsDisposed(valueContainer)) { throw new PromiseDisposedException("Always nullify your references when you are finished with them!" + " Call Retain() if you want to perform operations after the object has finished. Remember to call Release() when you are finished with it!" , Internal.GetFormattedStacktrace(skipFrames + 1)); } }
partial void ValidateReturn(Promise other) { if (other == null) { // Returning a null from the callback is not allowed. throw new InvalidReturnException("A null promise was returned."); } // Validate returned promise as not disposed. if (IsDisposed(other._valueOrPrevious)) { throw new InvalidReturnException("A disposed promise was returned.", Internal.GetFormattedStacktrace(other)); } // A promise cannot wait on itself. // This allows us to check All/Race/First Promises iteratively. ValueLinkedStack <InternalProtected.PromisePassThrough> passThroughs = new ValueLinkedStack <InternalProtected.PromisePassThrough>(); var prev = other; Repeat: for (; prev != null; prev = prev._valueOrPrevious as Promise) { if (prev == this) { throw new InvalidReturnException("Circular Promise chain detected.", Internal.GetFormattedStacktrace(other)); } prev.BorrowPassthroughs(ref passThroughs); } if (passThroughs.IsNotEmpty) { // passThroughs are removed from their targets before adding to passThroughs. Add them back here. var passThrough = passThroughs.Pop(); prev = passThrough.Owner; passThrough.Target.ReAdd(passThrough); goto Repeat; } }
/// <summary> /// Unregister the callback from the associated <see cref="CancelationToken"/>. /// </summary> public void Unregister() { if (!TryUnregister()) { throw new InvalidOperationException("CancelationRegistration is not registered.", Internal.GetFormattedStacktrace(1)); } }
/// <summary> /// Get the result. If the Promise resolved successfully, this will return without error. /// If the Promise was rejected, this will throw an <see cref="UnhandledException"/>. /// If the Promise was canceled, this will throw a <see cref="CanceledException"/>. /// </summary> public void GetResult() { ValidateYieldInstructionOperation(_value, 1); if (_state == State.Pending) { throw new InvalidOperationException("Promise is still pending. You must wait for the promse to settle before calling GetResult.", Internal.GetFormattedStacktrace(1)); } if (_state == State.Resolved) { return; } // Throw unhandled exception or canceled exception. throw ((Internal.IThrowable)_value).GetException(); }
protected static void ValidateProgressValue(float value, int skipFrames) { const string argName = "progress"; if (value < 0f || value > 1f || float.IsNaN(value)) { throw new ArgumentOutOfRangeException(argName, "Must be between 0 and 1.", Internal.GetFormattedStacktrace(skipFrames + 1)); } }
static protected void ThrowProgressException(int skipFrames) { throw new InvalidOperationException("Progress is disabled. Remove PROTO_PROMISE_PROGRESS_DISABLE from your compiler symbols to enable progress reports.", Internal.GetFormattedStacktrace(skipFrames + 1)); }
public static Promise <T> CreateFirst <T, TEnumerator>(TEnumerator promises) where TEnumerator : IEnumerator <Promise <T> > { ValidateArgument(promises, "promises", 2); if (!promises.MoveNext()) { throw new EmptyArgumentException("promises", "You must provide at least one element to First.", Internal.GetFormattedStacktrace(2)); } int count; var passThroughs = WrapInPassThroughs <T, TEnumerator>(promises, out count); return(FirstPromise <T> .GetOrCreate(passThroughs, count)); }
/// <summary> /// Release all resources used by this <see cref="CancelationSource"/>. This instance will no longer be valid. /// </summary> public void Dispose() { if (!IsValid) { throw new InvalidOperationException("CancelationSource.Dispose: source is not valid.", Internal.GetFormattedStacktrace(1)); } _ref.Dispose(); }
/// <summary> /// Communicates a request for cancelation with the provided reason, and invokes all callbacks that are registered to any associated <see cref="CancelationToken"/>. /// </summary> public void Cancel <TCancel>(TCancel reason) { if (!IsValid) { throw new InvalidOperationException("CancelationSource.Cancel: source is not valid.", Internal.GetFormattedStacktrace(1)); } if (_ref.IsCanceled) { throw new InvalidOperationException("CancelationSource.Cancel: source was already canceled.", Internal.GetFormattedStacktrace(1)); } _ref.SetCanceled(ref reason); }
/// <summary> /// Release this instance. Allows resources to be released when the associated <see cref="CancelationSource"/> is disposed (if <see cref="Release"/> has been called for all <see cref="Retain"/> calls). /// <para/>This should always be paired with a call to <see cref="Retain"/> /// </summary> public void Release() { if (!CanBeCanceled) { throw new InvalidOperationException("CancelationToken.Release: token cannot be canceled.", Internal.GetFormattedStacktrace(1)); } _ref.Release(); }
/// <summary> /// Capture a value and register a delegate that will be invoked with the captured value and the cancelation reason when this <see cref="CancelationToken"/> is canceled. /// If this is already canceled, the callback will be invoked immediately. /// </summary> /// <param name="callback">The delegate to be executed when the <see cref="CancelationToken"/> is canceled.</param> /// <returns>The <see cref="CancelationRegistration"/> instance that can be used to unregister the callback.</returns> public CancelationRegistration Register <TCapture>(TCapture captureValue, Action <TCapture, ReasonContainer> callback) { if (!CanBeCanceled) { throw new InvalidOperationException("CancelationToken.Register: token cannot be canceled.", Internal.GetFormattedStacktrace(1)); } ValidateArgument(callback, "callback", 1); if (_ref.IsCanceled) { callback.Invoke(captureValue, new ReasonContainer(_ref.ValueContainer)); return(default(CancelationRegistration)); } var cancelDelegate = Internal.CancelDelegate <Internal.CancelDelegateToken <TCapture> > .GetOrCreate(); cancelDelegate.canceler = new Internal.CancelDelegateToken <TCapture>(ref captureValue, callback); return(new CancelationRegistration(_ref, cancelDelegate)); }
/// <summary> /// Try to get the cancelation value casted to <typeparamref name="T"/>. /// Returns true if successful, false otherwise. /// </summary> public bool TryGetCancelationValueAs <T>(out T value) { if (!IsCancelationRequested) { throw new InvalidOperationException("CancelationToken.CancelationValue: token has not been canceled.", Internal.GetFormattedStacktrace(1)); } return(Internal.TryConvert(_ref.ValueContainer, out value)); }