123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- // Copyright (c) 2025 TerraByte Inc.
- //
- // The concrete implementation of the IPromise interface.
- // It manages the state and execution of an asynchronous operation.
- using System;
- using System.Threading;
- namespace Terra.Arbitrator.Promises
- {
- public class Promise<TResult> : IPromise<TResult>, ITrackablePromise
- {
- private PromiseState State { get; set; }
- private TResult _resolvedValue;
- private Exception _rejectedException;
- // Callbacks to be executed on the main thread
- private Action<TResult> _onResolvedCallback;
- private Action<Exception> _onRejectedCallback;
- private Action _onFinallyCallback;
-
- // Thread-safe flags
- private volatile bool _isResolved;
- private volatile bool _isRejected;
- /// <summary>
- /// Creates a new promise and starts its execution on a background thread.
- /// </summary>
- /// <param name="executor">The function to execute, which takes resolve and reject actions.</param>
- public Promise(Action<Action<TResult>, Action<Exception>> executor)
- {
- _isRejected = false;
- State = PromiseState.Pending;
- // The manager will track this promise until it's settled.
- PromiseManager.Track(this);
- ThreadPool.QueueUserWorkItem(_ =>
- {
- try
- {
- executor(Resolve, Reject);
- }
- catch (Exception ex)
- {
- Reject(ex);
- }
- });
- }
- private void Resolve(TResult value)
- {
- if (State != PromiseState.Pending) return;
- _resolvedValue = value;
- State = PromiseState.Resolved;
- _isResolved = true; // Signal that we are done
- }
- private void Reject(Exception ex)
- {
- if (State != PromiseState.Pending) return;
- _rejectedException = ex;
- State = PromiseState.Rejected;
- _isRejected = true; // Signal that we are done
- }
- public IPromise<TResult> Then(Action<TResult> onResolved)
- {
- _onResolvedCallback = onResolved;
- return this;
- }
- public IPromise<TResult> Catch(Action<Exception> onRejected)
- {
- _onRejectedCallback = onRejected;
- return this;
- }
- public void Finally(Action onFinally)
- {
- _onFinallyCallback = onFinally;
- }
- /// <summary>
- /// Called by the PromiseManager from the main thread to execute callbacks.
- /// </summary>
- /// <returns>True if the promise is settled, otherwise false.</returns>
- public bool Tick()
- {
- if (_isResolved)
- {
- try
- {
- _onResolvedCallback?.Invoke(_resolvedValue);
- }
- finally
- {
- _onFinallyCallback?.Invoke();
- }
- return true;
- }
- if (_isRejected)
- {
- try
- {
- _onRejectedCallback?.Invoke(_rejectedException);
- }
- finally
- {
- _onFinallyCallback?.Invoke();
- }
- return true;
- }
-
- return false;
- }
- }
- }
|